feat(syntax): detect languages from shebangs (#360) #925
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| push: | |
| branches: [main, develop] | |
| pull_request: | |
| branches: [main, develop] | |
| workflow_dispatch: | |
| inputs: | |
| validation_scope: | |
| description: Paid test coverage to run | |
| required: true | |
| default: full | |
| type: choice | |
| options: | |
| - full | |
| - smoke | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: true | |
| permissions: | |
| contents: read | |
| env: | |
| CARGO_TERM_COLOR: always | |
| CARGO_PROFILE_DEV_DEBUG: line-tables-only | |
| CARGO_PROFILE_TEST_DEBUG: line-tables-only | |
| RUST_BACKTRACE: 1 | |
| jobs: | |
| plan: | |
| name: Plan validation | |
| runs-on: ubuntu-latest | |
| outputs: | |
| matrix: ${{ steps.plan.outputs.matrix }} | |
| mode: ${{ steps.plan.outputs.mode }} | |
| steps: | |
| - name: Checkout repository history | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Collect pull request paths | |
| if: github.event_name == 'pull_request' | |
| env: | |
| BASE_SHA: ${{ github.event.pull_request.base.sha }} | |
| HEAD_SHA: ${{ github.event.pull_request.head.sha }} | |
| run: git diff --name-only --diff-filter=ACMR "$BASE_SHA" "$HEAD_SHA" > "$RUNNER_TEMP/changed-paths.txt" | |
| - name: Select paid test coverage | |
| id: plan | |
| env: | |
| MANUAL_SCOPE: ${{ inputs.validation_scope || 'full' }} | |
| run: >- | |
| python3 scripts/ci_matrix.py | |
| --event "$GITHUB_EVENT_NAME" | |
| --changed-paths "$RUNNER_TEMP/changed-paths.txt" | |
| --manual-scope "$MANUAL_SCOPE" | |
| workflow-lint: | |
| name: Workflow lint | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Validate GitHub Actions workflows | |
| uses: raven-actions/actionlint@3d39aea434753780c3b3d4a1a31c854b4dbf49d7 # v2.2.0 | |
| with: | |
| version: 1.7.12 | |
| - name: Verify README release version | |
| run: python3 scripts/readme_release.py --check | |
| - name: Validate main branch ruleset recipe | |
| run: python3 -m json.tool .github/rulesets/main.json > /dev/null | |
| - name: Validate reviewed release campaign | |
| run: python3 scripts/release_campaign.py validate | |
| - name: Test release campaign and Discord announcements | |
| run: python3 -m unittest tests.test_release_campaign tests.test_discord_release tests.test_social_release | |
| - name: Test validation helpers | |
| run: python3 -m unittest tests.test_ci_policy tests.test_doctest_packages tests.test_test_performance | |
| test: | |
| name: Test Suite (${{ matrix.name }}, stable) | |
| needs: plan | |
| if: needs.plan.outputs.mode != 'docs' | |
| runs-on: >- | |
| ${{ | |
| ( | |
| github.event_name != 'pull_request' || | |
| github.event.pull_request.head.repo.full_name == github.repository | |
| ) && matrix.warp || matrix.standard | |
| }} | |
| timeout-minutes: 30 | |
| strategy: | |
| fail-fast: false | |
| matrix: ${{ fromJSON(needs.plan.outputs.matrix) }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@master | |
| with: | |
| toolchain: stable | |
| - name: Install ripgrep | |
| uses: ./.github/actions/install-ripgrep | |
| - name: Cache Rust build artifacts | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| shared-key: validation-${{ runner.os }} | |
| - name: Run tests | |
| run: cargo test --all-targets --all-features --verbose | |
| - name: Test platform keyboard decoder | |
| run: cargo test --locked --manifest-path vendor/crossterm/Cargo.toml --lib red_ | |
| - name: Test terminal keyboard protocol | |
| if: runner.os != 'Windows' | |
| run: | | |
| cargo build --locked --bin red | |
| python3 scripts/test_keyboard_protocol.py | |
| clippy: | |
| name: Clippy | |
| needs: plan | |
| if: github.event_name != 'push' && needs.plan.outputs.mode != 'docs' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| components: clippy | |
| - name: Cache Rust build artifacts | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| shared-key: validation-${{ runner.os }} | |
| - name: Deny every Clippy warning | |
| run: cargo clippy --all-targets --all-features -- -D warnings | |
| fmt: | |
| name: Rustfmt | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| components: rustfmt | |
| - name: Check formatting | |
| run: cargo fmt --all -- --check | |
| self-check: | |
| name: Bundled Runtime Self-Check | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Cache Rust build artifacts | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| shared-key: validation-${{ runner.os }} | |
| - name: Initialize bundled runtime | |
| run: cargo run --locked -- --self-check | |
| changelog: | |
| name: Changelog | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Validate git-cliff configuration | |
| uses: orhun/git-cliff-action@f50e11560dce63f7c33227798f90b924471a88b5 | |
| with: | |
| version: v2.13.1 | |
| config: cliff.toml | |
| args: --unreleased | |
| env: | |
| OUTPUT: changelog-preview.md | |
| - name: Validate GitHub release notes configuration | |
| uses: orhun/git-cliff-action@f50e11560dce63f7c33227798f90b924471a88b5 | |
| with: | |
| version: v2.13.1 | |
| config: cliff.release.toml | |
| args: --unreleased | |
| env: | |
| OUTPUT: release-notes-preview.md | |
| - name: Read release PR version | |
| if: startsWith(github.head_ref, 'release/v') | |
| id: release | |
| shell: bash | |
| env: | |
| HEAD_REF: ${{ github.head_ref }} | |
| run: echo "version=${HEAD_REF#release/v}" >> "$GITHUB_OUTPUT" | |
| - name: Validate release PR campaign version | |
| if: startsWith(github.head_ref, 'release/v') | |
| env: | |
| VERSION: ${{ steps.release.outputs.version }} | |
| run: python3 scripts/release_campaign.py validate --version "$VERSION" | |
| - name: Regenerate release PR changelog | |
| if: startsWith(github.head_ref, 'release/v') | |
| uses: orhun/git-cliff-action@f50e11560dce63f7c33227798f90b924471a88b5 | |
| with: | |
| version: v2.13.1 | |
| config: cliff.toml | |
| args: --unreleased --tag v${{ steps.release.outputs.version }} --strip all | |
| env: | |
| OUTPUT: generated-release-changes.md | |
| - name: Verify release PR changelog | |
| if: startsWith(github.head_ref, 'release/v') | |
| shell: bash | |
| env: | |
| VERSION: ${{ steps.release.outputs.version }} | |
| run: | | |
| set -euo pipefail | |
| awk -v heading="## [$VERSION]" ' | |
| index($0, heading) == 1 { found = 1 } | |
| found && /^## \[/ && index($0, heading) != 1 { exit } | |
| found { print } | |
| ' CHANGELOG.md > committed-release-changes.md | |
| test -s committed-release-changes.md | |
| normalize_markdown() { | |
| awk ' | |
| NF { | |
| if (pending_blank && wrote) print "" | |
| wrote = 1 | |
| pending_blank = 0 | |
| next | |
| } | |
| wrote { pending_blank = 1 } | |
| ' "$1" | |
| } | |
| normalize_markdown committed-release-changes.md > normalized-committed-release-changes.md | |
| normalize_markdown generated-release-changes.md > normalized-generated-release-changes.md | |
| diff -u normalized-committed-release-changes.md normalized-generated-release-changes.md | |
| build: | |
| name: Build | |
| if: github.event_name != 'pull_request' | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, macos-latest, windows-latest] | |
| include: | |
| - os: ubuntu-latest | |
| target: x86_64-unknown-linux-gnu | |
| - os: macos-latest | |
| target: x86_64-apple-darwin | |
| - os: windows-latest | |
| target: x86_64-pc-windows-msvc | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: ${{ matrix.target }} | |
| - name: Cache Rust release build artifacts | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| shared-key: release-${{ matrix.target }} | |
| - name: Build release binary | |
| run: cargo build --release --target ${{ matrix.target }} | |
| - name: Upload artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: red-${{ matrix.target }} | |
| path: | | |
| target/${{ matrix.target }}/release/red | |
| target/${{ matrix.target }}/release/red.exe | |
| docs: | |
| name: Documentation | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Cache Rust build artifacts | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| shared-key: validation-${{ runner.os }} | |
| - name: Build documentation and deny rustdoc warnings | |
| env: | |
| RUSTDOCFLAGS: -D warnings | |
| run: cargo doc --workspace --no-deps --all-features --document-private-items | |
| - name: Run documentation tests | |
| run: python3 scripts/doctest_packages.py --no-default-features | |
| - name: Check documentation links | |
| run: | | |
| python3 scripts/check_markdown_links.py --self-test | |
| python3 scripts/check_markdown_links.py | |
| gate: | |
| name: CI Gate | |
| if: always() | |
| needs: | |
| - plan | |
| - workflow-lint | |
| - test | |
| - clippy | |
| - fmt | |
| - self-check | |
| - changelog | |
| - build | |
| - docs | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Require the planned terminal results | |
| env: | |
| NEEDS_JSON: ${{ toJSON(needs) }} | |
| VALIDATION_MODE: ${{ needs.plan.outputs.mode }} | |
| run: >- | |
| python3 scripts/ci_gate.py | |
| --event "$GITHUB_EVENT_NAME" | |
| --mode "$VALIDATION_MODE" | |
| --needs-json "$NEEDS_JSON" |