Skip to content

Simplify release workflow #39

Simplify release workflow

Simplify release workflow #39

Workflow file for this run

# @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