Skip to content

發佈 v1.0.0.8

發佈 v1.0.0.8 #9

Workflow file for this run

name: Release
on:
push:
tags:
- "v*"
- "V*"
workflow_dispatch:
inputs:
version:
description: "Release version, for example 1.0.1 or v1.0.1"
required: true
type: string
permissions:
contents: write
jobs:
build-release:
name: Build and publish release
runs-on: windows-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup MSBuild
uses: microsoft/setup-msbuild@v2
- name: Setup NuGet
uses: NuGet/setup-nuget@v2
- name: Resolve release version
id: release_version
shell: pwsh
run: |
if ("${{ github.event_name }}" -eq "workflow_dispatch") {
$rawVersion = "${{ inputs.version }}"
} else {
$rawVersion = "${{ github.ref_name }}"
}
$version = $rawVersion.Trim()
if ($version.StartsWith("v", [System.StringComparison]::OrdinalIgnoreCase)) {
$version = $version.Substring(1)
}
if ($version -notmatch '^\d+\.\d+\.\d+(\.\d+)?$') {
throw "Release version must be n.n.n or n.n.n.n. Received: $rawVersion"
}
$tagName = "v$version"
"version=$version" | Out-File -FilePath $env:GITHUB_OUTPUT -Append -Encoding utf8
"tag_name=$tagName" | Out-File -FilePath $env:GITHUB_OUTPUT -Append -Encoding utf8
- name: Verify assembly version matches release
shell: pwsh
run: |
$assemblyInfoPath = ".\mySQLPunk\Properties\AssemblyInfo.cs"
$assemblyInfo = Get-Content -LiteralPath $assemblyInfoPath -Raw -Encoding UTF8
if ($assemblyInfo -notmatch 'AssemblyFileVersion\("([^"]+)"\)') {
throw "AssemblyFileVersion was not found in $assemblyInfoPath"
}
$assemblyVersion = [version]$Matches[1]
$releaseVersion = [version]"${{ steps.release_version.outputs.version }}"
if ($releaseVersion.Revision -lt 0) {
$releaseVersion = [version]::new($releaseVersion.Major, $releaseVersion.Minor, $releaseVersion.Build, 0)
}
if ($assemblyVersion.Revision -lt 0) {
$assemblyVersion = [version]::new($assemblyVersion.Major, $assemblyVersion.Minor, $assemblyVersion.Build, 0)
}
if ($assemblyVersion -ne $releaseVersion) {
throw "AssemblyFileVersion $assemblyVersion does not match release version $releaseVersion. Update AssemblyInfo.cs before publishing."
}
- name: Restore packages
shell: pwsh
run: nuget restore .\mySQLPunk.sln -NonInteractive
- name: Setup Inno Setup
shell: pwsh
run: |
$candidates = @(
"${env:ProgramFiles(x86)}\Inno Setup 6\ISCC.exe",
"$env:ProgramFiles\Inno Setup 6\ISCC.exe",
"$env:LOCALAPPDATA\Programs\Inno Setup 6\ISCC.exe"
)
if ($candidates | Where-Object { Test-Path -LiteralPath $_ } | Select-Object -First 1) {
exit 0
}
$installerPath = Join-Path $env:RUNNER_TEMP "innosetup-6.7.3.exe"
$installerUrl = "https://github.com/jrsoftware/issrc/releases/download/is-6_7_3/innosetup-6.7.3.exe"
$expectedSha256 = "9c73c3bae7ed48d44112a0f48e66742c00090bdb5bef71d9d3c056c66e97b732"
Invoke-WebRequest -Uri $installerUrl -OutFile $installerPath
$actualSha256 = (Get-FileHash -LiteralPath $installerPath -Algorithm SHA256).Hash.ToLowerInvariant()
if ($actualSha256 -ne $expectedSha256) {
throw "Inno Setup installer SHA-256 mismatch. Expected $expectedSha256, got $actualSha256."
}
$process = Start-Process -FilePath $installerPath -ArgumentList "/VERYSILENT", "/SUPPRESSMSGBOXES", "/NORESTART", "/CURRENTUSER" -Wait -PassThru
if ($process.ExitCode -ne 0) {
throw "Inno Setup installation failed with exit code $($process.ExitCode)."
}
$iscc = "$env:LOCALAPPDATA\Programs\Inno Setup 6\ISCC.exe"
if (-not (Test-Path -LiteralPath $iscc)) {
throw "ISCC.exe was not found after installing Inno Setup."
}
- name: Build and package
shell: pwsh
run: .\scripts\package-release.ps1 -Version "${{ steps.release_version.outputs.version }}" -Configuration Release -OutputRoot .\dist
- name: Write release notes
shell: pwsh
run: .\scripts\New-ReleaseNotes.ps1 -Version "${{ steps.release_version.outputs.version }}" -OutputDirectory .\dist
- name: Upload workflow artifact
uses: actions/upload-artifact@v4
with:
name: mySQLPunk-${{ steps.release_version.outputs.version }}-release-assets
path: |
dist/*-setup.exe
dist/release-notes.md
dist/release-title.txt
- name: Create or update GitHub Release
shell: pwsh
env:
GITHUB_TOKEN: ${{ github.token }}
REPOSITORY: ${{ github.repository }}
TAG_NAME: ${{ steps.release_version.outputs.tag_name }}
run: |
$headers = @{
Authorization = "Bearer $env:GITHUB_TOKEN"
Accept = "application/vnd.github+json"
"X-GitHub-Api-Version" = "2022-11-28"
}
$releaseName = (Get-Content -LiteralPath ".\dist\release-title.txt" -Raw -Encoding UTF8).Trim()
$releaseNotes = Get-Content -LiteralPath ".\dist\release-notes.md" -Raw -Encoding UTF8
$releaseByTagUrl = "https://api.github.com/repos/$env:REPOSITORY/releases/tags/$env:TAG_NAME"
$release = $null
try {
$release = Invoke-RestMethod -Method Get -Uri $releaseByTagUrl -Headers $headers
} catch {
$statusCode = 0
if ($_.Exception.Response -ne $null) {
$statusCode = [int]$_.Exception.Response.StatusCode
}
if ($statusCode -ne 404) {
throw
}
$body = @{
tag_name = $env:TAG_NAME
target_commitish = $env:GITHUB_SHA
name = $releaseName
body = $releaseNotes
draft = $false
prerelease = $false
} | ConvertTo-Json -Depth 4
$release = Invoke-RestMethod -Method Post -Uri "https://api.github.com/repos/$env:REPOSITORY/releases" -Headers $headers -Body $body -ContentType "application/json"
}
if ($null -ne $release -and ($release.name -ne $releaseName -or [string]$release.body -ne $releaseNotes)) {
$body = @{
name = $releaseName
body = $releaseNotes
draft = $false
prerelease = $false
} | ConvertTo-Json -Depth 4
$release = Invoke-RestMethod -Method Patch -Uri "https://api.github.com/repos/$env:REPOSITORY/releases/$($release.id)" -Headers $headers -Body $body -ContentType "application/json"
}
$uploadBaseUrl = $release.upload_url -replace '\{.*\}$', ''
$assets = @(Get-ChildItem -LiteralPath ".\dist" -Filter "*-setup.exe")
if ($assets.Count -ne 1) {
throw "Exactly one setup EXE is required, but found $($assets.Count)."
}
# A release intentionally has one downloadable file. Remove assets left by older runs.
foreach ($existingAsset in @($release.assets)) {
Invoke-RestMethod -Method Delete -Uri $existingAsset.url -Headers $headers | Out-Null
}
foreach ($asset in $assets) {
$assetName = [uri]::EscapeDataString($asset.Name)
$assetLabel = [uri]::EscapeDataString("Windows x64 單一安裝程式")
$uploadUrl = "${uploadBaseUrl}?name=$assetName&label=$assetLabel"
Invoke-RestMethod -Method Post -Uri $uploadUrl -Headers $headers -InFile $asset.FullName -ContentType "application/octet-stream" | Out-Null
}