textual 1.0.0-dev

A reactive TUI framework inspired by the Python Textual library
Documentation
name: release

on:
  push:
    tags:
      - "v*"

# NOTE: textual depends on the in-repo `textual-macros` crate. To publish `textual` to
# crates.io, publish `textual-macros` first (manual one-time publish), then tag a release.
# Test suite is fully green (2500 pass, 0 fail). The compose-render regressions
# (markdown/help_panel/welcome) and the ScrollView horizontal intrinsic-width scroll were all fixed.

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
      - name: Cache cargo
        uses: actions/cache@v4
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
            target
          key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
      - name: Tests
        env:
          CARGO_INCREMENTAL: "0"
        run: cargo test

  package:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
      - name: Package (dry run)
        env:
          CARGO_INCREMENTAL: "0"
        run: cargo package -p textual

  publish:
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
    needs: [test, package]
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
      - name: Read crate version
        id: crate_version
        run: |
          set -euo pipefail
          version=$(cargo metadata --no-deps --format-version 1 | \
            python3 -c "import json,sys; pkgs=json.load(sys.stdin)['packages']; print(next(p['version'] for p in pkgs if p['name']=='textual'))")
          echo "version=$version" >> "$GITHUB_OUTPUT"
      - name: Check if version exists on crates.io
        id: version_check
        run: |
          set -euo pipefail
          version="${{ steps.crate_version.outputs.version }}"
          if curl -sfL "https://crates.io/api/v1/crates/textual/${version}"; then
            echo "exists=true" >> "$GITHUB_OUTPUT"
          else
            echo "exists=false" >> "$GITHUB_OUTPUT"
          fi
      - name: Skip publish (version exists)
        if: steps.version_check.outputs.exists == 'true'
        run: echo "crate version already published; skipping cargo publish"
      - name: Authenticate with crates.io
        id: auth
        uses: rust-lang/crates-io-auth-action@v1
        if: steps.version_check.outputs.exists != 'true'
      - name: Publish to crates.io
        env:
          CARGO_INCREMENTAL: "0"
          CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }}
        run: cargo publish -p textual --locked
        if: steps.version_check.outputs.exists != 'true'

  create-release:
    runs-on: ubuntu-latest
    permissions:
      contents: write
    needs: [test, package, publish]
    steps:
      - uses: actions/checkout@v4
      - name: Create GitHub Release
        uses: softprops/action-gh-release@v2
        with:
          generate_release_notes: true