From 3c6b61e1a79de8390895275cc8aba7d15dd0fc1b Mon Sep 17 00:00:00 2001 From: manavgup Date: Mon, 30 Mar 2026 13:19:59 -0400 Subject: [PATCH 1/2] Add CI workflows: lint, typecheck, test, package, dependency review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ci.yml — 4 parallel jobs on every push/PR to main: - Lint: ruff check + black check - Type Check: mypy - Test: pytest - Package Build: poetry build + twine check dependency-review.yml — on PRs that touch pyproject.toml/poetry.lock: - Fails on moderate+ CVEs - Denies GPL-3.0, AGPL-3.0, SSPL-1.0 licenses Both workflows adopt mcp-context-forge patterns: concurrency groups with cancel-in-progress, draft PR skipping, explicit permissions, job timeouts, persist-credentials: false. Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/ci.yml | 112 ++++++++++++++++++++++++ .github/workflows/dependency-review.yml | 29 ++++++ 2 files changed, 141 insertions(+) create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/dependency-review.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..7ac3bc8 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,112 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + branches: [main] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + lint: + name: Lint + runs-on: ubuntu-latest + timeout-minutes: 5 + if: github.event_name != 'pull_request' || !github.event.pull_request.draft + steps: + - uses: actions/checkout@v4 + with: + persist-credentials: false + + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install Poetry + run: pipx install poetry + + - name: Install dependencies + run: poetry install --no-interaction + + - name: Ruff check + run: poetry run ruff check . + + - name: Black check + run: poetry run black --check . + + typecheck: + name: Type Check + runs-on: ubuntu-latest + timeout-minutes: 5 + if: github.event_name != 'pull_request' || !github.event.pull_request.draft + steps: + - uses: actions/checkout@v4 + with: + persist-credentials: false + + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install Poetry + run: pipx install poetry + + - name: Install dependencies + run: poetry install --no-interaction + + - name: Mypy + run: poetry run mypy faststack_core/ cli/ + + test: + name: Test + runs-on: ubuntu-latest + timeout-minutes: 10 + if: github.event_name != 'pull_request' || !github.event.pull_request.draft + steps: + - uses: actions/checkout@v4 + with: + persist-credentials: false + + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install Poetry + run: pipx install poetry + + - name: Install dependencies + run: poetry install --no-interaction + + - name: Run tests + run: poetry run pytest -v --tb=short + + package: + name: Package Build + runs-on: ubuntu-latest + timeout-minutes: 5 + if: github.event_name != 'pull_request' || !github.event.pull_request.draft + steps: + - uses: actions/checkout@v4 + with: + persist-credentials: false + + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install Poetry + run: pipx install poetry + + - name: Build package + run: poetry build + + - name: Validate package + run: | + pip install twine + twine check dist/* diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml new file mode 100644 index 0000000..a34ae96 --- /dev/null +++ b/.github/workflows/dependency-review.yml @@ -0,0 +1,29 @@ +name: Dependency Review + +on: + pull_request: + branches: [main] + paths: + - "pyproject.toml" + - "poetry.lock" + +permissions: + contents: read + pull-requests: write + +jobs: + dependency-review: + name: Dependency Review + runs-on: ubuntu-latest + timeout-minutes: 5 + if: "!github.event.pull_request.draft" + steps: + - uses: actions/checkout@v4 + with: + persist-credentials: false + + - name: Dependency Review + uses: actions/dependency-review-action@v4 + with: + fail-on-severity: moderate + deny-licenses: GPL-3.0, AGPL-3.0, SSPL-1.0 From 55e1f5966cae04a0a5cbb626cd69034b705677af Mon Sep 17 00:00:00 2001 From: manavgup Date: Mon, 30 Mar 2026 13:25:15 -0400 Subject: [PATCH 2/2] Fix CI: allow pytest exit code 5 (no tests collected) Pytest returns exit code 5 when no tests are collected, which is expected until Phase 1 adds the first tests. The Makefile already handles this; now CI does too. Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7ac3bc8..2f612a5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -84,7 +84,7 @@ jobs: run: poetry install --no-interaction - name: Run tests - run: poetry run pytest -v --tb=short + run: poetry run pytest -v --tb=short || test $? -eq 5 package: name: Package Build