chore(release): 3.0.6 — 커넥션 풀 경로 격리 (통합테스트 flaky 수정) #98
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를 갱신. | |
| # 현재: v3.1.1 (HWP5 바이너리 서식 보존 + 에디터 API + 문단 들여쓰기 보존) — 2026-06-13 | |
| - name: Checkout kordoc | |
| uses: actions/checkout@v4 | |
| with: | |
| repository: chrisryugj/kordoc | |
| path: kordoc-src | |
| ref: cd8fd81912840ac76d7a976592e393b13c024a2b | |
| - 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.24] 사내 폐쇄망 권장 설치 경로의 핵심 산출물. | |
| # 단일 통합본(ltsc-setup ~573MB, Fixed Runtime 번들)은 (1) 망간/단방향 전송 | |
| # 솔루션에서 파일 무결성이 깨지고, (2) Fixed Runtime inject 경로가 controller | |
| # 생성 단계에서 hang 하는 회귀가 #23/#24 내내 반복돼 폐기했다(이슈 #29 JS190-prog | |
| # 실증: 일반 setup.exe + 이 standalone 을 따로 전송해 각각 설치하면 성공). | |
| # 이제 사내망 사용자는 [일반 setup.exe] + [이 standalone WebView2] 두 파일을 | |
| # 나눠 전송 후 설치한다 — 큰 단일 파일보다 전송 성공률이 높고, system runtime | |
| # 경로라 controller hang 도 없다. 고급 사용자용 수동 Fixed Runtime fallback 은 | |
| # webview2_runtime.rs 의 EBWebView 탐색으로 여전히 동작한다. | |
| # | |
| # [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.24] LTSC 단일 통합 installer(ltsc-setup ~573MB) 빌드를 폐기했다. | |
| # 배경: Fixed Version Runtime 을 NSIS 에 통째 bundle 하는 노선은 | |
| # 1) 573MB 단일 exe 가 망간/단방향 전송에서 무결성이 깨져 설치 불가, | |
| # 2) Fixed Runtime inject 후 WebView2 controller 생성이 hang (#23/#24), | |
| # 두 문제로 사내망에서 실패했다. 대신 [일반 setup.exe(offlineInstaller)] + | |
| # [위 standalone WebView2] 분리 배포로 전환 — 두 파일을 나눠 전송/설치하면 | |
| # 망간 전송 무결성·system runtime 안정성을 모두 확보한다(이슈 #29). | |
| # 관련 스크립트(scripts/setup-webview2-runtime.ps1, src-tauri/tauri.windows-ltsc.conf.json)는 | |
| # 고급 사용자용 수동 Fixed Runtime 배포 참고용으로 남겨둔다. | |
| 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: cd8fd81912840ac76d7a976592e393b13c024a2b | |
| - 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 |