Bevy <3 Github Actions
In this post, I want to show how I did manage to automate building and publishing my game written with Bevy to GitHub Pages using GitHub Actions. Few years ago I was working on some side project game- Slavic Castles. It was written in Rust, using Quicksilver framework. Lately I wanted to return to work on it, but it seems like the framework is dead. Bevy seems like a most used Rust game framework, so I've decided to give it a shot. It worked out well and I want to share with anyone interested how they can easily add some form of CI/CD to their Bevy projects.
Bevy and WASM
Bevy engine itself is a too big topic to cover, so I will assume that the reader has a basic knowledge about it. One minor thing that I can add that not everyone knows is the fact that you can easily make bevy canvas in WebGL match browser size, in main.rs
when adding DefaultPlugin add this:
.add_plugins(DefaultPlugins.set(WindowPlugin {
primary_window: Some(Window {
fit_canvas_to_parent: true,
..default()
}),
..default()
}))
And in index.html
make sure that this style rule is present:
html,
body {
margin: 0;
height: 100%;
}
For more info about building for web there is great page on Bevy cheatbook. Just make sure to install this tool, it should be mentioned there but is not:
cargo install wasm-bindgen-cli
GitHub Actions
Assuming that game is hosted on GitHub it can be easily be builded using GitHub Actions. You will need to create first .github/actions
folders in the main directory of the repo. Inside that directory, we will create YAML file named rust.yml
. Here it is where the magic happens. Below I will explain each part of the file but I want to recommend reading the docs about it.
Beggining of the file:
name: build
on:
push:
branches:
- 'main'
- 'master'
env:
CARGO_TERM_COLOR: always
Three things - give name to workflow, specifies when it should be run(in this case on pushing to branches main
and master
) and we are setting env variable.
jobs: # here we are specifing all of the jobs
build: # name of the job
runs-on: ubuntu-latest # system, linux is the cheapest
timeout-minutes: 30
steps:
- uses: actions/checkout@v3
- uses: actions/cache@v3
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: ${{ github.ref || github.run_id }}
- uses: dtolnay/rust-toolchain@stable
- name: Install alsa and udev
run: sudo apt-get update; sudo apt-get install --no-install-recommends libasound2-dev libudev-dev
In the second part we are starting the job, restoring cache (so the next build is going to be faster) installing all the dependencies and preparing for most important part:
- name: Build
run: cargo build --release --target wasm32-unknown-unknown && wasm-bindgen --out-dir ./out/ --target web ./target/wasm32-unknown-unknown/release/bevy_wasm_ci_example.wasm
- name: Copy
run: cp -R assets out/ && cp index.html out/index.html
- name: Push
uses: s0/git-publish-subdir-action@develop
env:
SQUASH_HISTORY: true
REPO: self
BRANCH: gh-pages # The branch name where you want to push the assets
FOLDER: out # The directory where your assets are generated
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # GitHub will automatically add this - you don't need to bother getting a token
MESSAGE: "Build: ({sha}) {msg}" # The commit message
Here we building our game to WASM, copying all of the assets, index.html (remember to create one!) and pushing it to branch named gh-pages
. If you did all of that and pushed the code to remote you should have this beatiful error:
Error: Process exited with code: 128:
remote: Permission to {USERNAME}/{REPO_NAME}.git denied to github-actions[bot].
That is because we need to make sure inside repository Settings -> Actions -> General
we have selected Read and write permissions
.
Then we can go to Settings -> Pages
you can specify gh-pages
as source branch for GitHub Pages. Now the game should be available on domain {username}.github.io/{repo_name}
. For me it would be this address.
The End
I guess this is more than enough to automate building and deploying Bevy games to web. For anyone interested the example project is available here.
This work is licensed under CC BY-NC-SA 4.0.
Piotr Siuszko @Mev Lyshkin
GameDev tool engineer, C#/C++ at day, Rust at night.