v1.1.0 #17
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: Release | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| platform: | |
| description: 'Platform to build' | |
| required: false | |
| default: 'all' | |
| type: choice | |
| options: | |
| - all | |
| - macos | |
| - linux | |
| - windows | |
| release: | |
| types: [published] | |
| permissions: | |
| contents: write | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| env: | |
| FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true | |
| jobs: | |
| build-macos: | |
| name: Build macOS (ARM64) | |
| if: > | |
| github.event_name == 'release' || | |
| inputs.platform == 'all' || inputs.platform == 'macos' || inputs.platform == '' | |
| runs-on: [macOS, ARM64, studio] | |
| timeout-minutes: 30 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Setup Tauri build environment | |
| uses: ./.github/actions/setup-tauri-build | |
| - name: Import Apple certificate | |
| env: | |
| APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }} | |
| APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} | |
| KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} | |
| run: | | |
| KEYCHAIN_PATH="$HOME/Library/Keychains/ci_signing.keychain-db" | |
| echo $APPLE_CERTIFICATE | base64 --decode > certificate.p12 | |
| security create-keychain -p "$KEYCHAIN_PASSWORD" ci_signing.keychain | |
| security default-keychain -s ci_signing.keychain | |
| security unlock-keychain -p "$KEYCHAIN_PASSWORD" ci_signing.keychain | |
| security set-keychain-settings -t 3600 -u ci_signing.keychain | |
| security list-keychains -d user -s ci_signing.keychain login.keychain | |
| security import certificate.p12 -k ci_signing.keychain \ | |
| -P "$APPLE_CERTIFICATE_PASSWORD" -T /usr/bin/codesign | |
| security set-key-partition-list -S apple-tool:,apple:,codesign: \ | |
| -s -k "$KEYCHAIN_PASSWORD" ci_signing.keychain | |
| security find-identity -v -p codesigning ci_signing.keychain | |
| rm certificate.p12 | |
| - name: Decode App Store Connect API key | |
| env: | |
| APPLE_API_KEY_B64: ${{ secrets.APPLE_API_KEY_B64 }} | |
| run: | | |
| echo "$APPLE_API_KEY_B64" | base64 --decode > /tmp/auth_key.p8 | |
| - name: Build binary | |
| env: | |
| GITHUB_TOKEN: ${{ github.token }} | |
| LASTFM_API_KEY: ${{ secrets.LASTFM_API_KEY }} | |
| LASTFM_API_SECRET: ${{ secrets.LASTFM_API_SECRET }} | |
| run: task ci:build TARGET=aarch64-apple-darwin | |
| - name: Bundle and sign | |
| env: | |
| APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }} | |
| run: task ci:bundle TARGET=aarch64-apple-darwin | |
| - name: Upload artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: macos-arm64 | |
| path: | | |
| target/aarch64-apple-darwin/release/bundle/dmg/*.dmg | |
| target/aarch64-apple-darwin/release/bundle/macos/*.app | |
| retention-days: 7 | |
| - name: Notarize | |
| env: | |
| APPLE_API_KEY: ${{ secrets.APPLE_API_KEY }} | |
| APPLE_API_ISSUER: ${{ secrets.APPLE_API_ISSUER }} | |
| run: task ci:notarize TARGET=aarch64-apple-darwin | |
| - name: Upload release assets | |
| if: github.event_name == 'release' | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| gh release upload "${{ github.event.release.tag_name }}" \ | |
| target/aarch64-apple-darwin/release/bundle/dmg/*.dmg | |
| - name: Cleanup CI keychain | |
| if: always() | |
| run: | | |
| security delete-keychain ci_signing.keychain || true | |
| rm -f /tmp/auth_key.p8 | |
| build-linux-amd64: | |
| name: Build Linux (amd64) | |
| if: > | |
| github.event_name == 'release' || | |
| inputs.platform == 'all' || inputs.platform == 'linux' || inputs.platform == '' | |
| runs-on: blacksmith-4vcpu-ubuntu-2404 | |
| timeout-minutes: 30 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Setup Tauri build environment | |
| uses: ./.github/actions/setup-tauri-build | |
| - name: Build binary | |
| env: | |
| GITHUB_TOKEN: ${{ github.token }} | |
| LASTFM_API_KEY: ${{ secrets.LASTFM_API_KEY }} | |
| LASTFM_API_SECRET: ${{ secrets.LASTFM_API_SECRET }} | |
| run: task ci:build TARGET=x86_64-unknown-linux-gnu | |
| - name: Bundle | |
| run: task ci:bundle TARGET=x86_64-unknown-linux-gnu BUNDLES=deb | |
| - name: Upload artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: linux-amd64 | |
| path: target/x86_64-unknown-linux-gnu/release/bundle/deb/*.deb | |
| retention-days: 7 | |
| - name: Upload release assets | |
| if: github.event_name == 'release' | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| gh release upload "${{ github.event.release.tag_name }}" \ | |
| target/x86_64-unknown-linux-gnu/release/bundle/deb/*.deb | |
| build-linux-arm64: | |
| name: Build Linux (ARM64) | |
| if: > | |
| github.event_name == 'release' || | |
| inputs.platform == 'all' || inputs.platform == 'linux' || inputs.platform == '' | |
| runs-on: blacksmith-4vcpu-ubuntu-2404 | |
| timeout-minutes: 60 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install Task | |
| uses: go-task/setup-task@v1 | |
| - name: Restore Taskfile fingerprint cache | |
| uses: actions/cache@v4 | |
| with: | |
| path: .task | |
| key: task-${{ runner.os }}-${{ hashFiles('taskfiles/ci.yml') }} | |
| restore-keys: | | |
| task-${{ runner.os }}- | |
| - name: Setup Blacksmith Builder | |
| uses: useblacksmith/setup-docker-builder@v1 | |
| - name: Set up QEMU | |
| uses: docker/setup-qemu-action@v3 | |
| with: | |
| platforms: arm64 | |
| - name: Build ARM64 .deb | |
| run: | | |
| docker buildx build \ | |
| --platform linux/arm64 \ | |
| --file docker/Dockerfile.linux-arm64 \ | |
| --build-arg LASTFM_API_KEY=${{ secrets.LASTFM_API_KEY }} \ | |
| --build-arg LASTFM_API_SECRET=${{ secrets.LASTFM_API_SECRET }} \ | |
| --target artifacts \ | |
| --output type=local,dest=dist/linux-arm64 \ | |
| . | |
| - name: Upload artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: linux-arm64 | |
| path: dist/linux-arm64/*.deb | |
| retention-days: 7 | |
| - name: Upload release assets | |
| if: github.event_name == 'release' | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| gh release upload "${{ github.event.release.tag_name }}" \ | |
| dist/linux-arm64/*.deb | |
| build-windows: | |
| name: Build Windows (x64) | |
| if: > | |
| github.event_name == 'release' || | |
| inputs.platform == 'all' || inputs.platform == 'windows' || inputs.platform == '' | |
| runs-on: [self-hosted, Windows, X64] | |
| timeout-minutes: 45 | |
| steps: | |
| - name: Bootstrap Windows prerequisites | |
| shell: powershell | |
| run: | | |
| $ProgressPreference = 'SilentlyContinue' | |
| $toInstall = @() | |
| if (-not (Get-Command git -ErrorAction SilentlyContinue)) { $toInstall += 'git' } | |
| if (-not (Get-Command pwsh -ErrorAction SilentlyContinue)) { $toInstall += 'pwsh' } | |
| if ($toInstall.Count -gt 0) { | |
| choco install @toInstall -y | |
| } | |
| $gitPath = (Get-ItemProperty 'HKLM:\SOFTWARE\GitForWindows' -ErrorAction SilentlyContinue).InstallPath | |
| if ($gitPath) { | |
| echo "$gitPath\cmd" >> $env:GITHUB_PATH | |
| } | |
| - uses: actions/checkout@v4 | |
| - name: Setup Tauri build environment | |
| uses: ./.github/actions/setup-tauri-build | |
| - name: Install Windows SDK (signtool) | |
| shell: pwsh | |
| run: | | |
| choco install windows-sdk-10.1 -y | |
| $signtool = Get-ChildItem -Path "${env:ProgramFiles(x86)}\Windows Kits\10\bin" ` | |
| -Recurse -Filter signtool.exe | Where-Object { $_.FullName -match '\\x64\\' } ` | |
| | Sort-Object { [version]($_.FullName -replace '.*\\(\d+\.\d+\.\d+\.\d+)\\.*','$1') } ` | |
| | Select-Object -Last 1 -ExpandProperty FullName | |
| echo "SIGNTOOL_PATH=$signtool" >> $env:GITHUB_ENV | |
| - name: Generate self-signed code signing certificate | |
| shell: pwsh | |
| env: | |
| WINDOWS_CERT_PASSWORD: ${{ secrets.WINDOWS_CERT_PASSWORD }} | |
| run: | | |
| $password = ConvertTo-SecureString -String $env:WINDOWS_CERT_PASSWORD -Force -AsPlainText | |
| $cert = New-SelfSignedCertificate -Type CodeSigningCert -Subject 'CN=MT' ` | |
| -CertStoreLocation Cert:\CurrentUser\My -NotAfter (Get-Date).AddYears(5) | |
| Export-PfxCertificate -Cert $cert -FilePath "${{ runner.temp }}\mt-cert.pfx" -Password $password | |
| echo "CERT_PATH=${{ runner.temp }}\mt-cert.pfx" >> $env:GITHUB_ENV | |
| - name: Write signing config override | |
| shell: pwsh | |
| env: | |
| WINDOWS_CERT_PASSWORD: ${{ secrets.WINDOWS_CERT_PASSWORD }} | |
| run: | | |
| $signScript = Join-Path "${{ runner.temp }}" 'sign.cmd' | |
| @" | |
| @echo off | |
| "$env:SIGNTOOL_PATH" sign /f "$env:CERT_PATH" /p "$env:WINDOWS_CERT_PASSWORD" /t http://timestamp.digicert.com /fd SHA256 %1 | |
| "@ | Out-File -FilePath $signScript -Encoding ascii | |
| $config = @{ | |
| build = @{ beforeBuildCommand = "" } | |
| bundle = @{ windows = @{ signCommand = @{ cmd = "cmd"; args = @("/C", $signScript, "%1") } } } | |
| } | ConvertTo-Json -Depth 5 | |
| $configPath = "${{ runner.temp }}\sign-override.json" | |
| $config | Out-File -FilePath $configPath -Encoding utf8 | |
| echo "SIGN_CONFIG_PATH=$configPath" >> $env:GITHUB_ENV | |
| - name: Build binary | |
| shell: pwsh | |
| env: | |
| LASTFM_API_KEY: ${{ secrets.LASTFM_API_KEY }} | |
| LASTFM_API_SECRET: ${{ secrets.LASTFM_API_SECRET }} | |
| run: task ci:build TARGET=x86_64-pc-windows-msvc CONFIG=${{ env.SIGN_CONFIG_PATH }} | |
| - name: Bundle NSIS installer | |
| shell: pwsh | |
| run: task ci:bundle TARGET=x86_64-pc-windows-msvc BUNDLES=nsis CONFIG=${{ env.SIGN_CONFIG_PATH }} | |
| - name: Upload artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: windows-x64 | |
| path: target/x86_64-pc-windows-msvc/release/bundle/nsis/*.exe | |
| retention-days: 7 | |
| - name: Upload release assets | |
| if: github.event_name == 'release' | |
| shell: pwsh | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| gh release upload "${{ github.event.release.tag_name }}" (Get-Item target/x86_64-pc-windows-msvc/release/bundle/nsis/*.exe) | |
| - name: Cleanup certificate | |
| if: always() | |
| shell: pwsh | |
| run: | | |
| Remove-Item -Force "${{ runner.temp }}\mt-cert.pfx" -ErrorAction SilentlyContinue | |
| Remove-Item -Force "${{ runner.temp }}\sign-override.json" -ErrorAction SilentlyContinue | |
| Get-ChildItem Cert:\CurrentUser\My -CodeSigningCert | Where-Object { $_.Subject -eq 'CN=MT' } | Remove-Item | |
| update-readme: | |
| name: Update README download links | |
| needs: [build-macos, build-linux-amd64, build-linux-arm64, build-windows] | |
| if: github.event_name == 'release' | |
| runs-on: blacksmith-4vcpu-ubuntu-2404 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| ref: main | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Update download table | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| TAG: ${{ github.event.release.tag_name }} | |
| run: | | |
| python3 << 'EOF' | |
| import json, os, re, subprocess | |
| tag = os.environ['TAG'] | |
| result = subprocess.run( | |
| ['gh', 'api', f'repos/pythoninthegrass/mt/releases/tags/{tag}'], | |
| capture_output=True, text=True, check=True | |
| ) | |
| assets = json.loads(result.stdout)['assets'] | |
| PLATFORM_MAP = [ | |
| ('.dmg', 'macOS', 'Apple Silicon (ARM64)'), | |
| ('amd64', 'Linux', 'x86_64 (amd64)'), | |
| ('arm64', 'Linux', 'ARM64'), | |
| ('.exe', 'Windows', 'x64'), | |
| ] | |
| rows = [] | |
| for asset in sorted(assets, key=lambda a: a['name']): | |
| name = asset['name'] | |
| url = asset['browser_download_url'] | |
| for key, platform, arch in PLATFORM_MAP: | |
| if key in name: | |
| rows.append(f'| {platform} | {arch} | [{name}]({url}) |') | |
| break | |
| table = '\n'.join([ | |
| '| Platform | Architecture | Download |', | |
| '|----------|--------------|----------|', | |
| *rows, | |
| ]) | |
| section = f'<!-- DOWNLOADS:START -->\n{table}\n<!-- DOWNLOADS:END -->' | |
| readme = open('README.md').read() | |
| updated = re.sub( | |
| r'<!-- DOWNLOADS:START -->.*?<!-- DOWNLOADS:END -->', | |
| section, readme, flags=re.DOTALL | |
| ) | |
| open('README.md', 'w').write(updated) | |
| print(f"Updated README with {len(rows)} download link(s)") | |
| EOF | |
| - name: Commit and push | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| git add README.md | |
| git diff --staged --quiet || git commit -m "chore: update download links for ${{ github.event.release.tag_name }} [skip ci]" | |
| git push origin main |