# Release builds: push a tag `v*` (or run it by hand with a tag name) and this builds the desktop # app and the CLI for Linux, Windows and macOS plus the web app, and attaches them to a GitHub # release with SHA256SUMS (a pre-release when the tag has a suffix, such as v0.2.0-rc1). Every # download is a plain program (Windows .exe, Linux binary and AppImage, a macOS .dmg); the licences # are built into the programs (Help ▸ About ▸ Licences, `solvecraft-cli licences`). Only the web # app, being many files, is a zip. Notes: .github/release-notes.md, with {tag} replaced. A dry run: # Actions ▸ Release ▸ Run workflow with "publish" off keeps the assets as the release-assets artifact. name: Release on: push: tags: ["v*"] workflow_dispatch: inputs: tag: description: "Tag to release (must exist), e.g. v0.1.0; empty: the branch this runs on" required: false publish: description: "Create the GitHub release (off: a dry run that keeps everything as the release-assets artifact)" type: boolean default: true permissions: contents: write env: CARGO_TERM_COLOR: always TAG: ${{ inputs.tag || github.ref_name }} TRUNK_VERSION: v0.21.14 jobs: linux: runs-on: ubuntu-22.04 # an older glibc, so the binaries run on older distributions timeout-minutes: 60 steps: - uses: actions/checkout@v4 with: ref: ${{ env.TAG }} - uses: dtolnay/rust-toolchain@stable - uses: Swatinem/rust-cache@v2 - run: cargo build --release --locked -p solvecraft -p solvecraft-cli - name: Package run: .github/release/package-linux.sh "$TAG" - uses: actions/upload-artifact@v4 with: name: linux path: out/* windows: runs-on: windows-latest timeout-minutes: 60 steps: - uses: actions/checkout@v4 with: ref: ${{ env.TAG }} - uses: dtolnay/rust-toolchain@stable - uses: Swatinem/rust-cache@v2 - run: cargo build --release --locked -p solvecraft -p solvecraft-cli - name: Package shell: pwsh run: | New-Item -ItemType Directory -Force -Path out | Out-Null Copy-Item target/release/solvecraft.exe "out/SolveCraft-$env:TAG-windows-x86_64.exe" Copy-Item target/release/solvecraft-cli.exe "out/solvecraft-cli-$env:TAG-windows-x86_64.exe" - uses: actions/upload-artifact@v4 with: name: windows path: out/* macos: # One universal build: arm64 natively, x86_64 cross-compiled on the same runner, joined by lipo. runs-on: macos-14 timeout-minutes: 90 steps: - uses: actions/checkout@v4 with: ref: ${{ env.TAG }} - uses: dtolnay/rust-toolchain@stable with: targets: aarch64-apple-darwin, x86_64-apple-darwin - uses: Swatinem/rust-cache@v2 - run: | cargo build --release --locked -p solvecraft -p solvecraft-cli --target aarch64-apple-darwin cargo build --release --locked -p solvecraft -p solvecraft-cli --target x86_64-apple-darwin - name: Package run: .github/release/package-macos.sh "$TAG" - uses: actions/upload-artifact@v4 with: name: macos path: out/* web: runs-on: ubuntu-latest timeout-minutes: 60 steps: - uses: actions/checkout@v4 with: ref: ${{ env.TAG }} - uses: dtolnay/rust-toolchain@stable with: targets: wasm32-unknown-unknown - uses: Swatinem/rust-cache@v2 - name: Install trunk run: | mkdir -p "$HOME/.local/bin" curl -sSfL "https://github.com/trunk-rs/trunk/releases/download/${TRUNK_VERSION}/trunk-x86_64-unknown-linux-gnu.tar.gz" | tar -xz -C "$HOME/.local/bin" echo "$HOME/.local/bin" >> "$GITHUB_PATH" - name: Build (relative public URL, so it can be served from any path) working-directory: apps/solvecraft-web run: trunk build --release - name: Package run: | name="solvecraft-$TAG-web" mkdir -p out && cp -r dist/web "$name" cp LICENSE-MIT LICENSE-APACHE NOTICE THIRD-PARTY-LICENSES.txt "$name/" zip -qr "out/$name.zip" "$name" - uses: actions/upload-artifact@v4 with: name: web path: out/* release: needs: [linux, windows, macos, web] runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: ref: ${{ env.TAG }} - uses: actions/download-artifact@v4 with: path: assets merge-multiple: true - name: Checksums working-directory: assets run: sha256sum * > SHA256SUMS && cat SHA256SUMS - name: Notes run: sed "s/{tag}/$TAG/g" .github/release-notes.md > notes.md - if: ${{ github.event_name == 'push' || inputs.publish }} uses: softprops/action-gh-release@v2 with: tag_name: ${{ env.TAG }} name: SolveCraft ${{ env.TAG }} body_path: notes.md generate_release_notes: true # A tag with a suffix (v0.2.0-rc1) is a pre-release; v1.2.3 is a normal release. prerelease: ${{ contains(env.TAG, '-') }} files: assets/* # A dry run (workflow_dispatch with publish off): the assets and notes as an artifact. - if: ${{ github.event_name == 'workflow_dispatch' && !inputs.publish }} run: cp notes.md assets/release-notes.md - if: ${{ github.event_name == 'workflow_dispatch' && !inputs.publish }} uses: actions/upload-artifact@v4 with: name: release-assets path: assets/*