main
yml 308 lines 8.61 KB
Raw
1 name: release-assets
2
3 on:
4 workflow_dispatch:
5 inputs:
6 tag:
7 description: 'Release tag (e.g., v3.0.2)'
8 required: true
9 type: string
10 signing_policy:
11 description: 'SignPath signing policy slug'
12 required: true
13 default: release-signing
14 type: string
15 commitish:
16 description: 'Target branch or commit (optional)'
17 required: false
18 type: string
19
20 env:
21 NODE_VERSION: '22'
22
23 jobs:
24 windows:
25 runs-on: windows-latest
26 permissions:
27 actions: write
28 contents: read
29 steps:
30 - name: Checkout
31 uses: actions/checkout@v4
32
33 - name: Resolve Windows pkg target
34 id: pkg_target
35 shell: pwsh
36 run: |
37 # keep workflow and package.json aligned by deriving the Windows pkg target from a single source of truth
38 $pkg = Get-Content package.json -Raw | ConvertFrom-Json
39 $target = @($pkg.pkg.targets) | Where-Object { $_ -match '-win-x64$' } | Select-Object -First 1
40 if (-not $target) {
41 throw "No Windows pkg target (-win-x64) found in package.json"
42 }
43 if ($target -notmatch '^node(\d+)-') {
44 throw "Unsupported pkg target format: $target"
45 }
46 "target=$target" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append
47
48 - name: Setup Node
49 uses: actions/setup-node@v4
50 with:
51 node-version: ${{ env.NODE_VERSION }}
52 cache: npm
53
54 - name: Install dependencies
55 run: npm ci
56
57 - name: Build server and UIs
58 run: |
59 npm run build-server
60 npm run build-frontend
61 npm run build-admin
62
63 - name: Prepare dist dependencies
64 run: npm run dist-modules
65
66 - name: Build Windows binary
67 run: |
68 cd dist
69 npx pkg . --public -C gzip -t ${{ steps.pkg_target.outputs.target }}
70 npx resedit-cli --in hfs.exe --icon 1,../hfs.ico --out hfs.exe
71
72 - name: Prepare unsigned artifact folder
73 shell: pwsh
74 run: |
75 New-Item -ItemType Directory -Force -Path dist/signpath | Out-Null
76 Copy-Item dist/hfs.exe dist/signpath/hfs.exe -Force
77 Copy-Item dist/plugins dist/signpath/plugins -Recurse -Force
78
79 - name: Upload unsigned artifact
80 id: upload_unsigned
81 uses: actions/upload-artifact@v4
82 with:
83 name: hfs-windows-unsigned
84 path: dist/signpath/**
85
86 - name: Sign with SignPath
87 uses: SignPath/github-action-submit-signing-request@v1
88 with:
89 api-token: ${{ secrets.SIGNPATH_API_TOKEN }}
90 organization-id: ${{ secrets.SIGNPATH_ORGANIZATION_ID }}
91 project-slug: hfs
92 artifact-configuration-slug: hfs_win_zip
93 signing-policy-slug: ${{ inputs.signing_policy }}
94 github-artifact-id: ${{ steps.upload_unsigned.outputs.artifact-id }}
95 github-token: ${{ github.token }}
96 output-artifact-directory: dist/signpath-output
97
98 - name: Package signed artifact
99 shell: pwsh
100 run: |
101 $version = node -p "require('./package.json').version"
102 $target = "dist/hfs-windows-x64-$version.zip"
103 $outputDir = 'dist/signpath-output'
104 $zip = Get-ChildItem -Path $outputDir -Filter *.zip -Recurse | Sort-Object LastWriteTime -Descending | Select-Object -First 1
105 if ($zip) {
106 if ((Resolve-Path $target).Path -ne $zip.FullName) {
107 Copy-Item $zip.FullName $target -Force
108 }
109 exit 0
110 }
111 $items = Get-ChildItem -Path $outputDir
112 if (-not $items) {
113 Write-Host 'No signed artifact files found. Listing dist contents for troubleshooting:'
114 Get-ChildItem -Path dist -Recurse | Select-Object FullName
115 throw 'No signed artifact files found after signing.'
116 }
117 Compress-Archive -Path "$outputDir/*" -DestinationPath $target -Force
118
119 - name: Upload signed package
120 uses: actions/upload-artifact@v4
121 with:
122 name: release-assets-windows
123 path: dist/hfs-windows-x64-*.zip
124
125 linux:
126 if: false # all disabled but windows to reduce CI credits consumption
127 runs-on: ubuntu-latest
128 needs: windows
129 permissions:
130 actions: write
131 contents: read
132 steps:
133 - name: Checkout
134 uses: actions/checkout@v4
135
136 - name: Setup Node
137 uses: actions/setup-node@v4
138 with:
139 node-version: ${{ env.NODE_VERSION }}
140 cache: npm
141
142 - name: Install dependencies
143 run: npm ci
144
145 - name: Build server and UIs
146 run: |
147 npm run build-server
148 npm run build-frontend
149 npm run build-admin
150
151 - name: Prepare dist dependencies
152 run: npm run dist-modules
153
154 - name: Build Linux binary
155 run: npm run dist-bin-linux
156
157 - name: Upload Linux package
158 uses: actions/upload-artifact@v4
159 with:
160 name: release-assets-linux
161 path: dist/hfs-linux-x64-*.zip
162
163 linux_arm:
164 if: false
165 runs-on: ubuntu-latest
166 needs: windows
167 permissions:
168 actions: write
169 contents: read
170 steps:
171 - name: Checkout
172 uses: actions/checkout@v4
173
174 - name: Setup Node
175 uses: actions/setup-node@v4
176 with:
177 node-version: ${{ env.NODE_VERSION }}
178 cache: npm
179
180 - name: Install dependencies
181 run: npm ci
182
183 - name: Build server and UIs
184 run: |
185 npm run build-server
186 npm run build-frontend
187 npm run build-admin
188
189 - name: Prepare dist dependencies
190 run: npm run dist-modules
191
192 - name: Build Linux arm64 binary
193 run: npm run dist-bin-linux-arm
194
195 - name: Upload Linux arm64 package
196 uses: actions/upload-artifact@v4
197 with:
198 name: release-assets-linux-arm64
199 path: dist/hfs-linux-arm64-*.zip
200
201 mac_x64:
202 if: false
203 runs-on: macos-15-intel
204 needs: windows
205 permissions:
206 actions: write
207 contents: read
208 steps:
209 - name: Checkout
210 uses: actions/checkout@v4
211
212 - name: Setup Node
213 uses: actions/setup-node@v4
214 with:
215 node-version: ${{ env.NODE_VERSION }}
216 cache: npm
217
218 - name: Install dependencies
219 run: npm ci
220
221 - name: Build server and UIs
222 run: |
223 npm run build-server
224 npm run build-frontend
225 npm run build-admin
226
227 - name: Prepare dist dependencies
228 run: npm run dist-modules
229
230 - name: Build macOS x64 binary
231 run: npm run dist-bin-mac
232
233 - name: Upload macOS x64 package
234 uses: actions/upload-artifact@v4
235 with:
236 name: release-assets-mac-x64
237 path: dist/hfs-mac-x64-*.zip
238
239 mac_arm:
240 if: false
241 runs-on: macos-14
242 needs: windows
243 permissions:
244 actions: write
245 contents: read
246 steps:
247 - name: Checkout
248 uses: actions/checkout@v4
249
250 - name: Setup Node
251 uses: actions/setup-node@v4
252 with:
253 node-version: ${{ env.NODE_VERSION }}
254 cache: npm
255
256 - name: Install dependencies
257 run: npm ci
258
259 - name: Build server and UIs
260 run: |
261 npm run build-server
262 npm run build-frontend
263 npm run build-admin
264
265 - name: Prepare dist dependencies
266 run: npm run dist-modules
267
268 - name: Build macOS arm64 binary
269 run: npm run dist-bin-mac-arm
270
271 - name: Upload macOS arm64 package
272 uses: actions/upload-artifact@v4
273 with:
274 name: release-assets-mac-arm
275 path: dist/hfs-mac-arm64-*.zip
276
277 release:
278 runs-on: ubuntu-latest
279 needs:
280 - windows
281 permissions:
282 contents: write
283 steps:
284 - name: Download assets
285 uses: actions/download-artifact@v4
286 with:
287 pattern: release-assets-*
288 merge-multiple: true
289 path: release-assets
290
291 - name: Normalize release title
292 id: release_title
293 shell: bash
294 run: |
295 # keep the release tag untouched, but strip the optional leading v from the display title
296 tag='${{ inputs.tag }}'
297 echo "name=${tag#v}" >> "$GITHUB_OUTPUT"
298
299 - name: Create draft release
300 uses: softprops/action-gh-release@v2
301 with:
302 tag_name: ${{ inputs.tag }}
303 name: ${{ steps.release_title.outputs.name }}
304 # release tags with a dash are treated as pre-releases so beta-style builds stay separated from stable ones
305 prerelease: ${{ contains(inputs.tag, '-') }}
306 target_commitish: ${{ inputs.commitish || github.event.repository.default_branch }}
307 draft: true
308 files: release-assets/*.zip