Skip to content

Changelog + rustfmt in release CI #65

Changelog + rustfmt in release CI

Changelog + rustfmt in release CI #65

Workflow file for this run

# 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: "Release workflow"
on:
push:
branches:
- '!**'
tags:
# To include pre-releases: 'v0.1.[0-9]+-?*'
- 'trigger-v0.[0-9]+.[0-9]+'
env:
# Crates to publish -- important, this doesn't work when there are spaces in any of the paths!
# Keep in sync with update-version.sh
GDEXT_CRATES: >
godot-bindings
godot-codegen
godot-macros
godot-ffi
godot-cell
godot-core
godot
# Used for integration test artifact, must be without patch version.
GODOT_ARTIFACT_VERSION: "4.4"
# Note: used for test and clippy, not for publish. Test features are different from other CIs.
CLIPPY_TEST_FEATURES: "--features godot/experimental-godot-api,godot/codegen-rustfmt,godot/serde"
CLIPPY_ARGS: >-
-D clippy::suspicious
-D clippy::style
-D clippy::complexity
-D clippy::perf
-D clippy::dbg_macro
-D clippy::todo
-D clippy::unimplemented
-D warnings
defaults:
run:
shell: bash
jobs:
validation:
runs-on: ubuntu-latest
outputs:
PUBLISHED_CRATE_VERSION: ${{ steps.parse-crate-version.outputs.PUBLISHED_CRATE_VERSION }}
steps:
- uses: actions/checkout@v4
# - name: "Parse crate version from Cargo.toml"
# id: parse-crate-version
# run: |
# crateVer=$(grep -Po '^version = "\K[^"]*' godot/Cargo.toml)
# if [[ -z "$crateVer" ]]; then
# echo "::error::Failed to parse crate version from godot/Cargo.toml."
# exit 1
# fi
#
# # Check if tag exists.
# git fetch --tags
# if git tag -l | grep -q "^v$crateVer$" ; then
# echo "::error::Tag 'v$crateVer' already exists."
# exit 2
# fi
#
# echo "PUBLISHED_CRATE_VERSION=$crateVer" >> $GITHUB_OUTPUT
# echo "Validated version: $crateVer"
- name: "Parse crate version from tag"
id: parse-crate-version
run: |
crateVer=$(echo "$GITHUB_REF" | sed -n "s#refs/tags/trigger-v\(.*\)#\1#p")
if [[ -z "$crateVer" ]]; then
printf "\n::error::Failed to parse GitHub ref '$GITHUB_REF'.\n"
exit 2
fi
echo "PUBLISHED_CRATE_VERSION=$crateVer" >> $GITHUB_OUTPUT
echo "Validated version: $crateVer"
- name: "Verify that Cargo.toml versions match ${{ steps.parse-crate-version.outputs.PUBLISHED_CRATE_VERSION }}"
run: |
echo "Checking crate versions..."
publishedVersion="${{ steps.parse-crate-version.outputs.PUBLISHED_CRATE_VERSION }}"
# Check if each Cargo.toml has that version
IFS=' ' read -r -a publishedCrates <<< "$GDEXT_CRATES"
for crate in "${publishedCrates[@]}"; do
readVersion=$(grep -Po '^version = "\K[^"]*' "$crate/Cargo.toml")
printf "* $crate -> $readVersion"
if [[ "$readVersion" != "$publishedVersion" ]]; then
printf " ERROR\n"
versionMismatch="1"
else
printf "\n"
fi
done
if [[ -n "$versionMismatch" ]]; then
printf "\n::error::At least one crate has a version mismatching the git tag.\n"
exit 2
else
printf "\nAll versions OK.\n"
fi
rustfmt:
runs-on: ubuntu-latest
needs: validation
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.ref }}
- name: "Install Rustfmt (uncached, nightly)"
run: rustup update nightly && rustup default nightly && rustup component add rustfmt
- name: "Check rustfmt"
run: cargo fmt --all -- --check
- name: "Run custom repo checks"
run: |
cargo run -p repo-tweak
git diff --quiet --exit-code || {
echo "::error::Godot versions out of sync; update with `cargo run -p repo-tweak`."
echo "Differences:"
echo "----------------------------------------------------"
git diff
echo "----------------------------------------------------"
exit 1
}
clippy:
runs-on: ubuntu-latest
needs: validation
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.ref }}
- name: "Install Rust (uncached)"
run: rustup update stable
- name: "Check clippy"
run: |
cargo clippy --all-targets $CLIPPY_TEST_FEATURES -- $CLIPPY_ARGS
docs-and-commit:
runs-on: ubuntu-latest
needs:
- validation
- rustfmt
- clippy
env:
PUBLISHED_CRATE_VERSION: ${{ needs.validation.outputs.PUBLISHED_CRATE_VERSION }}
steps:
- uses: actions/checkout@v4
with:
ref: 'trigger-v${{ needs.validation.outputs.PUBLISHED_CRATE_VERSION }}'
- name: "Install Rust (uncached)"
run: rustup update stable
# - name: "Tag base commit"
# run: git tag "v$PUBLISHED_CRATE_VERSION"
# - name: "Commit raw changes"
# # Note: first block was for an alternative approach, where a separate `releases` branch tracks deployments.
# # Such a branch would however be disjoint and require quite a bit of extra space in the repo.
# run: |
# # Backup current repo, so we can check out.
# mkdir -p /tmp/repo
# rsync -av --exclude .git --exclude target ./ /tmp/repo/
# git fetch origin releases && git switch releases || git switch --orphan releases
# find . -mindepth 1 -maxdepth 1 ! -name '.git' -exec rm -rf {} +
# # Restore.
# rsync -av --ignore-existing /tmp/repo/ .
#
# git add .
# git commit -m "Repo state for v${{ env.PUBLISHED_CRATE_VERSION }}"
- name: "Apply #[doc(cfg(...))]"
# Skip --rustfmt, as it causes weird reformatting of quote! {} statements.
# #[doc(cfg(...))] on the same line is the lesser evil.
run: .github/other/apply-doc-cfg.sh --install-sd
- name: "Commit post-processed docs"
run: |
git config user.name "Godot-Rust Automation"
git config user.email "GodotRust@users.noreply.github.com"
git switch -c tmp
git commit -am "v${{ env.PUBLISHED_CRATE_VERSION }} (with doc attributes)"
- name: "Tag post-processed library, commit + push, remove trigger tag"
run: |
docTag="v$PUBLISHED_CRATE_VERSION"
git tag "$docTag"
git push origin "$docTag"
git push origin --delete "trigger-v$PUBLISHED_CRATE_VERSION"
# Keep all in sync with minimal-ci and full-ci.
unit-test:
runs-on: ubuntu-latest
needs:
- validation # for outputs
- docs-and-commit
steps:
- uses: actions/checkout@v4
with:
ref: 'v${{ needs.validation.outputs.PUBLISHED_CRATE_VERSION }}'
- name: "Install Rust (uncached)"
run: rustup update stable
- name: "Compile and run test"
run: cargo test $CLIPPY_TEST_FEATURES
godot-itest:
name: godot-itest
runs-on: ubuntu-latest
needs:
- validation # for outputs
- docs-and-commit
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
with:
ref: 'v${{ needs.validation.outputs.PUBLISHED_CRATE_VERSION }}'
- name: "Run Godot integration test"
uses: ./.github/composite/godot-itest
with:
artifact-name: godot-linux-${{ env.GODOT_ARTIFACT_VERSION }}
godot-binary: godot.linuxbsd.editor.dev.x86_64
rust-extra-args: --features itest/codegen-full
rust-toolchain: stable
publish:
runs-on: ubuntu-latest
if: ${{ github.event.inputs.skip-release != 'y' }}
environment: 'Crates.io'
needs:
- validation # for outputs
- unit-test
- godot-itest
steps:
# Note: we cannot dry-run the publishing, since crates depend on each other, and dry-run will fail if they aren't yet on crates.io.
# Sleep to leave crates.io and docs.rs some time to index the dependencies, before releasing dependents.
- uses: actions/checkout@v4
with:
ref: 'v${{ needs.validation.outputs.PUBLISHED_CRATE_VERSION }}'
- name: "Install Rust (uncached)"
run: rustup update stable
- name: "Execute crates.io publishing"
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CRATES_IO_TOKEN }}
run: |
IFS=' ' read -r -a publishedCrates <<< "$GDEXT_CRATES"
for crate in "${publishedCrates[@]}"; do
echo "Publish $crate..."
(cd "$crate" && cargo publish -v) || {
printf "\n::error::Failed to publish $crate\n"
exit 2
}
echo "Wait..."
sleep 5s
done