Repository navigation
132 lines (126 loc) · 5.82 KB
/
Copy pathrelease.yml
File metadata and controls
132 lines (126 loc) · 5.82 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
122
123
124
125
126
127
128
129
130
131
132
name: release
on:
push:
tags: ["v*"]
permissions: {}
concurrency:
group: release-${{ github.ref_name }}
cancel-in-progress: false
env:
GOTOOLCHAIN: local
jobs:
build:
if: github.repository == 'ModAVD/ModAVDManager'
runs-on: windows-2025
timeout-minutes: 20
permissions:
contents: read
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
fetch-depth: 0
# the exact toolchain line, as in ci.yml (setup-go would resolve "go 1.26" to the newest 1.26.x)
- name: go version
id: go
shell: pwsh
run: |
$v = (Select-String -LiteralPath go.mod -Pattern '^toolchain\s+go(\S+)' | Select-Object -First 1).Matches.Groups[1].Value
if (-not $v) { throw 'go.mod has no toolchain line' }
"version=$v" >> $env:GITHUB_OUTPUT
- uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version: ${{ steps.go.outputs.version }}
cache: false
- name: verify tag and ancestry
shell: pwsh
env:
TAG: ${{ github.ref_name }}
SHA: ${{ github.sha }}
run: |
if ($env:TAG -notmatch '^v\d+\.\d+\.\d+$') { throw "invalid tag: $env:TAG" }
# Full ref names: a tag called origin/main would win over the remote branch.
# On main, or on any release/* branch.
git merge-base --is-ancestor $env:SHA refs/remotes/origin/main
$onBranch = ($LASTEXITCODE -eq 0)
if (-not $onBranch) {
foreach ($ref in @(git for-each-ref --format='%(refname)' refs/remotes/origin/release/)) {
git merge-base --is-ancestor $env:SHA $ref
if ($LASTEXITCODE -eq 0) { $onBranch = $true; break }
}
}
if (-not $onBranch) { throw 'tag is not on origin/main or any origin/release/* branch' }
- name: build and verify
shell: pwsh
env:
TAG: ${{ github.ref_name }}
run: |
$version = $env:TAG.Substring(1)
$want = (Select-String -LiteralPath 'internal/buildinfo/buildinfo.go' -Pattern 'Version = "([^"]+)"').Matches.Groups[1].Value
if ($want -ne $version) { throw "buildinfo.Version=$want, tag=$version" }
pwsh -NoProfile -File build.ps1 -Out out
if ($LASTEXITCODE -ne 0) { throw 'build.ps1 failed' }
$sums = @{}
foreach ($line in Get-Content "release/$version.SHA256SUMS.txt") { if ($line -match '^([0-9a-f]{64}) (.+)$') { $sums[$Matches[2]] = $Matches[1] } }
foreach ($name in @('ModAVD.exe', 'tools/modavd.exe')) {
$got = (Get-FileHash "out/$name" -Algorithm SHA256).Hash.ToLowerInvariant()
if ($got -ne $sums[$name]) { throw "$name hash mismatch" }
}
$zip = "ModAVDManager-$version-win-x64.zip"
go run ./internal/tools/mkzip -dir out -version $version -out $zip
if ($LASTEXITCODE -ne 0) { throw 'mkzip failed' }
$gotZip = (Get-FileHash $zip -Algorithm SHA256).Hash.ToLowerInvariant()
if ($gotZip -ne $sums[$zip]) { throw 'zip hash mismatch' }
New-Item -ItemType Directory -Force artifacts | Out-Null
Copy-Item $zip artifacts
Copy-Item "release/$version.SHA256SUMS.txt" "artifacts/SHA256SUMS.txt"
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: release-assets
path: artifacts
if-no-files-found: error
draft:
needs: build
runs-on: windows-2025
timeout-minutes: 10
permissions:
contents: write
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
fetch-depth: 1
- uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
with:
name: release-assets
path: artifacts
- name: verify artifact
shell: pwsh
env:
TAG: ${{ github.ref_name }}
run: |
# Checked against the tag's own list, not only the copy that travelled with the artifact.
$version = $env:TAG.Substring(1)
$zip = "ModAVDManager-$version-win-x64.zip"
$sums = Get-Content -Raw "release/$version.SHA256SUMS.txt"
if ((Get-Content -Raw artifacts/SHA256SUMS.txt) -cne $sums) { throw 'artifact SHA256SUMS.txt differs from the tag' }
$have = (Get-ChildItem artifacts -File | ForEach-Object Name | Sort-Object) -join ','
$expect = (@($zip, 'SHA256SUMS.txt') | Sort-Object) -join ','
if ($have -cne $expect) { throw "unexpected artifact files: $have" }
$want = [regex]::Match($sums, "(?m)^([0-9a-f]{64}) $([regex]::Escape($zip))$").Groups[1].Value
$got = (Get-FileHash "artifacts/$zip" -Algorithm SHA256).Hash.ToLowerInvariant()
if (-not $want -or $got -ne $want) { throw 'downloaded zip hash mismatch' }
- name: create draft
shell: pwsh
env:
TAG: ${{ github.ref_name }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
run: |
$version = $env:TAG.Substring(1)
# Drafts are not bound to their tag, so one tag can collect several: list every release, drafts included.
$tags = gh api "repos/$env:GH_REPO/releases?per_page=100" --paginate --jq '.[].tag_name'
if ($LASTEXITCODE -ne 0) { throw 'cannot list releases' }
if ($tags -contains $env:TAG) { throw "a release for $env:TAG already exists (draft or published)" }
gh release create $env:TAG --draft --verify-tag --notes-file "release/$version.md" "artifacts/ModAVDManager-$version-win-x64.zip" artifacts/SHA256SUMS.txt
if ($LASTEXITCODE -ne 0) { throw 'gh release create failed' }