docs(changelog): update v0.3.13 release notes #447
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: LeviLauncher build | |
| on: | |
| push: | |
| tags: | |
| - "v*" | |
| branches: | |
| - "**" | |
| pull_request: | |
| jobs: | |
| build: | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| build: | |
| [ | |
| { | |
| name: LeviLauncher, | |
| platform: windows/amd64, | |
| archs: amd64, | |
| os: windows-2022, | |
| }, | |
| ] | |
| runs-on: ${{ matrix.build.os }} | |
| steps: | |
| - uses: actions/checkout@v7 | |
| with: | |
| submodules: recursive | |
| - name: Install Inno Setup | |
| shell: pwsh | |
| run: | | |
| choco install innosetup --yes --no-progress | |
| $isccPath = $null | |
| $candidateDirs = @( | |
| "${env:ProgramFiles(x86)}\Inno Setup 7", | |
| "${env:ProgramFiles(x86)}\Inno Setup 6", | |
| "$env:ProgramFiles\Inno Setup 7", | |
| "$env:ProgramFiles\Inno Setup 6" | |
| ) | |
| foreach ($dir in $candidateDirs) { | |
| $candidate = Join-Path $dir "ISCC.exe" | |
| if (Test-Path $candidate) { | |
| $dir | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append | |
| $isccPath = $candidate | |
| break | |
| } | |
| } | |
| if (-not $isccPath) { | |
| $command = Get-Command iscc.exe -ErrorAction SilentlyContinue | |
| if ($command) { | |
| $isccPath = $command.Source | |
| } | |
| } | |
| if (-not $isccPath) { | |
| throw "iscc.exe was not found after installing Inno Setup." | |
| } | |
| Write-Host "Using Inno Setup compiler: $isccPath" | |
| $innoDir = Split-Path -Path $isccPath -Parent | |
| $langDir = Join-Path $innoDir "Languages" | |
| $chineseSimplifiedPath = Join-Path $langDir "ChineseSimplified.isl" | |
| $chineseSimplifiedUrl = "https://raw.githubusercontent.com/jrsoftware/issrc/refs/heads/main/Files/Languages/ChineseSimplified.isl" | |
| if (-not (Test-Path $langDir)) { | |
| New-Item -ItemType Directory -Path $langDir -Force | Out-Null | |
| } | |
| if (-not (Test-Path $chineseSimplifiedPath)) { | |
| Write-Host "ChineseSimplified.isl not found. Downloading from: $chineseSimplifiedUrl" | |
| Invoke-WebRequest -Uri $chineseSimplifiedUrl -OutFile $chineseSimplifiedPath -ErrorAction Stop | |
| Write-Host "Downloaded language file to: $chineseSimplifiedPath" | |
| } else { | |
| Write-Host "Language file already exists: $chineseSimplifiedPath" | |
| } | |
| - uses: ToQuery/wails3-build-action@v3-alpha.14 | |
| with: | |
| go-archs: ${{ matrix.build.archs }} | |
| build-name: ${{ matrix.build.name }} | |
| build-platform: ${{ matrix.build.platform }} | |
| package: false | |
| - name: Verify build outputs | |
| shell: pwsh | |
| run: | | |
| Write-Host "Checking build outputs for Windows ${{ matrix.build.archs }}" | |
| cd bin | |
| $requiredFiles = @( | |
| "LeviLauncher.exe", | |
| "LeviLauncher-${{ matrix.build.archs }}-installer.exe" | |
| ) | |
| foreach ($file in $requiredFiles) { | |
| if (-not (Test-Path $file)) { | |
| throw "Required build output not found: $file" | |
| } | |
| } | |
| Write-Host "Files in bin directory:" | |
| Get-ChildItem | |
| - name: Upload standalone EXE artifact | |
| uses: actions/upload-artifact@v7.0.0 | |
| with: | |
| path: bin/LeviLauncher.exe | |
| archive: false | |
| if-no-files-found: error | |
| - name: Upload installer artifact | |
| uses: actions/upload-artifact@v7.0.0 | |
| with: | |
| path: bin/LeviLauncher-${{ matrix.build.archs }}-installer.exe | |
| archive: false | |
| if-no-files-found: error | |
| release: | |
| name: Create Release | |
| needs: build | |
| if: startsWith(github.ref, 'refs/tags/') | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v7 | |
| - name: Download all artifacts | |
| uses: actions/download-artifact@v8.0.0 | |
| with: | |
| path: ./artifacts | |
| - name: List downloaded files | |
| run: | | |
| echo "Downloaded artifacts:" | |
| find ./artifacts -type f -name "*" | sort | |
| echo "Artifacts directory structure:" | |
| ls -R ./artifacts/ | |
| - name: Determine Prerelease Status | |
| id: check_prerelease | |
| run: | | |
| # Extract beta value from build/config.yml | |
| # Look for line with "beta:", extract content between quotes | |
| BETA=$(grep 'beta:' build/config.yml | sed -n 's/.*beta:[[:space:]]*"\([^"]*\)".*/\1/p') | |
| echo "Beta value found: $BETA" | |
| if [ "$BETA" == "true" ]; then | |
| echo "is_prerelease=true" >> $GITHUB_OUTPUT | |
| echo "Detected beta: true, setting prerelease to true" | |
| else | |
| echo "is_prerelease=false" >> $GITHUB_OUTPUT | |
| echo "Detected beta: $BETA, setting prerelease to false" | |
| fi | |
| - name: Extract Release Notes From CHANGELOG | |
| id: changelog | |
| run: | | |
| set -euo pipefail | |
| TAG="${{ github.ref_name }}" | |
| CHANGELOG_FILE="CHANGELOG.md" | |
| RELEASE_NOTES_FILE="release-notes.md" | |
| if [ ! -f "$CHANGELOG_FILE" ]; then | |
| echo "CHANGELOG.md not found at repository root." | |
| exit 1 | |
| fi | |
| awk -v tag="$TAG" ' | |
| BEGIN { | |
| in_section = 0 | |
| found = 0 | |
| } | |
| { | |
| if ($0 ~ "^## \\[" tag "\\]" || $0 ~ "^## " tag "([[:space:]]|$)") { | |
| in_section = 1 | |
| found = 1 | |
| } else if (in_section && $0 ~ "^## ") { | |
| exit | |
| } | |
| if (in_section) { | |
| } | |
| } | |
| END { | |
| if (!found) { | |
| exit 2 | |
| } | |
| } | |
| ' "$CHANGELOG_FILE" > "$RELEASE_NOTES_FILE" || { | |
| echo "No changelog section found for tag: $TAG" | |
| echo "Available sections:" | |
| grep '^## ' "$CHANGELOG_FILE" || true | |
| exit 1 | |
| } | |
| if ! grep -q '[^[:space:]]' "$RELEASE_NOTES_FILE"; then | |
| echo "Extracted release notes are empty for tag: $TAG" | |
| exit 1 | |
| fi | |
| echo "Release notes extracted to $RELEASE_NOTES_FILE" | |
| - name: Create Release | |
| id: create_release | |
| uses: softprops/action-gh-release@v1 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| with: | |
| tag_name: ${{ github.ref_name }} | |
| release_name: Release ${{ github.ref_name }} | |
| draft: false | |
| prerelease: ${{ steps.check_prerelease.outputs.is_prerelease }} | |
| body_path: release-notes.md | |
| - name: Upload Release Assets | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| echo "Uploading release assets..." | |
| for raw_exe_file in ./artifacts/*/LeviLauncher.exe; do | |
| if [ -f "$raw_exe_file" ]; then | |
| echo "Uploading standalone EXE: $raw_exe_file" | |
| gh release upload ${{ github.ref_name }} "$raw_exe_file" --clobber | |
| fi | |
| done | |
| for installer_file in ./artifacts/*/*installer.exe; do | |
| if [ -f "$installer_file" ]; then | |
| echo "Uploading installer: $installer_file" | |
| gh release upload ${{ github.ref_name }} "$installer_file" --clobber | |
| fi | |
| done | |
| echo "All assets uploaded successfully" | |
| - name: Notify Discord | |
| if: startsWith(github.ref, 'refs/tags/') | |
| env: | |
| DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }} | |
| INSTALLER_URL: "https://github.com/${{ github.repository }}/releases/download/${{ github.ref_name }}/LeviLauncher-amd64-installer.exe" | |
| STANDALONE_EXE_URL: "https://github.com/${{ github.repository }}/releases/download/${{ github.ref_name }}/LeviLauncher.exe" | |
| TAG_NAME: ${{ github.ref_name }} | |
| run: | | |
| EMBED_TITLE="🚀 LeviLauncher Update!" | |
| EMBED_DESC="A new version of **LeviLauncher** is ready." | |
| EMBED_COLOR=5814783 | |
| THUMB_URL="https://avatars.githubusercontent.com/u/78095377?s=200&v=4" | |
| curl -H "Content-Type: application/json" \ | |
| -d "{ | |
| \"embeds\": [{ | |
| \"title\": \"$EMBED_TITLE\", | |
| \"description\": \"$EMBED_DESC\", | |
| \"color\": $EMBED_COLOR, | |
| \"thumbnail\": { \"url\": \"$THUMB_URL\" }, | |
| \"fields\": [ | |
| { | |
| \"name\": \"📦 Version\", | |
| \"value\": \"\`$TAG_NAME\`\", | |
| \"inline\": true | |
| }, | |
| { | |
| \"name\": \"📦 Installer\", | |
| \"value\": \"[**Click here to download installer**]($INSTALLER_URL)\", | |
| \"inline\": true | |
| }, | |
| { | |
| \"name\": \"🧩 Standalone EXE\", | |
| \"value\": \"[**Click here to download EXE**]($STANDALONE_EXE_URL)\", | |
| \"inline\": true | |
| } | |
| ] | |
| }] | |
| }" \ | |
| "$DISCORD_WEBHOOK" | |
| upload-to-target-repo: | |
| name: Upload EXE to Target Repository | |
| needs: build | |
| # Temporarily disabled: no longer uploading to dreamguxiang/LeviLauncher | |
| # if: startsWith(github.ref, 'refs/tags/') | |
| if: false | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Download build artifacts | |
| uses: actions/download-artifact@v8.0.0 | |
| with: | |
| path: ./downloaded-artifacts | |
| - name: Find EXE file | |
| id: find_exe | |
| run: | | |
| set -euo pipefail | |
| echo "Looking for LeviLauncher.exe in downloaded artifacts..." | |
| EXE_FILE=$(find ./downloaded-artifacts -name "LeviLauncher.exe" -type f | head -1 || true) | |
| if [ -n "${EXE_FILE}" ]; then | |
| echo "Found EXE file: $EXE_FILE" | |
| echo "exe_path=$EXE_FILE" >> $GITHUB_OUTPUT | |
| else | |
| echo "LeviLauncher.exe still not found, searching for non-installer EXE..." | |
| OTHER_EXE=$(find ./downloaded-artifacts -name "*.exe" -type f | grep -v installer | head -1 || true) | |
| if [ -n "${OTHER_EXE}" ]; then | |
| echo "Found alternative EXE file: $OTHER_EXE" | |
| echo "exe_path=$OTHER_EXE" >> $GITHUB_OUTPUT | |
| else | |
| echo "No suitable EXE file found" | |
| exit 1 | |
| fi | |
| fi | |
| - name: Checkout target repository | |
| uses: actions/checkout@v7 | |
| with: | |
| repository: dreamguxiang/LeviLauncher | |
| token: ${{ secrets.TARGET_REPO_TOKEN }} | |
| path: target-repo | |
| - name: Setup target repository | |
| run: | | |
| cd target-repo | |
| mkdir -p windows | |
| cp ../${{ steps.find_exe.outputs.exe_path }} windows/LeviLauncher.exe | |
| git config user.name "GitHub Actions" | |
| git config user.email "actions@github.com" | |
| if git diff --quiet; then | |
| echo "No changes to commit" | |
| echo "has_changes=false" >> $GITHUB_ENV | |
| else | |
| echo "Changes detected, preparing commit" | |
| echo "has_changes=true" >> $GITHUB_ENV | |
| fi | |
| - name: Commit and push to target repository | |
| if: env.has_changes == 'true' | |
| run: | | |
| cd target-repo | |
| git add windows/LeviLauncher.exe | |
| git commit -m "Update LeviLauncher.exe from ${{ github.repository }}@${{ github.sha }}" | |
| git push origin main | |
| - name: Create tag in target repository | |
| if: env.has_changes == 'true' | |
| run: | | |
| cd target-repo | |
| TAG_NAME="${{ github.ref_name }}" | |
| git tag -a "$TAG_NAME" -m "Release $TAG_NAME" | |
| git push origin "$TAG_NAME" | |
| prime-goproxy: | |
| name: Prime GoProxy caches | |
| needs: | |
| - upload-to-target-repo | |
| # Temporarily disabled: depends on dreamguxiang/LeviLauncher upload flow | |
| # if: startsWith(github.ref, 'refs/tags/') | |
| if: false | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Prime GoProxy caches | |
| run: | | |
| set -euo pipefail | |
| TAG="${{ github.ref_name }}" | |
| echo "Priming GoProxy caches for tag: ${TAG}" | |
| URLS=( | |
| "https://goproxy.io/github.com/dreamguxiang/!levi!launcher/@v/${TAG}.zip" | |
| "https://mirrors.aliyun.com/goproxy/github.com/dreamguxiang/levilauncher/@v/${TAG}.zip" | |
| ) | |
| for url in "${URLS[@]}"; do | |
| echo "Requesting: ${url}" | |
| for i in {1..5}; do | |
| if curl -fsSL "${url}" -o /dev/null; then | |
| echo "Primed: ${url}" | |
| break | |
| else | |
| echo "Attempt ${i} failed for ${url}, retrying..." | |
| sleep $((i*2)) | |
| fi | |
| done | |
| done |