| 1 | name: signpath-windows |
| 2 | |
| 3 | on: |
| 4 | workflow_dispatch: |
| 5 | |
| 6 | jobs: |
| 7 | build-sign: |
| 8 | runs-on: windows-latest |
| 9 | permissions: |
| 10 | contents: read |
| 11 | env: |
| 12 | NODE_VERSION: '22' |
| 13 | steps: |
| 14 | - name: Checkout |
| 15 | uses: actions/checkout@v4 |
| 16 | |
| 17 | - name: Resolve Windows pkg target |
| 18 | id: pkg_target |
| 19 | shell: pwsh |
| 20 | run: | |
| 21 | # keep workflow and package.json aligned by deriving the Windows pkg target from a single source of truth |
| 22 | $pkg = Get-Content package.json -Raw | ConvertFrom-Json |
| 23 | $target = @($pkg.pkg.targets) | Where-Object { $_ -match '-win-x64$' } | Select-Object -First 1 |
| 24 | if (-not $target) { |
| 25 | throw "No Windows pkg target (-win-x64) found in package.json" |
| 26 | } |
| 27 | if ($target -notmatch '^node(\d+)-') { |
| 28 | throw "Unsupported pkg target format: $target" |
| 29 | } |
| 30 | "target=$target" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append |
| 31 | |
| 32 | - name: Setup Node |
| 33 | uses: actions/setup-node@v4 |
| 34 | with: |
| 35 | node-version: ${{ env.NODE_VERSION }} |
| 36 | cache: npm |
| 37 | |
| 38 | - name: Install dependencies |
| 39 | run: npm ci |
| 40 | |
| 41 | - name: Build server and UIs |
| 42 | run: | |
| 43 | npm run build-server |
| 44 | npm run build-frontend |
| 45 | npm run build-admin |
| 46 | |
| 47 | - name: Prepare dist dependencies |
| 48 | run: npm run dist-modules |
| 49 | |
| 50 | - name: Build Windows binary |
| 51 | run: | |
| 52 | cd dist |
| 53 | npx pkg . --public -C gzip -t ${{ steps.pkg_target.outputs.target }} |
| 54 | npx resedit-cli --in hfs.exe --icon 1,../hfs.ico --out hfs.exe |
| 55 | |
| 56 | - name: Prepare unsigned artifact folder |
| 57 | shell: pwsh |
| 58 | run: | |
| 59 | New-Item -ItemType Directory -Force -Path dist/signpath | Out-Null |
| 60 | Copy-Item dist/hfs.exe dist/signpath/hfs.exe -Force |
| 61 | Copy-Item dist/plugins dist/signpath/plugins -Recurse -Force |
| 62 | |
| 63 | - name: Upload unsigned artifact |
| 64 | id: upload_unsigned |
| 65 | uses: actions/upload-artifact@v4 |
| 66 | with: |
| 67 | name: hfs-windows-unsigned |
| 68 | path: dist/signpath/** |
| 69 | |
| 70 | - name: Sign with SignPath |
| 71 | uses: SignPath/github-action-submit-signing-request@v1 |
| 72 | with: |
| 73 | api-token: ${{ secrets.SIGNPATH_API_TOKEN }} |
| 74 | organization-id: ${{ secrets.SIGNPATH_ORGANIZATION_ID }} |
| 75 | project-slug: hfs |
| 76 | artifact-configuration-slug: hfs_win_zip |
| 77 | signing-policy-slug: release-signing |
| 78 | github-artifact-id: ${{ steps.upload_unsigned.outputs.artifact-id }} |
| 79 | github-token: ${{ secrets.GITHUB_TOKEN }} |
| 80 | output-artifact-directory: dist/signpath-output |
| 81 | |
| 82 | - name: Package signed artifact |
| 83 | shell: pwsh |
| 84 | run: | |
| 85 | $outputDir = 'dist/signpath-output' |
| 86 | $zip = Get-ChildItem -Path $outputDir -Filter *.zip -Recurse | Sort-Object LastWriteTime -Descending | Select-Object -First 1 |
| 87 | if ($zip) { |
| 88 | Copy-Item $zip.FullName 'dist/hfs-windows-x64-signed.zip' -Force |
| 89 | exit 0 |
| 90 | } |
| 91 | $items = Get-ChildItem -Path $outputDir |
| 92 | if (-not $items) { |
| 93 | Write-Host 'No signed artifact files found. Listing dist contents for troubleshooting:' |
| 94 | Get-ChildItem -Path dist -Recurse | Select-Object FullName |
| 95 | throw 'No signed artifact files found after signing.' |
| 96 | } |
| 97 | Compress-Archive -Path "$outputDir/*" -DestinationPath 'dist/hfs-windows-x64-signed.zip' -Force |
| 98 | |
| 99 | - name: Upload signed package |
| 100 | uses: actions/upload-artifact@v4 |
| 101 | with: |
| 102 | name: hfs-windows-signed |
| 103 | path: dist/hfs-windows-x64-signed.zip |