mirror of
https://github.com/nyakang/nyaterm.git
synced 2026-11-06 16:07:55 +00:00
- Introduced an `orchestrate` job to determine which CI jobs to run based on changed paths in pull requests. - Updated Rust workflow to conditionally execute jobs like linting, testing, and plugin SDK based on the selection logic. - Added a new script `select_rust_jobs.py` to handle job selection logic without requiring a Rust installation. - Enhanced documentation to explain the new CI execution model and its implications for contributors.
310 lines
9.7 KiB
YAML
310 lines
9.7 KiB
YAML
name: Rust
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
merge_group:
|
|
types: [checks_requested]
|
|
push:
|
|
branches: [main, migration/gpui]
|
|
pull_request:
|
|
branches: [main, migration/gpui]
|
|
types: [opened, synchronize, reopened, labeled]
|
|
|
|
# No paths filter on purpose. A workflow filtered out by `paths` never runs, so its
|
|
# gate job never reports either, which leaves a pull request waiting forever on a
|
|
# required status check that will never arrive. Select jobs inside the workflow
|
|
# instead, so Rust gate still reports on documentation-only changes.
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
concurrency:
|
|
group: ${{ github.workflow }}-${{ github.ref }}
|
|
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
|
|
|
env:
|
|
CARGO_TERM_COLOR: always
|
|
CARGO_INCREMENTAL: '0'
|
|
RUST_BACKTRACE: '1'
|
|
|
|
jobs:
|
|
orchestrate:
|
|
name: Select CI jobs
|
|
runs-on: ubuntu-24.04
|
|
timeout-minutes: 10
|
|
outputs:
|
|
run_rust: ${{ steps.select.outputs.run_rust }}
|
|
run_tmux: ${{ steps.select.outputs.run_tmux }}
|
|
run_plugin_sdk: ${{ steps.select.outputs.run_plugin_sdk }}
|
|
run_python: ${{ steps.select.outputs.run_python }}
|
|
run_workflows: ${{ steps.select.outputs.run_workflows }}
|
|
steps:
|
|
- name: Checkout tested revision and comparison history
|
|
uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 0
|
|
persist-credentials: false
|
|
|
|
- name: Install Python
|
|
uses: actions/setup-python@v5
|
|
with:
|
|
python-version: '3.12'
|
|
|
|
- name: Test selection rules and workflow gates
|
|
run: python -m unittest scripts.tests.test_select_rust_jobs -v
|
|
|
|
- name: Select jobs for this event
|
|
id: select
|
|
run: python scripts/ci/select_rust_jobs.py
|
|
|
|
lint:
|
|
name: Lint
|
|
needs: [orchestrate]
|
|
if: needs.orchestrate.outputs.run_rust == 'true'
|
|
runs-on: ubuntu-24.04
|
|
timeout-minutes: 30
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v4
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- name: Set up Rust
|
|
uses: ./.github/actions/setup-rust
|
|
with:
|
|
components: rustfmt, clippy
|
|
cache-key: lint
|
|
|
|
- name: Install Linux system dependencies
|
|
uses: ./.github/actions/install-linux-deps
|
|
|
|
- name: Check formatting
|
|
run: cargo fmt --all -- --check
|
|
|
|
- name: Check architecture boundaries
|
|
run: python scripts/ci/check_architecture.py
|
|
|
|
- name: Run clippy
|
|
run: cargo clippy --workspace --all-targets --locked -- -D warnings
|
|
|
|
test:
|
|
name: Test (${{ matrix.label }})
|
|
needs: [orchestrate]
|
|
if: needs.orchestrate.outputs.run_rust == 'true'
|
|
runs-on: ${{ matrix.os }}
|
|
timeout-minutes: 60
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- label: linux-x64
|
|
os: ubuntu-24.04
|
|
- label: macos-arm64
|
|
os: macos-15
|
|
- label: windows-x64
|
|
os: windows-2025
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v4
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- name: Set up Rust
|
|
uses: ./.github/actions/setup-rust
|
|
with:
|
|
cache-key: test-${{ matrix.label }}
|
|
|
|
- name: Install Linux system dependencies
|
|
if: runner.os == 'Linux'
|
|
uses: ./.github/actions/install-linux-deps
|
|
with:
|
|
extra_packages: zsh fish
|
|
|
|
# Keep lifecycle regressions independent of unrelated workspace failures.
|
|
- name: Test Windows local shell lifecycle
|
|
if: runner.os == 'Windows'
|
|
shell: pwsh
|
|
run: |
|
|
$gitRoot = Split-Path (Split-Path (Get-Command git.exe).Source)
|
|
$env:NYATERM_TEST_POSIX_SHELL = Join-Path $gitRoot 'bin/bash.exe'
|
|
if (!(Test-Path -LiteralPath $env:NYATERM_TEST_POSIX_SHELL)) {
|
|
throw 'Git Bash is required for the ConPTY lifecycle regressions'
|
|
}
|
|
cargo test -p nyaterm-transport --lib local_shell_integration::lifecycle_tests --locked -- --ignored --test-threads=1
|
|
|
|
# Cold PowerShell startup must not compete with thousands of parallel UI
|
|
# and worker tests. Keep real ConPTY execution covered in its own step.
|
|
- name: Test Windows shared terminal execution
|
|
if: runner.os == 'Windows'
|
|
run: >-
|
|
cargo test -p nyaterm-desktop --lib
|
|
shared_entry_routes_native_codex_claude_and_external_calls_on_a_hidden_terminal
|
|
--locked -- --ignored --test-threads=1
|
|
|
|
# --no-fail-fast so one crate's failure stops masking every crate after it.
|
|
- name: Test workspace
|
|
run: cargo test --workspace --locked --no-fail-fast
|
|
|
|
- name: Install Python for Windows resource tests
|
|
if: runner.os == 'Windows'
|
|
uses: actions/setup-python@v5
|
|
with:
|
|
python-version: '3.12'
|
|
|
|
- name: Test Windows executable resources
|
|
if: runner.os == 'Windows'
|
|
run: python -m unittest scripts.tests.test_windows_resources -v
|
|
|
|
tmux-compatibility:
|
|
name: tmux (${{ matrix.tmux }}, ${{ matrix.os }})
|
|
needs: [orchestrate]
|
|
if: needs.orchestrate.outputs.run_tmux == 'true'
|
|
runs-on: ${{ matrix.os }}
|
|
timeout-minutes: 30
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- os: ubuntu-24.04
|
|
tmux: 3.2a
|
|
- os: ubuntu-24.04
|
|
tmux: '3.4'
|
|
- os: ubuntu-24.04
|
|
tmux: '3.8'
|
|
- os: macos-15
|
|
tmux: system
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
persist-credentials: false
|
|
- uses: ./.github/actions/setup-rust
|
|
with:
|
|
cache-key: tmux-${{ runner.os }}
|
|
- name: Install Linux system dependencies
|
|
if: runner.os == 'Linux'
|
|
uses: ./.github/actions/install-linux-deps
|
|
with:
|
|
extra_packages: libevent-dev libncurses-dev
|
|
- name: Build pinned tmux release
|
|
if: runner.os == 'Linux'
|
|
shell: bash
|
|
env:
|
|
TMUX_VERSION: ${{ matrix.tmux }}
|
|
run: |
|
|
archive="$RUNNER_TEMP/tmux-$TMUX_VERSION.tar.gz"
|
|
curl --fail --location --retry 3 \
|
|
"https://github.com/tmux/tmux/releases/download/$TMUX_VERSION/tmux-$TMUX_VERSION.tar.gz" \
|
|
--output "$archive"
|
|
tar -xzf "$archive" -C "$RUNNER_TEMP"
|
|
cd "$RUNNER_TEMP/tmux-$TMUX_VERSION"
|
|
./configure --prefix="$RUNNER_TEMP/tmux-install"
|
|
make -j2
|
|
make install
|
|
echo "NYATERM_TEST_TMUX=$RUNNER_TEMP/tmux-install/bin/tmux" >> "$GITHUB_ENV"
|
|
- name: Locate macOS tmux
|
|
if: runner.os == 'macOS'
|
|
shell: bash
|
|
run: |
|
|
command -v tmux || brew install tmux
|
|
echo "NYATERM_TEST_TMUX=$(command -v tmux)" >> "$GITHUB_ENV"
|
|
- name: Test real Control Mode over SSH
|
|
shell: bash
|
|
run: |
|
|
"$NYATERM_TEST_TMUX" -V
|
|
cargo test -p nyaterm-transport --lib real_tmux --locked -- --ignored
|
|
|
|
plugin-sdk:
|
|
name: Plugin SDK
|
|
needs: [orchestrate]
|
|
if: needs.orchestrate.outputs.run_plugin_sdk == 'true'
|
|
runs-on: ubuntu-24.04
|
|
timeout-minutes: 30
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v4
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- name: Set up Rust
|
|
uses: ./.github/actions/setup-rust
|
|
with:
|
|
components: rustfmt
|
|
targets: wasm32-unknown-unknown
|
|
cache-key: plugin-sdk
|
|
|
|
- name: Install Linux system dependencies
|
|
uses: ./.github/actions/install-linux-deps
|
|
|
|
- name: Check guest formatting
|
|
run: cargo fmt --manifest-path examples/plugins/guests/Cargo.toml --all -- --check
|
|
|
|
- name: Build SDK guests and test regenerated components
|
|
run: python scripts/plugins/build.py --fixtures --check
|
|
|
|
- name: Verify packaged SDK
|
|
run: cargo package --locked -p nyaterm-plugin-api --allow-dirty
|
|
|
|
python:
|
|
name: Release helpers
|
|
needs: [orchestrate]
|
|
if: needs.orchestrate.outputs.run_python == 'true'
|
|
runs-on: ubuntu-24.04
|
|
timeout-minutes: 15
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v4
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- name: Install Python
|
|
uses: actions/setup-python@v5
|
|
with:
|
|
python-version: '3.12'
|
|
|
|
# Deliberately its own job: these need no Rust toolchain and no native
|
|
# libraries, so they should not queue behind a workspace build.
|
|
- name: Test packaging helpers
|
|
run: >-
|
|
python -m unittest
|
|
scripts.tests.test_check_release_assets
|
|
scripts.tests.test_package_native
|
|
scripts.tests.test_windows_msi
|
|
scripts.tests.test_verify_native_package
|
|
scripts.tests.test_generate_release_metadata
|
|
scripts.tests.test_bump_version
|
|
scripts.tests.test_release_provenance
|
|
scripts.tests.test_release_workflow
|
|
scripts.tests.test_check_architecture
|
|
|
|
workflows:
|
|
name: Workflow syntax
|
|
needs: [orchestrate]
|
|
if: needs.orchestrate.outputs.run_workflows == 'true'
|
|
runs-on: ubuntu-24.04
|
|
timeout-minutes: 10
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v4
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- name: Run actionlint
|
|
run: >-
|
|
docker run --rm
|
|
-v "${PWD}:/repo"
|
|
-w /repo
|
|
rhysd/actionlint:1.7.7
|
|
|
|
# Single always-reporting status check for branch protection. Passes when its
|
|
# dependencies succeeded or were skipped, fails when any failed or was cancelled.
|
|
gate:
|
|
name: Rust gate
|
|
runs-on: ubuntu-24.04
|
|
needs: [orchestrate, lint, test, tmux-compatibility, plugin-sdk, python, workflows]
|
|
if: always()
|
|
timeout-minutes: 5
|
|
steps:
|
|
- name: Check dependency results
|
|
if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')
|
|
run: exit 1
|