Repository navigation
121 lines (113 loc) · 5.85 KB
/
Copy pathrelease.yml
File metadata and controls
121 lines (113 loc) · 5.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# Keep the published release in step with main.
#
# The problem this exists for: v0.1.0 shipped, a fix landed on main, and the release kept
# handing people the old installer. Worse, that stale build was then installed over a dev
# machine and silently took a working fix away with it. So the rule is now mechanical rather
# than remembered: every push to main that can change the binary rebuilds the installer and
# replaces the asset on the release for whatever version src/version.h names.
#
# Versioning: src/version.h is the only place a version is declared, so bumping it is what
# cuts a NEW release. Pushes that do not touch it refresh the existing one in place, which is
# what keeps the download matching main without a version number per commit.
#
# Unsigned on purpose: no certificate is configured here, and tools/release.ps1 then packs
# both variants; setup signs the uiAccess one on each PC it installs to (issue #261,
# installer/local-sign.ps1) and falls back to the uiAccess=false build. Never put a
# self-signed cert in CI: it would be trusted by nobody and look worse than no signature.
name: release
on:
push:
branches: [ main ]
# Docs cannot change the installer, so they do not need to republish it: a republish gives
# the current release a new asset hash for nothing, resetting what little SmartScreen
# reputation the existing download has earned. A `paths` list rather than paths-ignore,
# because only it can take a file back after a broader pattern dropped it (later lines win).
paths:
- '**'
- '!**.md'
- '!docs/**'
- '!.github/ISSUE_TEMPLATE/**'
# Test harness only. It cannot change the shipped binary.
- '!tools/testenv/**'
# Text that ships IN the installer, so a change to it must republish: the licence it
# shows and installs (wind.nsi, LICENSE.txt), the notices it installs, and the release
# notes this workflow publishes with it.
- 'LICENSE'
- 'THIRD-PARTY-NOTICES.md'
- '.github/release-notes.md'
workflow_dispatch:
permissions:
contents: write
concurrency:
# Two pushes in quick succession must not race to upload the same asset.
group: release
cancel-in-progress: false
jobs:
release:
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
# Version read, unit tests, keybind JS test, Playwright UI suite and tools/release.ps1, shared
# with alpha.yml. Any failing gate fails the job before anything is published.
- name: Build installer (shared with alpha.yml)
id: ver
uses: ./.github/actions/build-installer
- name: Compose release notes
id: notes
shell: pwsh
run: |
$v = '${{ steps.ver.outputs.version }}'
$exe = "dist/Wind-Setup-x64-$v.exe"
if (-not (Test-Path $exe)) { throw "installer not produced: $exe" }
$sha = (Get-FileHash $exe -Algorithm SHA256).Hash
(Get-Content .github/release-notes.md -Raw).
Replace('__VERSION__', $v).
Replace('__SHA256__', $sha).
Replace('__COMMIT__', '${{ github.sha }}'.Substring(0,7)) |
Set-Content notes.md -NoNewline
"sha=$sha" >> $env:GITHUB_OUTPUT
# Create the release the first time this version is seen; afterwards replace the asset
# in place so the download always matches main. --clobber is what makes the refresh
# idempotent: without it a second push to the same version fails on a duplicate name.
- name: Publish or refresh the release
shell: pwsh
env:
GH_TOKEN: ${{ github.token }}
GH_REPO: ${{ github.repository }}
run: |
# Actions runs pwsh with $ErrorActionPreference='Stop', and PowerShell 7.4 turns a
# non-zero NATIVE exit into a throw. `gh release view` exits 1 when the tag does not
# exist yet, which is the normal first-release path, not an error - so exit codes are
# checked by hand here instead of being allowed to abort the step.
$ErrorActionPreference = 'Continue'
$PSNativeCommandUseErrorActionPreference = $false
$v = '${{ steps.ver.outputs.version }}'
$tag = "v$v"
$exe = "dist/Wind-Setup-x64-$v.exe"
# A stable-named copy of the same installer (#343), so this link never needs updating:
# https://github.com/<repo>/releases/latest/download/Wind-Setup-x64.exe always serves
# the newest release. The versioned name stays the primary asset.
$stable = "dist/Wind-Setup-x64.exe"
Copy-Item $exe $stable -Force
gh release view $tag 2>$null | Out-Null
if ($LASTEXITCODE -eq 0) {
Write-Host "refreshing existing release $tag"
gh release edit $tag --notes-file notes.md
if ($LASTEXITCODE -ne 0) { throw 'gh release edit failed' }
gh release upload $tag $exe $stable --clobber
if ($LASTEXITCODE -ne 0) { throw 'gh release upload failed' }
} else {
Write-Host "creating release $tag"
gh release create $tag $exe $stable --target '${{ github.sha }}' --title "Wind $v" --notes-file notes.md
if ($LASTEXITCODE -ne 0) { throw 'gh release create failed' }
}
- name: Summary
shell: pwsh
run: |
$v = '${{ steps.ver.outputs.version }}'
"## Wind $v published" >> $env:GITHUB_STEP_SUMMARY
"" >> $env:GITHUB_STEP_SUMMARY
"- tag ``v$v``" >> $env:GITHUB_STEP_SUMMARY
"- asset ``Wind-Setup-x64-$v.exe``" >> $env:GITHUB_STEP_SUMMARY
"- sha256 ``${{ steps.notes.outputs.sha }}``" >> $env:GITHUB_STEP_SUMMARY
"- unsigned (no certificate configured)" >> $env:GITHUB_STEP_SUMMARY