Skip to content

Finish Release-v0.10 #5

Finish Release-v0.10

Finish Release-v0.10 #5

Workflow file for this run

name: CD — Release Build & Publish
on:
push:
tags:
- "Release-*"
jobs:
build-installer:
name: Build Installer & Publish Public Release
runs-on: windows-latest
permissions:
contents: read
env:
RELEASE_REPOSITORY: JJDing-Louis/YTDownloader-Release
steps:
# ── 1. 取出版本號(支援 Release-1.2.3 與 Release-v1.2.3)─────────────
- name: Parse version from tag
id: version
shell: pwsh
run: |
$tag = "${{ github.ref_name }}" # e.g. Release-1.2.3 or Release-v1.2.3
$ver = $tag -replace '^Release-v?', '' # e.g. 1.2.3
if ($ver -notmatch '^\d+\.\d+\.\d+([-.+][0-9A-Za-z.-]+)?$') {
Write-Error "Invalid release tag '$tag'. Use Release-1.2.3 or Release-v1.2.3."
exit 1
}
echo "VERSION=$ver" >> $env:GITHUB_OUTPUT
echo "RELEASE_TAG=$tag" >> $env:GITHUB_OUTPUT
echo "Parsed release tag: $tag"
echo "Parsed version: $ver"
# ── 2. Checkout ──────────────────────────────────────────────────────────
- name: Checkout source
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Verify public release token
shell: pwsh
env:
RELEASE_REPO_TOKEN: ${{ secrets.RELEASE_REPO_TOKEN }}
run: |
if ([string]::IsNullOrWhiteSpace($env:RELEASE_REPO_TOKEN)) {
Write-Error "Missing repository secret RELEASE_REPO_TOKEN. Create a fine-grained token that can write releases to $env:RELEASE_REPOSITORY."
exit 1
}
- name: Verify GitHub Packages token
shell: pwsh
env:
GH_PACKAGES_TOKEN: ${{ secrets.GH_PACKAGES_TOKEN }}
run: |
if ([string]::IsNullOrWhiteSpace($env:GH_PACKAGES_TOKEN)) {
Write-Error "Missing repository secret GH_PACKAGES_TOKEN. Create a classic PAT with read:packages permission for GitHub Packages restore."
exit 1
}
# ── 3. 設定 .NET 8 ───────────────────────────────────────────────────────
- name: Setup .NET 8
uses: actions/setup-dotnet@v4
with:
dotnet-version: "8.0.x"
# ── 4. Restore & Publish(self-contained, win-x64)──────────────────────
- name: Configure GitHub Packages NuGet source
shell: pwsh
env:
GH_PACKAGES_TOKEN: ${{ secrets.GH_PACKAGES_TOKEN }}
run: |
dotnet nuget add source `
--username JJDing-Louis `
--password $env:GH_PACKAGES_TOKEN `
--store-password-in-clear-text `
--name JJDing-Louis `
"https://nuget.pkg.github.com/JJDing-Louis/index.json"
- name: Restore NuGet packages
run: dotnet restore YTDownloader.sln
- name: Publish application
run: >
dotnet publish YTDownloader/YTDownloader.csproj
--configuration Release
--runtime win-x64
--self-contained true
-p:PublishSingleFile=false
-p:Version=${{ steps.version.outputs.VERSION }}
-p:AssemblyVersion=${{ steps.version.outputs.VERSION }}.0
-p:FileVersion=${{ steps.version.outputs.VERSION }}.0
-p:InformationalVersion=${{ steps.version.outputs.VERSION }}
--output publish
# ── 5. 安裝 Inno Setup 6 ─────────────────────────────────────────────────
- name: Install Inno Setup
run: choco install innosetup --yes --no-progress
shell: pwsh
# ── 6. 編譯安裝程式 ───────────────────────────────────────────────────────
- name: Build installer with Inno Setup
shell: pwsh
run: |
$iscc = "C:\Program Files (x86)\Inno Setup 6\ISCC.exe"
$ver = "${{ steps.version.outputs.VERSION }}"
& $iscc /DAppVersion=$ver installer\setup.iss
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
# ── 7. 確認安裝檔存在並列出 ──────────────────────────────────────────────
- name: Verify installer output
shell: pwsh
run: |
$files = Get-ChildItem installer\Output\*.exe
if (-not $files) { Write-Error "No installer found!"; exit 1 }
$files | ForEach-Object { Write-Host "Found: $($_.FullName)" }
# ── 8. 產生 SHA256 檔案雜湊 ───────────────────────────────────────────
- name: Generate SHA256 checksums
shell: pwsh
run: |
./scripts/New-FileHashes.ps1 `
-Path installer/Output `
-OutputFile installer/Output/SHA256SUMS.txt `
-Filter "*.exe"
Get-Content installer/Output/SHA256SUMS.txt
# ── 9. 從上一個 Release tag 產生 changelog ───────────────────────────
- name: Generate release notes
id: release_notes
shell: pwsh
run: |
$version = "${{ steps.version.outputs.VERSION }}"
$currentTag = "${{ github.ref_name }}"
$tags = git tag --list "Release-*" --sort=-v:refname
$previousTag = $tags | Where-Object { $_ -ne $currentTag } | Select-Object -First 1
if ($previousTag) {
$range = "$previousTag..$currentTag"
$compareText = "Changes since $previousTag"
$commits = git log --pretty=format:"- %s (%h)" $range
} else {
$compareText = "Initial release"
$commits = git log --pretty=format:"- %s (%h)" $currentTag
}
if (-not $commits) {
$commits = "- No commit changes detected."
}
$commitText = ($commits -join "`n")
$notes = @(
"## YTDownloader v$version",
"",
"### Installation",
"",
"1. Download ``YTDownloader_Setup_v$version.exe``.",
"2. Verify the installer with ``SHA256SUMS.txt`` if needed.",
"3. Run the installer and follow the setup wizard.",
"",
"### System Requirements",
"",
"- Windows 10 version 1809 or later",
"- x64 architecture",
"",
"### Changelog",
"",
$compareText,
"",
$commitText,
"",
"### File Hashes",
"",
"See ``SHA256SUMS.txt`` attached to this release.",
"",
"### License",
"",
"YTDownloader is distributed under the YTDownloader End User License Agreement. Users may install and use the official application for personal, learning, backup, and other non-commercial purposes. Commercial use, redistribution, product bundling, paid packaging, and commercial service use are not permitted."
)
$notes | Set-Content -Path RELEASE_NOTES.md -Encoding utf8
Get-Content RELEASE_NOTES.md
# ── 10. 建立 public release repo 的 GitHub Release 並上傳安裝程式與雜湊檔 ─
- name: Create public GitHub Release
shell: pwsh
env:
GH_TOKEN: ${{ secrets.RELEASE_REPO_TOKEN }}
run: |
$tag = "${{ steps.version.outputs.RELEASE_TAG }}"
$version = "${{ steps.version.outputs.VERSION }}"
$installer = "installer/Output/YTDownloader_Setup_v$version.exe"
$checksums = "installer/Output/SHA256SUMS.txt"
if (-not (Test-Path -LiteralPath $installer)) {
Write-Error "Installer not found: $installer"
exit 1
}
if (-not (Test-Path -LiteralPath $checksums)) {
Write-Error "Checksum file not found: $checksums"
exit 1
}
gh release view $tag --repo $env:RELEASE_REPOSITORY *> $null
if ($LASTEXITCODE -eq 0) {
Write-Host "Release $tag already exists in $env:RELEASE_REPOSITORY. Updating notes and assets."
gh release edit $tag `
--repo $env:RELEASE_REPOSITORY `
--title "YTDownloader $version" `
--notes-file RELEASE_NOTES.md `
--latest
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
gh release upload $tag `
--repo $env:RELEASE_REPOSITORY `
--clobber `
$installer `
$checksums
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
} else {
Write-Host "Creating release $tag in $env:RELEASE_REPOSITORY."
gh release create $tag `
$installer `
$checksums `
--repo $env:RELEASE_REPOSITORY `
--title "YTDownloader $version" `
--notes-file RELEASE_NOTES.md `
--latest
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
}
gh release view $tag --repo $env:RELEASE_REPOSITORY --json url,tagName,name,isDraft,isPrerelease
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }