Simplify release workflow #39
Workflow file for this run
This file contains 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
# @CREDIT: | |
# <https://github.com/bevyengine/bevy_github_ci_template/blob/main/.github/workflows/release.yaml> | |
# <https://github.com/TheBevyFlock/bevy_quickstart/blob/main/.github/workflows/release.yaml> | |
name: Release | |
on: | |
push: | |
tags: | |
# <https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#filter-pattern-cheat-sheet> | |
- 'v[0-9]+.[0-9]+.[0-9]+' | |
workflow_dispatch: | |
inputs: | |
version: | |
description: 'Version number in SemVer 2.0 format for pre-release versions (X.Y.Z-alpha.W)' | |
required: true | |
type: string | |
upload-to-itch: | |
description: 'Upload to itch.io' | |
required: false | |
type: boolean | |
default: false | |
env: | |
# Name of the binary that will be created. | |
BIN_NAME: game-of-life | |
# Name of the package that will be created. | |
PKG_NAME: game-of-life | |
# Bevy's asset directory; usually `assets`. | |
ASSET_DIR: assets | |
# itch.io target; usually `<itch.io username>/<game name>`. Comment out | |
# to disable upload to itch.io. | |
ITCH_TARGET: mnemotic/game-of-life | |
# Whether assets be downloaded from GitHub LFS store. | |
USE_GIT_LFS: true | |
# Whether to upload the binaries to itch.io. Set to `false` or comment | |
# out to disable | |
UPLOAD_TO_ITCH: true | |
# Whether to upload the binaries to GitHub releases. Set to `false` or | |
# comment out to disable. | |
UPLOAD_TO_GITHUB_RELEASE: true | |
jobs: | |
check-is-manually-triggered: | |
runs-on: ubuntu-latest | |
steps: | |
- name: Check whether workflow was triggered manually | |
run: | | |
echo "::notice ::Workflow triggered by event '${{ github.event_name }}'" | |
outputs: | |
is-manually-triggered: ${{ github.event_name == 'workflow_dispatch' }} | |
get-version: | |
runs-on: ubuntu-latest | |
needs: | |
- check-is-manually-triggered | |
steps: | |
- name: Get tag version | |
id: get-tag-version | |
uses: tj-actions/branch-names@v8 | |
with: | |
strip_tag_prefix: 'v' | |
- name: Get input version | |
id: get-input-version | |
run: | | |
echo "version=${{ inputs.version }}" >> "${GITHUB_OUTPUT}" | |
- name: Validate version | |
id: validate-version | |
run: | | |
if [[ ${{ needs.check-is-manually-triggered.outputs.is-manually-triggered }} == true ]]; then | |
regex='^[0-9]+\.[0-9]+\.[0-9]+-(alpha|beta|rc)\.[1-9]+$' | |
version='${{ steps.get-input-version.outputs.version }}' | |
else | |
regex='^[0-9]+\.[0-9]+\.[0-9]+$' | |
version='${{ steps.get-tag-version.outputs.tag }}' | |
fi | |
if [[ $version =~ $regex ]]; then | |
echo "version=${version}" >> "${GITHUB_OUTPUT}" | |
exit 0 | |
else | |
echo "::error ::Version number '${version}' is not valid" | |
exit 1 | |
fi | |
outputs: | |
version: ${{ steps.validate-version.outputs.version }} | |
build: | |
permissions: | |
contents: write # required to create (pre)releases and tags | |
needs: | |
- get-version | |
- check-is-manually-triggered | |
env: | |
VERSION: ${{ needs.get-version.outputs.version }} | |
strategy: | |
matrix: | |
include: | |
- platform: web | |
targets: wasm32-unknown-unknown | |
profile: release | |
binary_ext: .wasm | |
package_ext: .zip | |
runner: ubuntu-latest | |
- platform: linux | |
targets: x86_64-unknown-linux-gnu | |
profile: release-native | |
package_ext: .zip | |
runner: ubuntu-latest | |
- platform: windows | |
targets: x86_64-pc-windows-msvc | |
profile: release-native | |
binary_ext: .exe | |
package_ext: .zip | |
runner: windows-latest | |
runs-on: ${{ matrix.runner }} | |
defaults: | |
run: | |
shell: bash | |
steps: | |
- name: Set environment variables | |
run: | | |
pkg='${{ env.PKG_NAME }}_${{ env.VERSION }}_${{ matrix.platform }}' | |
echo "PKG=${pkg}" >> "${GITHUB_ENV}" | |
echo "OUT_DIR=tmp/packages/${pkg}/" >> "${GITHUB_ENV}" | |
- name: Checkout sources | |
uses: actions/checkout@v4 | |
with: | |
lfs: ${{ env.USE_GIT_LFS }} | |
- name: Install Rust toolchain | |
uses: dtolnay/rust-toolchain@nightly | |
with: | |
targets: ${{ matrix.targets }} | |
- name: Restore cache | |
uses: Swatinem/rust-cache@v2 | |
- name: Install dependencies (Linux) | |
if: ${{ matrix.platform == 'linux' }} | |
run: | | |
sudo apt-get update | |
sudo apt-get install --no-install-recommends \ | |
libasound2-dev \ | |
libudev-dev \ | |
libwayland-dev \ | |
libxkbcommon-dev | |
- name: Prepare output directories | |
run: | | |
rm -rf tmp/ | |
mkdir -p tmp/bin/ '${{ env.OUT_DIR }}' | |
- name: Install cargo-binstall (web) | |
if: ${{ matrix.platform == 'web' }} | |
uses: cargo-bins/[email protected] | |
- name: Install Trunk (web) | |
if: ${{ matrix.platform == 'web' }} | |
run: | | |
cargo binstall --no-confirm --force trunk wasm-bindgen-cli wasm-opt | |
- name: Build binaries (web) | |
if: ${{ matrix.platform == 'web' }} | |
run: | | |
trunk build --release --dist '${{ env.OUT_DIR }}' | |
- name: Build binaries (native) | |
if: ${{ matrix.platform != 'web' }} | |
run: | | |
for target in ${{ matrix.targets }}; do | |
cargo build \ | |
--profile='${{ matrix.profile }}' \ | |
--target="${target}" | |
# move binaries to tmp/bin/ directory | |
src="target/${target}/${{ matrix.profile }}/${{ env.BIN_NAME }}${{ matrix.binary_ext }}" | |
dst="tmp/bin/${target}${{ matrix.binary_ext }}" | |
mv $src $dst | |
done | |
- name: Add binaries to package (native) | |
if: ${{ matrix.platform != 'web' }} | |
run: | | |
for target in ${{ matrix.targets }}; do | |
src="tmp/bin/${target}${{ matrix.binary_ext }}" | |
dst='${{ env.OUT_DIR }}/${{ env.PKG_NAME }}${{ matrix.binary_ext }}' | |
mv $src $dst | |
done | |
- name: Add assets to package (native) | |
if: ${{ matrix.platform != 'web' }} | |
run: | | |
cp -r '${{ env.ASSET_DIR }}' '${{ env.OUT_DIR }}' || true # ignore errors | |
- name: Finalize package (native, non-Windows) | |
if: ${{ matrix.platform != 'windows' }} | |
working-directory: tmp/packages/ | |
run: | | |
zip --recurse-paths '${{ env.PKG }}${{ matrix.package_ext }}' '${{ env.PKG }}' | |
- name: Finalize package (native, Windows) | |
if: ${{ matrix.platform == 'windows' }} | |
working-directory: tmp/packages/ | |
shell: pwsh | |
run: | | |
$Params = @{ | |
Path = '${{ env.PKG }}' | |
DestinationPath = '${{ env.PKG }}${{ matrix.package_ext }}' | |
} | |
Compress-Archive @Params | |
- name: Upload package to artifacts | |
uses: actions/upload-artifact@v4 | |
with: | |
path: tmp/packages/${{ env.PKG }}${{ matrix.package_ext }} | |
name: package-${{ matrix.platform }} | |
retention-days: 1 | |
- name: Upload package to GitHub releases | |
if: ${{ env.UPLOAD_TO_GITHUB_RELEASE == 'true' && matrix.platform != 'web' }} | |
uses: svenstaro/upload-release-action@v2 | |
with: | |
repo_token: '${{ secrets.GITHUB_TOKEN }}' | |
file: tmp/packages/${{ env.PKG }}${{ matrix.package_ext }} | |
asset_name: ${{ env.PKG }}${{ matrix.package_ext }} | |
tag: v${{ env.VERSION }} | |
overwrite: true | |
prerelease: ${{ needs.check-is-manually-triggered.outputs.is-manually-triggered }} | |
get-itch-target: | |
runs-on: ubuntu-latest | |
steps: | |
- name: Get itch.io target | |
run: | | |
exit 0 | |
outputs: | |
itch-target: ${{ env.ITCH_TARGET }} | |
check-should-upload-to-itch: | |
runs-on: ubuntu-latest | |
needs: | |
- check-is-manually-triggered | |
steps: | |
- name: Check whether to upload to itch.io | |
id: check | |
run: | | |
if [[ ${{ needs.check-is-manually-triggered.outputs.is-manually-triggered }} == true ]]; then | |
echo "should-upload=${{ env.UPLOAD_TO_ITCH == 'true' && inputs.upload-to-itch }}" >> "${GITHUB_OUTPUT}" | |
else | |
echo "should-upload=${{ env.UPLOAD_TO_ITCH == 'true' }}" >> "${GITHUB_OUTPUT}" | |
fi | |
# map a step outputs to job outputs | |
outputs: | |
should-upload: ${{ steps.check.outputs.should-upload }} | |
upload-to-itch: | |
runs-on: ubuntu-latest | |
needs: | |
- build | |
- get-version | |
- get-itch-target | |
- check-should-upload-to-itch | |
env: | |
VERSION: ${{ needs.get-version.outputs.version }} | |
if: >- | |
${{ | |
needs.check-should-upload-to-itch.outputs.should-upload == 'true' && | |
needs.get-itch-target.outputs.itch-target != '' | |
}} | |
steps: | |
- name: Download all packages from artifacts | |
uses: actions/download-artifact@v4 | |
with: | |
path: tmp/ | |
pattern: package-* | |
- name: Install butler | |
run: | | |
curl -L -o butler.zip https://broth.itch.zone/butler/linux-amd64/LATEST/archive/default | |
unzip butler.zip | |
chmod +x butler | |
./butler -V | |
- name: Upload all packages to itch.io | |
env: | |
# read by butler | |
BUTLER_API_KEY: ${{ secrets.BUTLER_API_KEY }} | |
run: | | |
for pkg in $(ls tmp/); do | |
./butler push \ | |
--fix-permissions \ | |
--userversion='${{ env.VERSION }}' \ | |
tmp/"${pkg}"/* \ | |
'${{ env.ITCH_TARGET }}':"${pkg#package-}" # strip 'package-' prefix' | |
done |