name: Pre-commit run-name: Run pre-commit checks on: pull_request: push: branches: - main - 'release-[0-9]+.[0-9]+.x' concurrency: group: ${{ github.workflow }}-${{ github.ref == 'refs/heads/main' && github.run_id || github.ref }} cancel-in-progress: true jobs: pre-commit: runs-on: ubuntu-latest permissions: contents: write pull-requests: write steps: - name: Checkout code uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: # For dependabot PRs, we need to checkout with a token that can push changes token: ${{ github.actor == 'dependabot[bot]' && secrets.GITHUB_TOKEN || github.token }} # Fetch full history for dependabot PRs to allow commits fetch-depth: ${{ github.actor == 'dependabot[bot]' && 0 || 1 }} - name: Set up Python uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 with: python-version: '3.12' cache: pip cache-dependency-path: | **/requirements*.txt .pre-commit-config.yaml - name: Set up Node.js uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 with: node-version: '20' cache: 'npm' cache-dependency-path: 'src/llama_stack_ui/' - name: Set up uv uses: astral-sh/setup-uv@85856786d1ce8acfbcc2f13a5f3fbd6b938f9f41 # v7.1.2 - name: Install npm dependencies run: npm ci working-directory: src/llama_stack_ui - name: Install pre-commit run: python -m pip install pre-commit - name: Cache pre-commit uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 with: path: ~/.cache/pre-commit key: pre-commit-3|${{ env.pythonLocation }}|${{ hashFiles('.pre-commit-config.yaml') }} - name: Run pre-commit id: precommit run: | set +e pre-commit run --show-diff-on-failure --color=always --all-files 2>&1 | tee /tmp/precommit.log status=${PIPESTATUS[0]} echo "status=$status" >> $GITHUB_OUTPUT exit 0 env: SKIP: no-commit-to-branch,mypy RUFF_OUTPUT_FORMAT: github - name: Check pre-commit results if: steps.precommit.outputs.status != '0' run: | echo "::error::Pre-commit hooks failed. Please run 'pre-commit run --all-files' locally and commit the fixes." echo "" echo "Failed hooks output:" cat /tmp/precommit.log exit 1 - name: Debug run: | echo "github.ref: ${{ github.ref }}" echo "github.actor: ${{ github.actor }}" - name: Commit changes for dependabot PRs if: github.actor == 'dependabot[bot]' run: | if ! git diff --exit-code || [ -n "$(git ls-files --others --exclude-standard)" ]; then git config --local user.email "github-actions[bot]@users.noreply.github.com" git config --local user.name "github-actions[bot]" # Ensure we're on the correct branch git checkout -B ${{ github.head_ref }} git add -A git commit -m "Apply pre-commit fixes" # Pull latest changes from the PR branch and rebase our commit on top git pull --rebase origin ${{ github.head_ref }} # Push to the PR branch git push origin ${{ github.head_ref }} echo "Pre-commit fixes committed and pushed" else echo "No changes to commit" fi - name: Verify no uncommitted changes if: github.actor != 'dependabot[bot]' run: | if ! git diff --exit-code; then echo "::error::There are uncommitted changes after pre-commit. Please run 'pre-commit run --all-files' locally and commit the fixes." echo "::warning::Files with changes:" git diff --name-status exit 1 fi - name: Verify if there are any new files after pre-commit if: github.actor != 'dependabot[bot]' run: | unstaged_files=$(git ls-files --others --exclude-standard) if [ -n "$unstaged_files" ]; then echo "::error::There are new untracked files after pre-commit. Please run 'pre-commit run --all-files' locally and commit the fixes." echo "::warning::New files:" echo "$unstaged_files" exit 1 fi - name: Configure client installation id: client-config uses: ./.github/actions/install-llama-stack-client - name: Sync dev + type_checking dependencies env: UV_EXTRA_INDEX_URL: ${{ steps.client-config.outputs.uv-extra-index-url }} run: | if [ -n "$UV_EXTRA_INDEX_URL" ]; then export UV_INDEX_STRATEGY="unsafe-best-match" fi uv sync --group dev --group type_checking # Install specific client version after sync if needed if [ "${{ steps.client-config.outputs.install-after-sync }}" = "true" ]; then echo "Installing llama-stack-client from: ${{ steps.client-config.outputs.install-source }}" uv pip install ${{ steps.client-config.outputs.install-source }} fi - name: Run mypy (full type_checking) env: UV_EXTRA_INDEX_URL: ${{ steps.client-config.outputs.uv-extra-index-url }} run: | if [ -n "$UV_EXTRA_INDEX_URL" ]; then export UV_INDEX_STRATEGY="unsafe-best-match" fi set +e uv run --group dev --group type_checking mypy status=$? if [ $status -ne 0 ]; then echo "::error::Full mypy failed. Reproduce locally with 'uv run pre-commit run mypy-full --hook-stage manual --all-files'." fi exit $status - name: Check if any unused recordings run: | set -e PYTHONPATH=$PWD uv run ./scripts/cleanup_recordings.py --delete changes=$(git status --short tests/integration | grep 'recordings' || true) if [ -n "$changes" ]; then echo "::error::Unused integration recordings detected. Run 'PYTHONPATH=$(pwd) uv run ./scripts/cleanup_recordings.py --delete' locally and commit the deletions." echo "$changes" exit 1 fi