mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-31 19:16:29 +00:00
Swap all `runs-on: ubuntu-latest` to `runs-on: arc-runner-set` all jobs.
The ARM docker build job in docker.yml uses `${{ matrix.runner }}`
and is left untouched since the GKE runner pool is x86_64 only.
Runners are backed by ARC (Actions Runner Controller) on a GKE cluster
with a spot preemptible node pool that scales based on job demand.
Use the baked Electron dependencies for the desktop E2E job.
172 lines
6.7 KiB
YAML
172 lines
6.7 KiB
YAML
name: Lint (ruff + ty)
|
|
|
|
# Two things here:
|
|
# 1. Advisory diff — ruff + ty diagnostics as a diff vs the target branch.
|
|
# Writes a Markdown summary to the run page. Exit zero always.
|
|
# 2. Blocking ``ruff check .`` — enforces the explicit rules in
|
|
# ``[tool.ruff.lint.select]`` (currently PLW1514). Failure blocks merge.
|
|
# Separate job so the advisory diff still runs even when enforcement
|
|
# fails.
|
|
#
|
|
# CI-sensitive file review was previously here as a ``ci-review`` job but
|
|
# has moved to ``review-labels.yml`` so it can be rerun independently.
|
|
|
|
on:
|
|
workflow_call:
|
|
inputs:
|
|
event_name:
|
|
description: The event name from the calling orchestrator (pull_request or push).
|
|
type: string
|
|
required: true
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
concurrency:
|
|
group: lint-${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
lint-diff:
|
|
name: ruff + ty diff
|
|
if: inputs.event_name == 'pull_request'
|
|
runs-on: arc-runner-set
|
|
timeout-minutes: 10
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
with:
|
|
fetch-depth: 0 # need full history for merge-base + worktree
|
|
|
|
- name: Install uv
|
|
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # 8.2.0
|
|
with:
|
|
# Pinned: unpinned setup-uv fetches a 'latest' manifest from
|
|
# raw.githubusercontent.com every job; transient fetch failures
|
|
# fail the job (2026-07-28 incident). Keep in sync with tests.yml.
|
|
version: "0.9.28"
|
|
|
|
- name: Install ruff + ty
|
|
uses: ./.github/actions/retry
|
|
with:
|
|
command: uv tool install ruff && uv tool install ty
|
|
|
|
- name: Determine base ref
|
|
id: base
|
|
run: |
|
|
# For PRs, diff against the merge base with the target branch.
|
|
# For pushes to main, diff against the previous commit on main.
|
|
if [ "${{ inputs.event_name }}" = "pull_request" ]; then
|
|
BASE_SHA=$(git merge-base "origin/${{ github.base_ref }}" HEAD)
|
|
BASE_REF="origin/${{ github.base_ref }}"
|
|
else
|
|
BASE_SHA=$(git rev-parse HEAD~1 2>/dev/null || git rev-parse HEAD)
|
|
BASE_REF="HEAD~1"
|
|
fi
|
|
echo "sha=${BASE_SHA}" >> "$GITHUB_OUTPUT"
|
|
echo "ref=${BASE_REF}" >> "$GITHUB_OUTPUT"
|
|
echo "Base SHA: ${BASE_SHA}"
|
|
echo "Base ref: ${BASE_REF}"
|
|
|
|
- name: Run ruff + ty on HEAD
|
|
run: |
|
|
mkdir -p .lint-reports/head
|
|
ruff check --output-format json --exit-zero \
|
|
> .lint-reports/head/ruff.json || true
|
|
ty check --output-format gitlab --exit-zero \
|
|
> .lint-reports/head/ty.json || true
|
|
echo "HEAD ruff: $(wc -c < .lint-reports/head/ruff.json) bytes"
|
|
echo "HEAD ty: $(wc -c < .lint-reports/head/ty.json) bytes"
|
|
|
|
- name: Run ruff + ty on base (via git worktree)
|
|
run: |
|
|
mkdir -p .lint-reports/base
|
|
# Use a worktree so we don't clobber the main checkout. If the basex
|
|
# SHA is identical to HEAD (e.g. first commit), skip and leave the
|
|
# base reports empty — the diff script handles missing files.
|
|
HEAD_SHA=$(git rev-parse HEAD)
|
|
BASE_SHA="${{ steps.base.outputs.sha }}"
|
|
if [ "$BASE_SHA" = "$HEAD_SHA" ]; then
|
|
echo "Base SHA == HEAD SHA, skipping base scan."
|
|
echo '[]' > .lint-reports/base/ruff.json
|
|
echo '[]' > .lint-reports/base/ty.json
|
|
else
|
|
git worktree add --detach /tmp/lint-base "$BASE_SHA"
|
|
(
|
|
cd /tmp/lint-base
|
|
ruff check --output-format json --exit-zero \
|
|
> "$GITHUB_WORKSPACE/.lint-reports/base/ruff.json" || true
|
|
ty check --output-format gitlab --exit-zero \
|
|
> "$GITHUB_WORKSPACE/.lint-reports/base/ty.json" || true
|
|
)
|
|
git worktree remove --force /tmp/lint-base
|
|
fi
|
|
echo "base ruff: $(wc -c < .lint-reports/base/ruff.json) bytes"
|
|
echo "base ty: $(wc -c < .lint-reports/base/ty.json) bytes"
|
|
|
|
- name: Generate diff summary
|
|
env:
|
|
HEAD_REF: ${{ inputs.event_name == 'pull_request' && github.head_ref || github.ref_name }}
|
|
run: |
|
|
python3 scripts/lint_diff.py \
|
|
--base-ruff .lint-reports/base/ruff.json \
|
|
--head-ruff .lint-reports/head/ruff.json \
|
|
--base-ty .lint-reports/base/ty.json \
|
|
--head-ty .lint-reports/head/ty.json \
|
|
--base-ref "${{ steps.base.outputs.ref }}" \
|
|
--head-ref "$HEAD_REF" \
|
|
--output .lint-reports/summary.md
|
|
cat .lint-reports/summary.md >> "$GITHUB_STEP_SUMMARY"
|
|
|
|
ruff-blocking:
|
|
# Enforce the rules in pyproject.toml [tool.ruff.lint.select]. Currently
|
|
# PLW1514 (unspecified-encoding) — catches bare ``open()`` /
|
|
# ``read_text()`` / ``write_text()`` calls that default to locale
|
|
# encoding on Windows. Failure here blocks merge; the advisory
|
|
# ``lint-diff`` job above runs independently so reviewers still get
|
|
# the diff comment even when enforcement fails.
|
|
name: ruff enforcement (blocking)
|
|
runs-on: arc-runner-set
|
|
timeout-minutes: 5
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
|
|
- name: Install uv
|
|
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # 8.2.0
|
|
with:
|
|
# Pinned: unpinned setup-uv fetches a 'latest' manifest from
|
|
# raw.githubusercontent.com every job; transient fetch failures
|
|
# fail the job (2026-07-28 incident). Keep in sync with tests.yml.
|
|
version: "0.9.28"
|
|
|
|
- name: Install ruff
|
|
uses: ./.github/actions/retry
|
|
with:
|
|
command: uv tool install ruff
|
|
|
|
- name: ruff check .
|
|
# No --exit-zero, no || true. Exit code propagates to the job,
|
|
# which propagates to the required-check gate.
|
|
run: |
|
|
ruff check .
|
|
|
|
windows-footguns:
|
|
# Static guardrails on Windows-unsafe Python primitives — os.kill(pid, 0),
|
|
# os.killpg, os.setsid, signal.SIGKILL without getattr fallback,
|
|
# shebang scripts via subprocess, bare open() without encoding=, etc.
|
|
# See scripts/check-windows-footguns.py for the full rule list.
|
|
name: Windows footguns (blocking)
|
|
runs-on: arc-runner-set
|
|
timeout-minutes: 5
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
|
|
- name: Set up Python
|
|
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v5
|
|
with:
|
|
python-version: "3.11"
|
|
|
|
- name: Run footgun checker
|
|
run: python3 scripts/check-windows-footguns.py --all
|