name: CI
on:
pull_request:
branches: [dev]
push:
branches: [dev]
permissions:
contents: read
jobs:
version-bump:
name: Version Change Required
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Verify version matches upstream
run: scripts/verify_upstream_version.sh
gate:
name: Lint / Build / Doc / Tests
runs-on: ubuntu-latest
needs: version-bump
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
components: clippy, rustfmt
- name: Configure shared Cargo cache
run: |
# The runner image pre-sets CARGO_HOME=$HOME/.cargo; drop the
# ambient value so the shared-cache defaults apply (the resolver
# rejects it as an uncontained override otherwise).
unset CARGO_HOME
. scripts/cargo-env.sh
configure_shared_cargo_cache_environment
{
echo "CARGO_SHARED_CACHE_DIRECTORY=$CARGO_SHARED_CACHE_DIRECTORY"
echo "CARGO_HOME=$CARGO_HOME"
echo "CARGO_TARGET_DIR=$CARGO_TARGET_DIR"
echo "CARGO_BUILD_BUILD_DIR=$CARGO_BUILD_BUILD_DIR"
echo "CARGO_INSTALL_ROOT=$CARGO_INSTALL_ROOT"
} >> "$GITHUB_ENV"
- name: Test shared Cargo cache env
run: scripts/test-cargo-env.sh
- uses: actions/setup-go@v5
with:
go-version: 'stable'
- name: Fetch upstream Go source (pinned)
run: |
git clone --quiet https://github.com/charmbracelet/bubbletea.git upstream-go
cd upstream-go && git checkout --quiet v2.0.8
- name: Fetch sibling rusty-bubbles (pinned)
uses: actions/checkout@v4
with:
repository: coderbants/rusty-bubbles
path: siblings/rusty-bubbles
ref: dev
- name: Fetch sibling rusty-colorprofile (pinned)
uses: actions/checkout@v4
with:
repository: coderbants/rusty-colorprofile
path: siblings/rusty-colorprofile
ref: dev
- name: Fetch sibling rusty-lipgloss (pinned)
uses: actions/checkout@v4
with:
repository: coderbants/rusty-lipgloss
path: siblings/rusty-lipgloss
ref: dev
- name: Fetch sibling rusty-testkit (pinned)
uses: actions/checkout@v4
with:
repository: coderbants/rusty-testkit
path: siblings/rusty-testkit
ref: dev
- name: Fetch sibling rusty-ultraviolet (pinned)
uses: actions/checkout@v4
with:
repository: coderbants/rusty-ultraviolet
path: siblings/rusty-ultraviolet
ref: dev
- name: Fetch sibling rusty-x-ansi (pinned)
uses: actions/checkout@v4
with:
repository: coderbants/rusty-x-ansi
path: siblings/rusty-x-ansi
ref: dev
- name: Place sibling crates
run: |
mkdir -p ../siblings && true
mv siblings/rusty-bubbles ../rusty-bubbles
mv siblings/rusty-colorprofile ../rusty-colorprofile
mv siblings/rusty-lipgloss ../rusty-lipgloss
mv siblings/rusty-testkit ../rusty-testkit
mv siblings/rusty-ultraviolet ../rusty-ultraviolet
mv siblings/rusty-x-ansi ../rusty-x-ansi
- name: Format
run: cargo fmt --all --check
- name: Lint
run: cargo clippy --all-targets -- -D warnings
- name: Build
run: cargo build --all-targets
- name: Docgen
run: cargo doc --no-deps
- name: Test (all targets, all integration tests)
run: cargo test --all-targets -- --test-threads=1
- name: Prepare e2e fixtures
run: |
# The file_picker spec expects the macOS-style home folders that
# both the Go and Rust examples list from $HOME.
mkdir -p "$HOME/Applications" "$HOME/Documents"
- name: e2e_examples
run: ./scripts/e2e_examples.sh
- name: verify_examples
run: ./scripts/verify_examples.sh
- name: verify_mapping
run: ./scripts/verify_mapping.sh
coverage:
name: Coverage
runs-on: ubuntu-latest
needs: gate
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- name: Configure shared Cargo cache
run: |
# The runner image pre-sets CARGO_HOME=$HOME/.cargo; drop the
# ambient value so the shared-cache defaults apply.
unset CARGO_HOME
. scripts/cargo-env.sh
configure_shared_cargo_cache_environment
{
echo "CARGO_SHARED_CACHE_DIRECTORY=$CARGO_SHARED_CACHE_DIRECTORY"
echo "CARGO_HOME=$CARGO_HOME"
echo "CARGO_TARGET_DIR=$CARGO_TARGET_DIR"
echo "CARGO_BUILD_BUILD_DIR=$CARGO_BUILD_BUILD_DIR"
echo "CARGO_INSTALL_ROOT=$CARGO_INSTALL_ROOT"
} >> "$GITHUB_ENV"
- name: Fetch sibling rusty-bubbles (pinned)
uses: actions/checkout@v4
with:
repository: coderbants/rusty-bubbles
path: siblings/rusty-bubbles
ref: dev
- name: Fetch sibling rusty-colorprofile (pinned)
uses: actions/checkout@v4
with:
repository: coderbants/rusty-colorprofile
path: siblings/rusty-colorprofile
ref: dev
- name: Fetch sibling rusty-lipgloss (pinned)
uses: actions/checkout@v4
with:
repository: coderbants/rusty-lipgloss
path: siblings/rusty-lipgloss
ref: dev
- name: Fetch sibling rusty-testkit (pinned)
uses: actions/checkout@v4
with:
repository: coderbants/rusty-testkit
path: siblings/rusty-testkit
ref: dev
- name: Fetch sibling rusty-ultraviolet (pinned)
uses: actions/checkout@v4
with:
repository: coderbants/rusty-ultraviolet
path: siblings/rusty-ultraviolet
ref: dev
- name: Fetch sibling rusty-x-ansi (pinned)
uses: actions/checkout@v4
with:
repository: coderbants/rusty-x-ansi
path: siblings/rusty-x-ansi
ref: dev
- name: Place sibling crates
run: |
mkdir -p ../siblings && true
mv siblings/rusty-bubbles ../rusty-bubbles
mv siblings/rusty-colorprofile ../rusty-colorprofile
mv siblings/rusty-lipgloss ../rusty-lipgloss
mv siblings/rusty-testkit ../rusty-testkit
mv siblings/rusty-ultraviolet ../rusty-ultraviolet
mv siblings/rusty-x-ansi ../rusty-x-ansi
- name: Install cargo-tarpaulin
uses: taiki-e/install-action@cargo-tarpaulin
- name: Generate code coverage
run: |
cargo tarpaulin --all-features --out xml --output-dir target/tarpaulin -- --test-threads=1 2>&1 | tee /tmp/tarpaulin.log
- name: Write coverage badge in place
run: |
raw="$(grep -oE 'line-rate="[0-9.]+' target/tarpaulin/cobertura.xml | head -1 | grep -oE '[0-9.]+')"
pct="$(awk -v r="$raw" 'BEGIN { printf "%.1f", r * 100 }')"
if [ -z "$pct" ]; then
echo "could not parse coverage from the tarpaulin report" >&2
exit 1
fi
case "$pct" in
9[0-9]*|100*) color="brightgreen" ;;
7[5-9]*) color="yellowgreen" ;;
6[0-9]*) color="orange" ;;
*) color="red" ;;
esac
curl -sS "https://img.shields.io/badge/coverage-${pct}%25-${color}.svg" -o coverage.svg
# Commit the badge in place only when it changed (git diff ignores
# untracked files, so use status), so the push cannot re-trigger CI
# indefinitely.
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
if [ -n "$(git status --porcelain -- coverage.svg)" ]; then
git add coverage.svg
git commit -q -m "docs: update coverage badge ($pct%)"
git push -q origin dev
fi