release: v2.6.19 — 파일/폴더 열기 실패 회귀 수정 (explorer.exe 경로 — #28 PATH hija… #78
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Publish Release | |
| on: | |
| push: | |
| tags: | |
| - 'v*' | |
| concurrency: | |
| group: publish-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| # Release gate — tag push 시 CI(tsc/cargo fmt/check/clippy/test) 를 먼저 통과시킨다. | |
| # ci.yml 을 workflow_call reuse 하므로 검증 본문은 한 곳에서 관리. | |
| validate: | |
| name: CI gate | |
| uses: ./.github/workflows/ci.yml | |
| permissions: | |
| contents: read | |
| publish-tauri: | |
| name: Build & Release (Windows) | |
| needs: validate | |
| permissions: | |
| contents: write | |
| runs-on: windows-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: pnpm/action-setup@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: 22 | |
| cache: pnpm | |
| - uses: dtolnay/rust-toolchain@stable | |
| - uses: Swatinem/rust-cache@v2 | |
| with: | |
| workspaces: src-tauri | |
| - name: Install frontend dependencies | |
| run: pnpm install --frozen-lockfile | |
| # kordoc 사이드카 소스 체크아웃 (HWP/HWPX/DOCX/PDF 파싱 런타임) | |
| # 리포가 private이면 token: ${{ secrets.KORDOC_PAT }} 추가 필요 | |
| # | |
| # SHA 고정으로 공급망 공격 방지. 새 kordoc 버전 릴리스 시 이 SHA를 갱신. | |
| # 현재: v2.7.1 (HWP 3.0 구버전 파서 추가 — 1996~2002년 단일 binary 포맷) — 2026-05-09 | |
| - name: Checkout kordoc | |
| uses: actions/checkout@v4 | |
| with: | |
| repository: chrisryugj/kordoc | |
| path: kordoc-src | |
| ref: 2645250c5e0edae7869d28c8c323ec58f2ee7f10 | |
| - name: Build kordoc dist | |
| working-directory: kordoc-src | |
| shell: pwsh | |
| run: | | |
| npm ci | |
| npm run build | |
| if (-not (Test-Path "dist/cli.js")) { | |
| Write-Error "kordoc build output (dist/cli.js) not found" | |
| exit 1 | |
| } | |
| - name: Bundle kordoc into Tauri resources | |
| shell: pwsh | |
| run: | | |
| & scripts/bundle-kordoc.ps1 -KordocDir "${{ github.workspace }}/kordoc-src" | |
| - name: Download ONNX models | |
| shell: pwsh | |
| run: | | |
| & scripts/download-model.ps1 | |
| - name: Download VC++ Redistributable | |
| shell: pwsh | |
| run: | | |
| & scripts/download-vcredist.ps1 | |
| # 자동 업데이트: | |
| # - TAURI_SIGNING_PRIVATE_KEY: ed25519 개인키 (`pnpm tauri signer generate -w`로 생성한 ~/.tauri/docufinder.key 내용) | |
| # - TAURI_SIGNING_PRIVATE_KEY_PASSWORD: 키 생성 시 비밀번호 (없으면 생략 가능) | |
| # includeUpdaterJson=true 이면 tauri-action 이 latest.json 을 NSIS zip + .sig 와 함께 | |
| # Release 에 업로드 → tauri-plugin-updater 가 자동 인식. | |
| # 태그 커밋 메시지에서 "release:" 이후 본문을 Release notes 로 추출 | |
| - name: Extract release notes from tag commit | |
| id: notes | |
| shell: bash | |
| run: | | |
| MSG=$(git log -1 --pretty=%B "${{ github.ref_name }}" | sed -e 's/^release: [^—]*—\s*//') | |
| { | |
| echo "body<<NOTES_EOF" | |
| echo "$MSG" | |
| echo "NOTES_EOF" | |
| } >> "$GITHUB_OUTPUT" | |
| - uses: tauri-apps/tauri-action@v0 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} | |
| TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} | |
| # 오류 자동 리포트 (build-time 환경변수로 바이너리에 주입) | |
| TELEGRAM_BOT_TOKEN: ${{ secrets.TELEGRAM_BOT_TOKEN }} | |
| TELEGRAM_CHAT_ID: ${{ secrets.TELEGRAM_CHAT_ID }} | |
| with: | |
| tagName: v__VERSION__ | |
| releaseName: 'Anything v__VERSION__' | |
| releaseBody: ${{ steps.notes.outputs.body }} | |
| releaseDraft: false | |
| prerelease: false | |
| includeUpdaterJson: true | |
| updaterJsonPreferNsis: true | |
| # 디버그 심볼 (PDB) 업로드 — 사용자 크래시 덤프(.dmp) 의 콜스택 풀이용. | |
| # Cargo.toml [profile.release] 의 strip / debug 설정에 따라 PDB 가 생성될 때만 업로드. | |
| - name: Upload PDB to release (if present) | |
| if: success() | |
| shell: pwsh | |
| run: | | |
| $pdb = "src-tauri/target/release/docufinder.pdb" | |
| if (Test-Path $pdb) { | |
| gh release upload "${{ github.ref_name }}" $pdb --clobber | |
| Write-Host "Uploaded $pdb to release ${{ github.ref_name }}" | |
| } else { | |
| Write-Host "No PDB found at $pdb (release profile likely has strip enabled), skipping" | |
| } | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| # Microsoft Edge WebView2 Runtime Standalone Installer 동봉. | |
| # 일반 사용자는 NSIS installer 가 알아서 WebView2 를 깔지만, | |
| # WebView2 가 없는 환경에서 installMode:currentUser 권한으로 설치 시 일부 | |
| # 시스템 등록 단계가 부분 실패하여 wry 가 detect 못 하는 경로가 있음 | |
| # (회사 PC / LTSC 1809 / GPO 차단 환경 등). 이 경우 사용자가 별도로 | |
| # 다운받아 관리자 권한으로 선설치할 수 있도록 release 에 함께 첨부. | |
| # | |
| # [v2.6.18] linkid 교정: 2099617 은 X86 installer 다 (이슈 #23 검증 — | |
| # go.microsoft.com redirect 가 ...InstallerX86.exe). X64 런타임용 standalone | |
| # 은 linkid=2124701 (...InstallerX64.exe). 잘못된 파일명(X64.exe)으로 X86 | |
| # 을 올려 사용자가 x86 런타임을 깔던 배포 버그를 수정. | |
| # NOTE: standalone installer exe **자체**의 PE 는 x86 stub 이 정상이다 (어느 | |
| # 아키텍처 머신에서도 실행돼야 하므로). 설치되는 런타임 arch 는 linkid 가 | |
| # 결정하므로 installer exe 의 PE 검증은 무의미 — 다운로드 크기만 sanity check. | |
| - name: Download & upload WebView2 Standalone Installer | |
| if: success() | |
| shell: pwsh | |
| run: | | |
| $url = "https://go.microsoft.com/fwlink/?linkid=2124701" | |
| $out = "MicrosoftEdgeWebView2RuntimeInstallerX64.exe" | |
| [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 | |
| Invoke-WebRequest -Uri $url -OutFile $out -UseBasicParsing | |
| $size = (Get-Item $out).Length | |
| # sanity check — 정상 standalone installer 는 ~190MB. HTML 에러 페이지 등은 수 KB. | |
| if ($size -lt 50MB) { | |
| Write-Error "standalone installer 다운로드 비정상 ($size bytes) — 중단." | |
| exit 1 | |
| } | |
| Write-Host "Downloaded WebView2 X64 standalone installer: $size bytes" | |
| gh release upload "${{ github.ref_name }}" $out --clobber | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| # [v2.6.4] LTSC 1809 / admin 권한 없는 / GPO 차단 환경 전용 별도 installer build. | |
| # 기본 installer 는 system WebView2 Runtime 에 의존하지만, 이 build 는 EBWebView | |
| # 폴더 자체를 NSIS resources 로 통째 bundle (~170MB 추가). 사용자는 LTSC installer | |
| # 한 번 실행이면 끝 — zip 풀기 / standalone installer admin 권한 / registry 등록 | |
| # 같은 수동 단계 0. lib.rs::webview2_runtime 가 설치 후 EBWebView 를 detect 해 | |
| # 직접 만든 ICoreWebView2Environment 를 wry 에 inject. | |
| # | |
| # v2.5.27 의 webviewInstallMode:fixedRuntime 회귀를 피하기 위해 그 모드는 안 쓰고 | |
| # bundle.resources 일반 파일로 EBWebView 를 추가 (kordoc/vcredist 처리 경로와 동일). | |
| - name: Prepare EBWebView for LTSC variant (copy runner Edge → src-tauri/resources/) | |
| if: success() | |
| shell: pwsh | |
| run: ./scripts/setup-webview2-runtime.ps1 | |
| - name: Build LTSC installer (tauri build --config tauri.windows-ltsc.conf.json) | |
| if: success() | |
| shell: pwsh | |
| run: | | |
| pnpm exec tauri build --config src-tauri/tauri.windows-ltsc.conf.json | |
| env: | |
| # 동일 signing key 로 LTSC installer 도 서명. updater latest.json 은 | |
| # tauri.windows-ltsc.conf.json 의 createUpdaterArtifacts:false 로 차단 → | |
| # 첫 build 의 updater 아티팩트가 보존된다. | |
| TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} | |
| TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} | |
| TELEGRAM_BOT_TOKEN: ${{ secrets.TELEGRAM_BOT_TOKEN }} | |
| TELEGRAM_CHAT_ID: ${{ secrets.TELEGRAM_CHAT_ID }} | |
| - name: Rename + upload LTSC installer to release | |
| if: success() | |
| shell: pwsh | |
| run: | | |
| $tag = "${{ github.ref_name }}" | |
| $ver = $tag.TrimStart('v') | |
| $src = "src-tauri/target/release/bundle/nsis/Anything_${ver}_x64-setup.exe" | |
| if (-not (Test-Path $src)) { | |
| Write-Error "LTSC build output not found: $src" | |
| exit 1 | |
| } | |
| $dst = "Anything_${ver}_x64-ltsc-setup.exe" | |
| Move-Item $src $dst -Force | |
| $size = [math]::Round((Get-Item $dst).Length / 1MB, 1) | |
| Write-Host "LTSC installer: $dst ($size MB) — uploading to release $tag" | |
| gh release upload $tag $dst --clobber | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| publish-macos: | |
| name: Build & Release (macOS arm64) | |
| needs: validate | |
| permissions: | |
| contents: write | |
| runs-on: macos-14 # Apple Silicon runner | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: pnpm/action-setup@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: 20 | |
| cache: pnpm | |
| - uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: aarch64-apple-darwin | |
| - uses: Swatinem/rust-cache@v2 | |
| with: | |
| workspaces: src-tauri | |
| key: macos-arm64 | |
| - name: Install frontend dependencies | |
| run: pnpm install --frozen-lockfile | |
| # kordoc 소스 체크아웃 (Windows job 과 동일한 SHA 고정) | |
| # GitHub Actions 보안상 path 는 workspace 내부만 허용 → kordoc-src 사용. | |
| # SHA 고정 — windows job 과 동일 SHA 유지 (버전 동기화). | |
| - name: Checkout kordoc | |
| uses: actions/checkout@v4 | |
| with: | |
| repository: chrisryugj/kordoc | |
| path: kordoc-src | |
| ref: 2645250c5e0edae7869d28c8c323ec58f2ee7f10 | |
| - name: Build kordoc dist | |
| working-directory: kordoc-src | |
| run: | | |
| npm ci | |
| npm run build | |
| test -f dist/cli.js || { echo "kordoc build output missing"; exit 1; } | |
| - name: Bundle macOS resources (node + kordoc + ORT dylib) | |
| env: | |
| KORDOC_DIR: ${{ github.workspace }}/kordoc-src | |
| run: bash scripts/setup-macos-resources.sh | |
| - name: Tauri build (aarch64-apple-darwin, ad-hoc signed) | |
| run: pnpm exec tauri build --target aarch64-apple-darwin | |
| # v2.6.10: --options runtime (Hardened Runtime) 제거. | |
| # 배경: | |
| # v2.6.7 에서 entitlements.plist + Hardened Runtime 으로 OCR(onnxruntime) dlopen | |
| # SIGKILL 을 풀려 했으나, ad-hoc 서명(signingIdentity:"-") 환경에서는 OS 가 | |
| # entitlements 의 신뢰성을 검증하지 못해 disable-library-validation 권한이 | |
| # 사실상 무시된다. 결과적으로 Hardened Runtime 만 켜지고 entitlements 는 | |
| # 안 먹어 Library Validation 이 외부 dylib 페이지를 invalid 로 판단, | |
| # SIGKILL(Code Signature Invalid / Namespace CODESIGNING, Code 2, Invalid Page). | |
| # 해결: Hardened Runtime 자체를 끄면 Library Validation 강제가 없어진다. | |
| # ad-hoc + no hardened runtime → dlopen 정상. | |
| # inside-out 서명 순서는 그대로 (resources/dylib → 메인 바이너리 → .app 번들). | |
| - name: Re-apply ad-hoc signature (no hardened runtime) | |
| run: | | |
| APP="src-tauri/target/aarch64-apple-darwin/release/bundle/macos/Anything.app" | |
| if [ -d "$APP" ]; then | |
| # 1) 번들된 외부 dylib (libonnxruntime.dylib 등) 먼저 서명 | |
| find "$APP/Contents/Resources" -name "*.dylib" -print0 2>/dev/null \ | |
| | xargs -0 -I{} codesign --force --sign - "{}" | |
| # 2) 메인 실행 바이너리 ad-hoc 재서명 (hardened runtime 미적용) | |
| codesign --force --sign - "$APP/Contents/MacOS/docufinder" || true | |
| # 3) .app 번들 전체 deep 재서명 | |
| codesign --force --deep --sign - "$APP" | |
| # 검증 로그 | |
| codesign -dv "$APP" 2>&1 | head -20 || true | |
| fi | |
| - name: Upload dmg to release | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| DMG=$(ls src-tauri/target/aarch64-apple-darwin/release/bundle/dmg/*.dmg 2>/dev/null | head -1) | |
| if [ -z "$DMG" ]; then | |
| echo "no dmg artifact found"; exit 1 | |
| fi | |
| TAG="${{ github.ref_name }}" | |
| # Release 가 아직 없으면 (Windows job 보다 먼저 끝났거나 Windows job 실패한 경우) | |
| # mac 단독 release 생성. 이미 있으면 추가 업로드만. | |
| if ! gh release view "$TAG" --json id >/dev/null 2>&1; then | |
| echo "Release $TAG 없음 → 새로 생성" | |
| gh release create "$TAG" \ | |
| --title "Anything $TAG" \ | |
| --generate-notes \ | |
| "$DMG" | |
| else | |
| echo "Release $TAG 존재 → dmg 추가 업로드" | |
| gh release upload "$TAG" "$DMG" --clobber | |
| fi |