Demo CI #26
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
# Copyright (c) godot-rust; Bromeon and contributors. | |
# This Source Code Form is subject to the terms of the Mozilla Public | |
# License, v. 2.0. If a copy of the MPL was not distributed with this | |
# file, You can obtain one at https://mozilla.org/MPL/2.0/. | |
name: Demo CI | |
# | |
# Runs before merging. Rebases on master to make sure CI passes for latest integration, not only for the PR at the time of creation. | |
on: | |
# Allow manually triggering the workflow: | |
# https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#workflow_dispatch | |
workflow_dispatch: | |
# Still have merge group, to ensure checks are additionally run at the time of merge, not just last commit. | |
# This can sometimes detect issues when behavior in Godot/godot-rust changed in the meantime. Also, little traffic expected on this repo. | |
merge_group: | |
pull_request: | |
branches: | |
- master | |
types: | |
- opened | |
- synchronize | |
- reopened | |
push: | |
branches: | |
- master | |
# Periodic: if we break stuff, we notice within one day. | |
# Run at 03:47 UTC each morning | |
schedule: | |
- cron: "47 3 * * *" | |
env: | |
# Applies to all 'register-docs' features across crates. | |
CLIPPY_FEATURES: '--features godot/register-docs,godot/experimental-godot-api,godot/serde' | |
TEST_FEATURES: '' | |
RETRY: ${{ github.workspace }}/.github/other/retry.sh | |
CARGO_DENY_VERSION: "0.16.1" | |
CARGO_MACHETE_VERSION: "0.7.0" | |
defaults: | |
run: | |
shell: bash | |
# If a new commit is pushed before the old one's CI has completed (on the same branch), abort previous run | |
#concurrency: | |
# group: ${{ github.head_ref }} | |
# cancel-in-progress: true | |
jobs: | |
rustfmt: | |
runs-on: ubuntu-22.04 | |
steps: | |
- uses: actions/checkout@v4 | |
- name: "Install Rust" | |
uses: ./.github/composite/rust | |
with: | |
components: rustfmt | |
- name: "Check rustfmt" | |
run: cargo fmt --all -- --check | |
clippy: | |
runs-on: ubuntu-22.04 | |
steps: | |
- uses: actions/checkout@v4 | |
- name: "Install Rust" | |
uses: ./.github/composite/rust | |
with: | |
components: clippy | |
# Note: could use `-- --no-deps` to not lint dependencies, however it doesn't really speed up and also skips deps in workspace. | |
- name: "Check clippy" | |
run: | | |
cargo clippy --all-targets $CLIPPY_FEATURES -- \ | |
-D clippy::suspicious \ | |
-D clippy::style \ | |
-D clippy::complexity \ | |
-D clippy::perf \ | |
-D clippy::dbg_macro \ | |
-D clippy::todo \ | |
-D clippy::unimplemented \ | |
-D warnings | |
unit-test: | |
name: unit-test (${{ matrix.name }}${{ matrix.rust-special }}) | |
runs-on: ${{ matrix.os }} | |
continue-on-error: false | |
strategy: | |
fail-fast: false # cancel all jobs as soon as one fails? | |
matrix: | |
# Order this way because macOS typically has the longest duration, followed by Windows, so it benefits total workflow execution time. | |
# Additionally, the 'linux (msrv *)' special case will then be listed next to the other 'linux' jobs. | |
# Note: Windows uses '--target x86_64-pc-windows-msvc' by default as Cargo argument. | |
include: | |
# - name: macos | |
# os: macos-latest # arm64 | |
# | |
# - name: windows | |
# os: windows-latest | |
# | |
# - name: linux | |
# os: ubuntu-22.04 | |
- name: linux | |
os: ubuntu-22.04 | |
rust-toolchain: nightly | |
rust-special: -minimal-deps | |
rust-cache-key: minimal-deps | |
- name: linux | |
os: ubuntu-22.04 | |
rust-toolchain: "1.80" | |
rust-special: -msrv | |
steps: | |
- uses: actions/checkout@v4 | |
- name: "Patch Cargo.toml to use nightly extension API" | |
# Only on Linux because godot4-prebuilt/nightly branch doesn't have artifacts for other platforms. | |
if: matrix.name == 'linux' && matrix.rust-special == '' | |
run: .github/other/patch-prebuilt.sh nightly | |
- name: "Install Rust" | |
uses: ./.github/composite/rust | |
with: | |
rust: ${{ matrix.rust-toolchain || 'stable' }} | |
cache-key: ${{ matrix.rust-cache-key }} # only needed when rustc version is possibly the same | |
- name: "Install minimal dependency versions from Cargo" | |
if: matrix.rust-special == '-minimal-deps' | |
run: cargo +nightly update -Z minimal-versions | |
- name: "Compile tests" | |
run: cargo test $TEST_FEATURES --no-run ${{ matrix.rust-extra-args }} | |
- name: "Test" | |
run: cargo test $TEST_FEATURES ${{ matrix.rust-extra-args }} | |
run-examples: | |
name: run-examples (${{ matrix.name }}) | |
runs-on: ${{ matrix.os }} | |
strategy: | |
fail-fast: false # cancel all jobs as soon as one fails? | |
matrix: | |
include: | |
# macOS | |
- name: macos-x86 | |
os: macos-13 | |
artifact-name: macos-x86-nightly | |
godot-binary: godot.macos.editor.dev.x86_64 | |
- name: macos-arm | |
os: macos-latest | |
artifact-name: macos-arm-nightly | |
godot-binary: godot.macos.editor.dev.arm64 | |
# Windows | |
- name: windows | |
os: windows-latest | |
artifact-name: windows-nightly | |
godot-binary: godot.windows.editor.dev.x86_64.exe | |
# Linux | |
- name: linux | |
os: ubuntu-22.04 | |
artifact-name: linux-nightly | |
godot-binary: godot.linuxbsd.editor.dev.x86_64 | |
- name: linux-4.3 | |
os: ubuntu-22.04 | |
artifact-name: linux-4.3 | |
godot-binary: godot.linuxbsd.editor.dev.x86_64 | |
# Deliberately don't include: | |
# | |
# * Memchecks: increases CI complexity too much with the patching and everything. | |
# Such cases need to be tested in the itest suite in the main repo. | |
# | |
# * Double precision. Makes a lot of code more difficult to write (real conversions etc), missing the point of examples | |
# being approachable. Users who need it are trusted to adjust code based on compile errors. | |
# | |
# * Godot versions older than latest stable: require "least common denominator" compromises, not being able to showcase new features. | |
# Also, opening projects in newer editor versions frequently causes warnings. | |
steps: | |
- uses: actions/checkout@v4 | |
# macOS: needed for 'timeout' command in check script. | |
- name: "Install coreutils (macOS)" | |
if: contains(matrix.name, 'macos') | |
run: brew install coreutils | |
- name: "Install Godot" | |
uses: ./.github/composite/godot-install | |
with: | |
artifact-name: 'godot-${{ matrix.artifact-name }}' | |
godot-binary: '${{ matrix.godot-binary }}' | |
- name: "Install Rust" | |
uses: ./.github/composite/rust | |
# First compile, to fail early in case of compilation errors. | |
- name: "Compile Rust examples (Release mode)" | |
run: cargo build --release ${{ matrix.rust-extra-args }} | |
- name: "Run examples for short time" | |
run: | | |
# List all folders in './example' directory | |
for example in $(ls examples); do | |
./.github/other/check-example.sh "$example" | |
done | |
cargo-deny-machete: | |
runs-on: ubuntu-22.04 | |
steps: | |
- uses: actions/checkout@v4 | |
# Deny | |
# Note: manually downloading is ~30s faster than https://github.com/EmbarkStudios/cargo-deny-action | |
- name: "Install cargo-deny" | |
run: | | |
wget --no-verbose https://github.com/EmbarkStudios/cargo-deny/releases/download/$CARGO_DENY_VERSION/cargo-deny-$CARGO_DENY_VERSION-x86_64-unknown-linux-musl.tar.gz -O cargo-deny.tar.gz | |
tar -zxvf cargo-deny.tar.gz | |
mkdir -p $HOME/.cargo/bin | |
mv cargo-deny-$CARGO_DENY_VERSION-x86_64-unknown-linux-musl/cargo-deny $HOME/.cargo/bin | |
- name: "Deny non-conforming dependencies" | |
run: cargo deny check --config .github/other/deny.toml | |
# Machete | |
- name: "Install cargo-machete" | |
uses: baptiste0928/cargo-install@v3 | |
with: | |
crate: cargo-machete | |
version: ${{ env.CARGO_MACHETE_VERSION }} | |
- name: "Use machete to cut down dependencies" | |
run: cargo machete | |
license-guard: | |
runs-on: ubuntu-22.04 | |
steps: | |
- uses: actions/checkout@v4 | |
- name: "Check license headers" | |
uses: 'apache/skywalking-eyes/[email protected]' | |
with: | |
# log: debug # optional: set the log level. The default value is `info`. | |
config: .github/other/licenserc.yml | |
# token: # optional: the token that license eye uses when it needs to comment on the pull request. | |
# Set to empty ("") to disable commenting on pull request. The default value is ${{ github.token }} | |
# mode: # optional: Which mode License-Eye should be run in. Choices are `check` or `fix`. The default value is `check`. | |
mode: check | |
# --------------------------------------------------------------------------------------------------------------------------------------------- | |
# CI status report | |
# Job to notify merge queue about success/failure | |
ci-status: | |
# Check for 'merge_group' not strictly necessary, but helpful when adding add-hoc `push:` trigger to `on:` for testing branch. | |
#if: always() && github.event_name == 'merge_group' | |
if: always() | |
needs: | |
- rustfmt | |
- clippy | |
- unit-test | |
- run-examples | |
- cargo-deny-machete | |
- license-guard | |
runs-on: ubuntu-22.04 | |
steps: | |
# Deliberate choice to use bash script and not GitHub Action glob syntax, as that is not well-documented and hard to get right. | |
# For example: contains(needs.*.result, 'success') does NOT work because * is a logical OR, thus true if a single job succeeds. | |
- name: "Determine success or failure" | |
run: | | |
DEPENDENCIES='${{ toJson(needs) }}' | |
echo "Dependency jobs:" | |
all_success=true | |
for job in $(echo "$DEPENDENCIES" | jq -r 'keys[]'); do | |
status=$(echo "$DEPENDENCIES" | jq -r ".[\"$job\"].result") | |
echo "* $job -> $status" | |
if [[ "$status" != "success" ]]; then | |
all_success=false | |
fi | |
done | |
if [[ "$all_success" == "false" ]]; then | |
echo "One or more dependency jobs failed or were cancelled." | |
exit 1 | |
fi |