-
Notifications
You must be signed in to change notification settings - Fork 3
183 lines (164 loc) · 6.74 KB
/
Copy pathrelease.yml
File metadata and controls
183 lines (164 loc) · 6.74 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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
name: Release
on:
workflow_dispatch:
inputs:
version:
description: 'Version to build and release (e.g. 3.0.0)'
required: true
type: string
push:
tags:
- 'release_*'
permissions:
contents: read
concurrency:
group: release-${{ github.ref }}
cancel-in-progress: false
jobs:
version:
name: Resolve version
runs-on: ubuntu-latest
outputs:
version: ${{ steps.resolve.outputs.version }}
steps:
- name: Resolve and validate version
id: resolve
shell: pwsh
env:
INPUT_VERSION: ${{ inputs.version }}
REF_NAME: ${{ github.ref_name }}
EVENT_NAME: ${{ github.event_name }}
run: |
$version = if ($env:EVENT_NAME -eq 'workflow_dispatch') { $env:INPUT_VERSION } else { $env:REF_NAME -replace '^release_', '' }
$version = "$version".Trim()
if ($version -notmatch '^\d+\.\d+\.\d+$') { throw "Invalid version '$version' - expected a three-part version such as 3.0.0." }
"version=$version" >> $env:GITHUB_OUTPUT
Write-Host "Release version: $version"
verify:
name: Verify build & tests
needs: [version]
runs-on: windows-latest
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Set up .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: 10.0.x
cache: true
cache-dependency-path: '**/*.csproj'
- name: Verify csproj version matches
shell: pwsh
env:
VERSION: ${{ needs.version.outputs.version }}
run: |
[xml]$core = Get-Content -LiteralPath SimpleZipDrive.Core\SimpleZipDrive.Core.csproj
$assemblyVersion = $core.Project.PropertyGroup.AssemblyVersion | Where-Object { $_ } | Select-Object -First 1
if ($assemblyVersion -ne $env:VERSION) {
throw "Version mismatch: release $($env:VERSION) but SimpleZipDrive.Core AssemblyVersion is '$assemblyVersion'. Bump all five csproj files first."
}
- name: Restore
run: dotnet restore CSharp_SimpleZipDrive.sln
- name: Build (Release)
run: dotnet build CSharp_SimpleZipDrive.sln -c Release --no-restore
- name: Test
run: dotnet test SimpleZipDrive.Tests\SimpleZipDrive.Tests.csproj -c Release --no-build
bundles:
name: Build bundles
needs: [version, verify]
runs-on: windows-latest
env:
VERSION: ${{ needs.version.outputs.version }}
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Set up .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: 10.0.x
cache: true
cache-dependency-path: '**/*.csproj'
- name: Package the four per-variant bundles
shell: pwsh
run: |
.\scripts\package-release.ps1 -Version $env:VERSION -OutputDirectory "$env:RUNNER_TEMP\bundles" -StagingDirectory "$env:RUNNER_TEMP\staging" -SkipTests
- name: Generate release notes from WhatsNew.md
shell: pwsh
run: |
$content = Get-Content -LiteralPath WhatsNew.md -Raw
$pattern = "(?ms)^##\s+$([regex]::Escape($env:VERSION))\s*\r?\n(.*?)(?=^##\s+|\z)"
$match = [regex]::Match($content, $pattern)
if ($match.Success) {
$notes = $match.Groups[1].Value.Trim()
} else {
$notes = "Release $($env:VERSION). See WhatsNew.md for the full changelog."
}
$notes += "`n`n---`n`nFull changelog: [$env:GITHUB_SERVER_URL/$env:GITHUB_REPOSITORY/blob/master/WhatsNew.md]($env:GITHUB_SERVER_URL/$env:GITHUB_REPOSITORY/blob/master/WhatsNew.md)"
Set-Content -LiteralPath "$env:RUNNER_TEMP\bundles\release-notes.md" -Value $notes -Encoding utf8
- name: Write review summary with checksums
shell: pwsh
run: |
$lines = @('## Bundles ready for review', '', 'Download the **release-bundles** artifact below and inspect the zips before approving the release.', '')
Get-ChildItem -LiteralPath "$env:RUNNER_TEMP\bundles" -Filter *.zip | Sort-Object Name | ForEach-Object {
$hash = (Get-FileHash -LiteralPath $_.FullName -Algorithm SHA256).Hash
$lines += ('- `{0}` - {1:N0} bytes - SHA256 `{2}`' -f $_.Name, $_.Length, $hash)
}
$lines += ''
$lines += 'The **Publish release** job is waiting for approval in the protected `release` environment.'
$lines | Set-Content -LiteralPath $env:GITHUB_STEP_SUMMARY -Encoding utf8
- name: Upload bundles for review
uses: actions/upload-artifact@v7
with:
name: release-bundles
path: |
${{ runner.temp }}/bundles/*.zip
${{ runner.temp }}/bundles/release-notes.md
if-no-files-found: error
retention-days: 30
publish:
name: Publish release (approval required)
needs: [version, bundles]
runs-on: ubuntu-latest
environment: release
permissions:
contents: write
env:
VERSION: ${{ needs.version.outputs.version }}
GH_TOKEN: ${{ github.token }}
GH_REPO: ${{ github.repository }}
steps:
- name: Download bundles
uses: actions/download-artifact@v8
with:
name: release-bundles
path: bundles
- name: Verify the four expected bundles are present
shell: pwsh
run: |
$expected = @(
"release_$($env:VERSION)_Dokan_win-x64.zip",
"release_$($env:VERSION)_Dokan_win-arm64.zip",
"release_$($env:VERSION)_WinFsp_win-x64.zip",
"release_$($env:VERSION)_WinFsp_win-arm64.zip"
)
foreach ($name in $expected) {
if (-not (Test-Path -LiteralPath (Join-Path 'bundles' $name))) { throw "Missing expected bundle: $name" }
}
Get-ChildItem -LiteralPath bundles -File | Select-Object Name, Length
- name: Create or update the GitHub release
shell: bash
env:
EVENT_NAME: ${{ github.event_name }}
RELEASE_SHA: ${{ github.sha }}
run: |
TAG="release_${VERSION}"
if gh release view "$TAG" >/dev/null 2>&1; then
echo "Release $TAG already exists - updating notes and uploading/replacing the four bundles."
gh release edit "$TAG" --notes-file bundles/release-notes.md
gh release upload "$TAG" bundles/*.zip --clobber
elif [ "$EVENT_NAME" = "workflow_dispatch" ]; then
gh release create "$TAG" --title "$VERSION" --target "$RELEASE_SHA" --notes-file bundles/release-notes.md bundles/*.zip
else
gh release create "$TAG" --title "$VERSION" --notes-file bundles/release-notes.md bundles/*.zip
fi
echo "Published: $(gh release view "$TAG" --json url --jq .url)"