docs(readme): point at v1.31.0 "Ledger" #22
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: | |
| push: | |
| tags: ["v*"] | |
| # Manual re-run against an already-tagged release — e.g. to backfill artifacts onto a release | |
| # that predates this workflow's packaging/upload steps, or to rebuild after a transient | |
| # platform-specific failure without re-tagging (which would be destructive to a published tag). | |
| workflow_dispatch: | |
| inputs: | |
| tag: | |
| description: "Existing tag to build and attach artifacts to (e.g. v0.2.0)" | |
| required: true | |
| # Invoked directly by release-auto.yml right after it creates a tag: a tag pushed by the | |
| # built-in GITHUB_TOKEN does NOT trigger `on: push: tags` (GitHub's recursion guard), so | |
| # release-auto.yml calls this workflow rather than relying on that push to fire it. | |
| workflow_call: | |
| inputs: | |
| tag: | |
| description: "Existing tag to build and attach artifacts to (e.g. v0.5.0)" | |
| required: true | |
| type: string | |
| # A tag is normally pushed once, but this guards a mistaken re-push (delete+recreate the same | |
| # tag) from queuing a redundant duplicate build behind the one already running. Manual dispatches | |
| # for different tags get independent groups (keyed on the resolved tag, not the ref) so backfilling | |
| # multiple historical releases in a row doesn't cancel each other. | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ inputs.tag || github.ref_name }} | |
| cancel-in-progress: true | |
| # `gh release upload`/`gh release create` (below) need write access to create/attach to releases. | |
| permissions: | |
| contents: write | |
| jobs: | |
| build: | |
| strategy: | |
| matrix: | |
| include: | |
| - { os: ubuntu-latest, target: x86_64-unknown-linux-gnu } | |
| - { os: macos-latest, target: aarch64-apple-darwin } | |
| - { os: windows-latest, target: x86_64-pc-windows-msvc } | |
| runs-on: ${{ matrix.os }} | |
| env: | |
| # A manual dispatch supplies the target tag explicitly (defaults are not evaluated for a | |
| # `push` trigger, where `github.ref_name` is already the pushed tag). | |
| TAG: ${{ inputs.tag || github.ref_name }} | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| with: | |
| persist-credentials: false | |
| ref: ${{ env.TAG }} | |
| - uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # stable | |
| with: | |
| targets: ${{ matrix.target }} | |
| - uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 | |
| with: | |
| key: release-${{ matrix.target }} | |
| - name: Install Linux frontend system deps | |
| if: runner.os == 'Linux' | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y libxkbcommon-dev libwayland-dev libasound2-dev \ | |
| libudev-dev libx11-dev libxcursor-dev libxrandr-dev libxi-dev | |
| - run: cargo build --release -p rustysnes-frontend --target ${{ matrix.target }} | |
| # Package the built binary + docs/license into one archive per platform, named | |
| # `rustysnes-<tag>-<target>.<tar.gz|zip>` — tar.gz on Unix (the customary format, and | |
| # preserves the executable bit), zip on Windows (no executable bit to preserve, and zip is | |
| # what Windows users expect to double-click-extract). | |
| - name: Package (Linux/macOS) | |
| if: runner.os != 'Windows' | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| stage="rustysnes-${TAG}-${{ matrix.target }}" | |
| mkdir -p "$stage" | |
| cp "target/${{ matrix.target }}/release/rustysnes" "$stage/" | |
| cp README.md LICENSE-MIT LICENSE-APACHE NOTICE LICENSES-THIRD-PARTY-FONTS.txt "$stage/" | |
| tar czf "$stage.tar.gz" "$stage" | |
| echo "ASSET=$stage.tar.gz" >> "$GITHUB_ENV" | |
| - name: Package (Windows) | |
| if: runner.os == 'Windows' | |
| shell: pwsh | |
| run: | | |
| $stage = "rustysnes-${env:TAG}-${{ matrix.target }}" | |
| New-Item -ItemType Directory -Force -Path $stage | Out-Null | |
| Copy-Item "target/${{ matrix.target }}/release/rustysnes.exe" $stage/ | |
| Copy-Item README.md, LICENSE-MIT, LICENSE-APACHE, NOTICE, LICENSES-THIRD-PARTY-FONTS.txt $stage/ | |
| Compress-Archive -Force -Path $stage -DestinationPath "$stage.zip" | |
| Add-Content -Path $env:GITHUB_ENV -Value "ASSET=$stage.zip" | |
| # A detached SHA-256 checksum alongside each archive, so a downloader can verify the | |
| # binary they fetched matches what CI actually built without trusting GitHub's transport | |
| # alone. Neither `sha256sum` (GNU coreutils — absent on macOS) nor `shasum` (Perl-based — | |
| # not guaranteed present in Windows' Git-Bash `PATH`) is available on every runner this | |
| # matrix uses, so try both rather than assuming one. | |
| - name: Checksum | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| if command -v sha256sum >/dev/null 2>&1; then | |
| sha256sum "$ASSET" > "$ASSET.sha256" | |
| else | |
| shasum -a 256 "$ASSET" > "$ASSET.sha256" | |
| fi | |
| # Attach to the GitHub release matching this tag, creating a minimal one first if it | |
| # doesn't exist yet (the release ceremony normally authors the real release notes with | |
| # `gh release create --notes-file` around the same time the tag is pushed — this is a | |
| # self-healing fallback for whichever finishes first, not the primary way releases get | |
| # their notes). `--clobber` makes a re-run (e.g. after a failed job, or a manual backfill | |
| # dispatch) idempotent. | |
| - name: Attach artifact to the GitHub release | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| REPO="${{ github.repository }}" | |
| if ! gh release view "$TAG" --repo "$REPO" >/dev/null 2>&1; then | |
| # All 3 matrix legs run concurrently and race this same check-then-create — a second | |
| # leg's `gh release create` can fail with "already exists" if a racing leg won. That | |
| # is not a real failure (the release now exists either way), so don't let it fail the | |
| # job; instead re-check existence and only error if the release is STILL missing | |
| # (a genuine creation failure, e.g. a permissions problem). | |
| gh release create "$TAG" --repo "$REPO" --title "$TAG" --generate-notes || true | |
| gh release view "$TAG" --repo "$REPO" >/dev/null 2>&1 || { | |
| echo "::error::release $TAG still missing after create attempt" >&2 | |
| exit 1 | |
| } | |
| fi | |
| gh release upload "$TAG" "$ASSET" "$ASSET.sha256" --repo "$REPO" --clobber |