From 06015506625a78b981ae0b34be40239fc1b389be Mon Sep 17 00:00:00 2001 From: Ahmed Allam Date: Thu, 5 Nov 2026 19:19:34 +0000 Subject: [PATCH] ci: fold CI into one workflow with job timeouts and path-gate the binary and workflow lint --- .../workflows/{ci-package.yml => binary.yml} | 63 ++++----- .github/workflows/build-release.yml | 2 + .github/workflows/ci-python.yml | 61 --------- .github/workflows/ci-tui.yml | 26 ---- .github/workflows/ci-viewer.yml | 27 ---- .github/workflows/ci.yml | 125 ++++++++++++++---- .../{ci-workflows.yml => workflows.yml} | 16 ++- .pre-commit-config.yaml | 20 --- 8 files changed, 141 insertions(+), 199 deletions(-) rename .github/workflows/{ci-package.yml => binary.yml} (53%) delete mode 100644 .github/workflows/ci-python.yml delete mode 100644 .github/workflows/ci-tui.yml delete mode 100644 .github/workflows/ci-viewer.yml rename .github/workflows/{ci-workflows.yml => workflows.yml} (81%) diff --git a/.github/workflows/ci-package.yml b/.github/workflows/binary.yml similarity index 53% rename from .github/workflows/ci-package.yml rename to .github/workflows/binary.yml index 31cddee1a..18f5b78f4 100644 --- a/.github/workflows/ci-package.yml +++ b/.github/workflows/binary.yml @@ -1,48 +1,39 @@ -name: Package +name: Binary on: - workflow_call: + pull_request: + paths: + - pyproject.toml + - uv.lock + - strix.spec + - scripts/** + - strix/interface/tui/** + - .github/actions/** + - .github/workflows/binary.yml + push: + branches: + - main + paths: + - pyproject.toml + - uv.lock + - strix.spec + - scripts/** + - strix/interface/tui/** + - .github/actions/** + - .github/workflows/binary.yml + workflow_dispatch: permissions: contents: read -jobs: - wheel: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 - with: - persist-credentials: false - - uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 - with: - go-version-file: strix/interface/tui/go.mod - cache-dependency-path: strix/interface/tui/go.sum - - uses: ./.github/actions/setup-python-env - - run: uv build --wheel - - name: Wheel ships the TUI sidecar and the viewer bundle - run: | - uv run --frozen python - <<'PY' - import glob, zipfile - (wheel,) = glob.glob("dist/*.whl") - names = zipfile.ZipFile(wheel).namelist() - assert "strix/bin/strix-tui" in names, names - assert "strix/interface/viewer/static/index.html" in names, names - assert not any(name.startswith("strix/interface/viewer/frontend/") for name in names) - assert not any(name.startswith("strix/interface/tui/cmd/") for name in names) - PY - - name: Install into a clean environment and run the CLI - env: - UV_EXCLUDE_NEWER: 5 days - run: | - uv venv --python 3.12 /tmp/strix-smoke - uv pip install --python /tmp/strix-smoke/bin/python dist/*.whl - /tmp/strix-smoke/bin/strix --version - /tmp/strix-smoke/bin/strix --help >/dev/null - - name: Vertex AI and Bedrock dependencies install with the wheel - run: /tmp/strix-smoke/bin/python -c "import google.auth.transport.requests, boto3" +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true +jobs: binary: runs-on: ubuntu-latest + timeout-minutes: 20 steps: - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 with: diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml index 504080206..337255c2c 100644 --- a/.github/workflows/build-release.yml +++ b/.github/workflows/build-release.yml @@ -32,6 +32,7 @@ jobs: wheel-platform: win_amd64 runs-on: ${{ matrix.os }} + timeout-minutes: 45 steps: - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 @@ -110,6 +111,7 @@ jobs: if: startsWith(github.ref, 'refs/tags/') needs: build runs-on: ubuntu-latest + timeout-minutes: 10 permissions: contents: write diff --git a/.github/workflows/ci-python.yml b/.github/workflows/ci-python.yml deleted file mode 100644 index d1ee05915..000000000 --- a/.github/workflows/ci-python.yml +++ /dev/null @@ -1,61 +0,0 @@ -name: Python - -on: - workflow_call: - -permissions: - contents: read - -jobs: - lock: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 - with: - persist-credentials: false - - uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5.4.2 - - run: uv lock --check - - ruff: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 - with: - persist-credentials: false - - uses: ./.github/actions/setup-python-env - - run: uv run --frozen ruff check . - - run: uv run --frozen ruff format --check . - - mypy: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 - with: - persist-credentials: false - - uses: ./.github/actions/setup-python-env - - run: uv run --frozen mypy strix/ - - bandit: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 - with: - persist-credentials: false - - uses: ./.github/actions/setup-python-env - - run: uv run --frozen bandit -r strix/ -c pyproject.toml - - pytest: - name: pytest (${{ matrix.python-version }}) - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - python-version: ['3.12', '3.13', '3.14'] - steps: - - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 - with: - persist-credentials: false - - uses: ./.github/actions/setup-python-env - with: - python-version: ${{ matrix.python-version }} - - run: uv run --frozen pytest -q diff --git a/.github/workflows/ci-tui.yml b/.github/workflows/ci-tui.yml deleted file mode 100644 index 1dac8219f..000000000 --- a/.github/workflows/ci-tui.yml +++ /dev/null @@ -1,26 +0,0 @@ -name: TUI - -on: - workflow_call: - -permissions: - contents: read - -jobs: - go: - runs-on: ubuntu-latest - defaults: - run: - working-directory: strix/interface/tui - steps: - - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 - with: - persist-credentials: false - - uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 - with: - go-version-file: strix/interface/tui/go.mod - cache-dependency-path: strix/interface/tui/go.sum - - run: test -z "$(gofmt -l .)" - - run: go vet ./... - - run: CGO_ENABLED=0 go build -trimpath -o /dev/null ./cmd/strix-tui - - run: go test -race ./... diff --git a/.github/workflows/ci-viewer.yml b/.github/workflows/ci-viewer.yml deleted file mode 100644 index 4bfc93613..000000000 --- a/.github/workflows/ci-viewer.yml +++ /dev/null @@ -1,27 +0,0 @@ -name: Viewer - -on: - workflow_call: - -permissions: - contents: read - -jobs: - build: - runs-on: ubuntu-latest - defaults: - run: - working-directory: strix/interface/viewer/frontend - steps: - - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 - with: - persist-credentials: false - - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 - with: - node-version: '24' - cache: npm - cache-dependency-path: strix/interface/viewer/frontend/package-lock.json - - run: npm ci --no-audit --no-fund - - run: npm run build - - name: Committed viewer bundle matches the build - run: git -C "$GITHUB_WORKSPACE" diff --exit-code --stat -- strix/interface/viewer/static && test -z "$(git -C "$GITHUB_WORKSPACE" status --porcelain -- strix/interface/viewer/static)" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9ae8e7636..51d0fe0e8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,38 +15,107 @@ concurrency: cancel-in-progress: true jobs: - python: - uses: ./.github/workflows/ci-python.yml + lint: + runs-on: ubuntu-latest + timeout-minutes: 15 + steps: + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 + with: + persist-credentials: false + - uses: ./.github/actions/setup-python-env + - run: uv lock --check + - run: uv run --frozen ruff check . + - run: uv run --frozen ruff format --check . + - run: uv run --frozen mypy strix/ + - run: uv run --frozen bandit -r strix/ -c pyproject.toml + + pytest: + name: pytest (${{ matrix.python-version }}) + runs-on: ubuntu-latest + timeout-minutes: 15 + strategy: + fail-fast: false + matrix: + python-version: ['3.12', '3.14'] + steps: + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 + with: + persist-credentials: false + - uses: ./.github/actions/setup-python-env + with: + python-version: ${{ matrix.python-version }} + - run: uv run --frozen pytest -q tui: - uses: ./.github/workflows/ci-tui.yml + runs-on: ubuntu-latest + timeout-minutes: 15 + defaults: + run: + working-directory: strix/interface/tui + steps: + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 + with: + persist-credentials: false + - uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 + with: + go-version-file: strix/interface/tui/go.mod + cache-dependency-path: strix/interface/tui/go.sum + - run: test -z "$(gofmt -l .)" + - run: go vet ./... + - run: CGO_ENABLED=0 go build -trimpath -o /dev/null ./cmd/strix-tui + - run: go test -race ./... viewer: - uses: ./.github/workflows/ci-viewer.yml - - package: - uses: ./.github/workflows/ci-package.yml - - workflows: - uses: ./.github/workflows/ci-workflows.yml - - ci-passed: - name: ci-passed - if: always() - needs: - - python - - tui - - viewer - - package - - workflows runs-on: ubuntu-latest + timeout-minutes: 15 + defaults: + run: + working-directory: strix/interface/viewer/frontend steps: - - name: Every job succeeded - env: - NEEDS: ${{ toJSON(needs) }} + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 + with: + persist-credentials: false + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + with: + node-version: '24' + cache: npm + cache-dependency-path: strix/interface/viewer/frontend/package-lock.json + - run: npm ci --no-audit --no-fund + - run: npm run build + - name: Committed viewer bundle matches the build + run: git -C "$GITHUB_WORKSPACE" diff --exit-code --stat -- strix/interface/viewer/static && test -z "$(git -C "$GITHUB_WORKSPACE" status --porcelain -- strix/interface/viewer/static)" + + wheel: + runs-on: ubuntu-latest + timeout-minutes: 15 + steps: + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 + with: + persist-credentials: false + - uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 + with: + go-version-file: strix/interface/tui/go.mod + cache-dependency-path: strix/interface/tui/go.sum + - uses: ./.github/actions/setup-python-env + - run: uv build --wheel + - name: Wheel ships the TUI sidecar and the viewer bundle run: | - failing=$(jq -r 'to_entries[] | select(.value.result != "success") | "\(.key): \(.value.result)"' <<< "$NEEDS") - if [ -n "$failing" ]; then - echo "$failing" - exit 1 - fi + uv run --frozen python - <<'PY' + import glob, zipfile + (wheel,) = glob.glob("dist/*.whl") + names = zipfile.ZipFile(wheel).namelist() + assert "strix/bin/strix-tui" in names, names + assert "strix/interface/viewer/static/index.html" in names, names + assert not any(name.startswith("strix/interface/viewer/frontend/") for name in names) + assert not any(name.startswith("strix/interface/tui/cmd/") for name in names) + PY + - name: Install into a clean environment and run the CLI + env: + UV_EXCLUDE_NEWER: 5 days + run: | + uv venv --python 3.12 /tmp/strix-smoke + uv pip install --python /tmp/strix-smoke/bin/python dist/*.whl + /tmp/strix-smoke/bin/strix --version + /tmp/strix-smoke/bin/strix --help >/dev/null + - name: Vertex AI and Bedrock dependencies install with the wheel + run: /tmp/strix-smoke/bin/python -c "import google.auth.transport.requests, boto3" diff --git a/.github/workflows/ci-workflows.yml b/.github/workflows/workflows.yml similarity index 81% rename from .github/workflows/ci-workflows.yml rename to .github/workflows/workflows.yml index 5796e0d2a..32601e93c 100644 --- a/.github/workflows/ci-workflows.yml +++ b/.github/workflows/workflows.yml @@ -1,14 +1,27 @@ name: Workflows on: - workflow_call: + pull_request: + paths: + - .github/** + push: + branches: + - main + paths: + - .github/** + workflow_dispatch: permissions: contents: read +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: actionlint: runs-on: ubuntu-latest + timeout-minutes: 10 env: ACTIONLINT_VERSION: 1.7.12 ACTIONLINT_SCRIPT_REF: 914e7df21a07ef503a81201c76d2b11c789d3fca # v1.7.12 @@ -27,6 +40,7 @@ jobs: zizmor: runs-on: ubuntu-latest + timeout-minutes: 10 steps: - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 with: diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ceaae9717..00af1cea8 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -45,23 +45,3 @@ repos: hooks: - id: bandit args: [-c, pyproject.toml] - - # Additional Python code quality checks - - repo: https://github.com/asottile/pyupgrade - rev: v3.21.2 - hooks: - - id: pyupgrade - args: [--py312-plus] - -ci: - autofix_commit_msg: | - [pre-commit.ci] auto fixes from pre-commit.com hooks - - for more information, see https://pre-commit.ci - autofix_prs: true - autoupdate_branch: "" - autoupdate_commit_msg: "[pre-commit.ci] pre-commit autoupdate" - autoupdate_schedule: weekly - # pre-commit.ci cannot run `language: system` hooks; mypy runs via `make check-all`. - skip: [mypy] - submodules: false