Finish Release-v0.10 #5
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 } |