rusty-bubbles 2.1.0

Cleanroom Rust port of charm.land/bubbles/v2: TUI components for Bubble Tea applications
Documentation
name: CI

# Gate for all PRs to the live branch (`dev`): merges are rejected unless
# every lint, build, docgen and test (including all integration tests)
# passes 100%, and unless the merge carries a version change (releases on
# crates.io cannot be overwritten in place, so every merge to the live
# branch must be accompanied by a new tagged version).

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/bubbles.git upstream-go
          cd upstream-go && git checkout --quiet v2.1.0
      - name: Fetch sibling rusty-bubbletea (pinned)
        uses: actions/checkout@v4
        with:
          repository: coderbants/rusty-bubbletea
          path: siblings/rusty-bubbletea
          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-bubbletea ../rusty-bubbletea
          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
      - 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-bubbletea (pinned)
        uses: actions/checkout@v4
        with:
          repository: coderbants/rusty-bubbletea
          path: siblings/rusty-bubbletea
          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-bubbletea ../rusty-bubbletea
          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