From c1dbdf37881ed76efee204d72469f20f68ca5e42 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 21 Apr 2026 22:01:42 +0000 Subject: [PATCH] Add CI/CD workflows matching GNAT - python-tests: pytest matrix on 3.11 + 3.12 - python-lint-fast: Ruff check + format on PR/push - python-typecheck: mypy on redgnat/ (blocking) - python-security: Bandit + pip-audit on PR/push/weekly schedule - semgrep: SAST on PR/push/weekly schedule - dco_check: DCO sign-off enforcement on PRs - dependency-review: pip-audit on PRs - pylint: Pylint on all pushes across 3.11 + 3.12 - security-hygiene: technique + engagement tests on relevant path changes https://claude.ai/code/session_01DGwbYiq7PnxMxMXtnTEmov --- .github/workflows/dco_check.yml | 14 ++++++++ .github/workflows/dependency-review.yml | 21 ++++++++++++ .github/workflows/pylint.yml | 26 +++++++++++++++ .github/workflows/python-lint-fast.yml | 28 ++++++++++++++++ .github/workflows/python-security.yml | 44 +++++++++++++++++++++++++ .github/workflows/python-tests.yml | 35 ++++++++++++++++++++ .github/workflows/python-typecheck.yml | 31 +++++++++++++++++ .github/workflows/security-hygiene.yml | 29 ++++++++++++++++ .github/workflows/semgrep.yml | 29 ++++++++++++++++ 9 files changed, 257 insertions(+) create mode 100644 .github/workflows/dco_check.yml create mode 100644 .github/workflows/dependency-review.yml create mode 100644 .github/workflows/pylint.yml create mode 100644 .github/workflows/python-lint-fast.yml create mode 100644 .github/workflows/python-security.yml create mode 100644 .github/workflows/python-tests.yml create mode 100644 .github/workflows/python-typecheck.yml create mode 100644 .github/workflows/security-hygiene.yml create mode 100644 .github/workflows/semgrep.yml diff --git a/.github/workflows/dco_check.yml b/.github/workflows/dco_check.yml new file mode 100644 index 0000000..81e3f21 --- /dev/null +++ b/.github/workflows/dco_check.yml @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright 2026 Bill Halpin +--- +name: DCO Check + +on: + pull_request: + +jobs: + dco: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: tim-actions/dco@master diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml new file mode 100644 index 0000000..9bbd92f --- /dev/null +++ b/.github/workflows/dependency-review.yml @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright 2026 Bill Halpin +--- +name: Dependency Review + +on: + pull_request: + +permissions: + contents: read + +jobs: + pip-audit: + runs-on: ubuntu-latest + steps: + - name: Check out code + uses: actions/checkout@v4 + - name: Run pip-audit + uses: pypa/gh-action-pip-audit@v1.1.0 + with: + inputs: "." diff --git a/.github/workflows/pylint.yml b/.github/workflows/pylint.yml new file mode 100644 index 0000000..37c6116 --- /dev/null +++ b/.github/workflows/pylint.yml @@ -0,0 +1,26 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright 2026 Bill Halpin +--- +name: Pylint + +on: [push] + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.11", "3.12"] + steps: + - uses: actions/checkout@v4 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v6 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install pylint + pip install -e ".[dev]" + - name: Analysing the code with pylint + run: pylint redgnat/ diff --git a/.github/workflows/python-lint-fast.yml b/.github/workflows/python-lint-fast.yml new file mode 100644 index 0000000..ec672e1 --- /dev/null +++ b/.github/workflows/python-lint-fast.yml @@ -0,0 +1,28 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright 2026 Bill Halpin +--- +name: Python Fast Lint + +on: + pull_request: + push: + branches: [main] + +concurrency: + group: python-fast-lint-${{ github.ref }} + cancel-in-progress: true + +jobs: + ruff: + runs-on: ubuntu-latest + steps: + - name: Check out code + uses: actions/checkout@v4 + - name: Run Ruff + uses: astral-sh/ruff-action@v3 + with: + args: check . + - name: Check formatting + uses: astral-sh/ruff-action@v3 + with: + args: format --check . diff --git a/.github/workflows/python-security.yml b/.github/workflows/python-security.yml new file mode 100644 index 0000000..318a0a0 --- /dev/null +++ b/.github/workflows/python-security.yml @@ -0,0 +1,44 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright 2026 Bill Halpin +--- +name: Python Security + +on: + pull_request: + push: + branches: [main] + schedule: + - cron: "23 4 * * 1" # Mondays at 04:23 UTC + +concurrency: + group: python-security-${{ github.ref }} + cancel-in-progress: true + +jobs: + bandit: + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - name: Check out code + uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.11" + - name: Install Bandit + run: pip install bandit + - name: Run Bandit + run: bandit -r redgnat/ -ll -x tests/ + + pip-audit: + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - name: Check out code + uses: actions/checkout@v4 + - name: Run pip-audit + uses: pypa/gh-action-pip-audit@v1.1.0 + with: + inputs: "." diff --git a/.github/workflows/python-tests.yml b/.github/workflows/python-tests.yml new file mode 100644 index 0000000..4566f0d --- /dev/null +++ b/.github/workflows/python-tests.yml @@ -0,0 +1,35 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright 2026 Bill Halpin +--- +name: Python Tests + +on: + pull_request: + push: + branches: [main] + +concurrency: + group: python-tests-${{ github.ref }} + cancel-in-progress: true + +jobs: + test: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + python-version: ["3.11", "3.12"] + steps: + - name: Check out code + uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v6 + with: + python-version: ${{ matrix.python-version }} + cache: pip + - name: Upgrade pip + run: python -m pip install --upgrade pip + - name: Install package and test deps + run: pip install -e ".[dev]" + - name: Run tests + run: pytest -q diff --git a/.github/workflows/python-typecheck.yml b/.github/workflows/python-typecheck.yml new file mode 100644 index 0000000..0411abb --- /dev/null +++ b/.github/workflows/python-typecheck.yml @@ -0,0 +1,31 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright 2026 Bill Halpin +--- +name: Python Type Check + +on: + pull_request: + push: + branches: [main] + +concurrency: + group: python-typecheck-${{ github.ref }} + cancel-in-progress: true + +jobs: + mypy: + runs-on: ubuntu-latest + steps: + - name: Check out code + uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v6 + with: + python-version: "3.11" + cache: pip + - name: Upgrade pip + run: python -m pip install --upgrade pip + - name: Install package and type deps + run: pip install -e ".[dev]" + - name: Run mypy + run: mypy redgnat/ diff --git a/.github/workflows/security-hygiene.yml b/.github/workflows/security-hygiene.yml new file mode 100644 index 0000000..36ea8de --- /dev/null +++ b/.github/workflows/security-hygiene.yml @@ -0,0 +1,29 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright 2026 Bill Halpin +--- +name: Security Hygiene + +on: + pull_request: + paths: + - "redgnat/techniques/**" + - "redgnat/engagement/**" + - "tests/unit/techniques/**" + - "tests/unit/engagement/**" + - ".github/workflows/security-hygiene.yml" + workflow_dispatch: + +jobs: + hygiene: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: "3.11" + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -e ".[dev]" + - name: Run technique and engagement tests + run: pytest tests/unit/techniques/ tests/unit/engagement/ -q diff --git a/.github/workflows/semgrep.yml b/.github/workflows/semgrep.yml new file mode 100644 index 0000000..a161843 --- /dev/null +++ b/.github/workflows/semgrep.yml @@ -0,0 +1,29 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright 2026 Bill Halpin +--- +name: Semgrep + +on: + pull_request: + push: + branches: [main] + schedule: + - cron: "11 5 * * 3" # Wednesdays at 05:11 UTC + +jobs: + semgrep: + name: Semgrep SAST + runs-on: ubuntu-latest + permissions: + contents: read + + steps: + - name: Check out code + uses: actions/checkout@v4 + - name: Run Semgrep + uses: returntocorp/semgrep-action@v1 + with: + config: >- + p/python + p/security-audit + p/secrets