Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,42 @@ jobs:
-m unittest
lib.python.base_demo_cli.tests.test_cli

security:
name: Security scanners
runs-on: ubuntu-latest
timeout-minutes: 20

steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4

- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
with:
python-version: "3.13"

- name: Install uv
run: python -m pip install --disable-pip-version-check uv==0.12.5

- name: Install ShellCheck
run: |
sudo apt-get update
sudo apt-get install -y shellcheck

- name: Run Bandit
run: |
uv run --no-project --with bandit==1.9.4 \
bandit -q -r bin lib -x '*/tests/*' --severity-level medium

- name: Run pip-audit
run: |
uv export --locked --no-dev --no-emit-project --format requirements-txt \
| uv run --no-project --with pip-audit==2.10.1 \
pip-audit --cache-dir "$RUNNER_TEMP/pip-audit" -r /dev/stdin

- name: Run ShellCheck
run: |
git ls-files -z '*.sh' 'bin/base-demo-python-info' \
| xargs -0 shellcheck --severity=error

validate-ubuntu:
runs-on: ubuntu-latest
timeout-minutes: 35
Expand Down
1 change: 1 addition & 0 deletions docs/contracts.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ depend on.
| `compose-local-isolation` | Every published Compose port binds to loopback, Compose owns container names, and every Compose operation uses a stable checkout-and-environment project identity unless automation supplies a validated override. | `infra/compose.yaml`, `bin/base-demo-services` | `tests/infra_test.bats`, `tests/validate.sh` | Disposable credentials can become remotely reachable, or one worktree's lifecycle and log commands can target another worktree's containers. | Security |
| `frontend-setup-path` | `basectl setup base-demo` installs Node 22.22.0 with bundled npm 10.9.4 through mise, and `basectl test base-demo` delegates to a mise task that runs locked `npm ci` when frontend inputs change or dependencies are absent. | `.mise.toml`, `base_manifest.yaml`, `services/demo-console/package.json`, `services/demo-console/package-lock.json` | `tests/demo_console_test.bats`, `tests/validate.sh`, Base's external base-demo E2E | A clean checkout can pass setup but fail the supported test path because Node, npm, Vite, or `node_modules` was never provisioned. | Setup |
| `demo-console-build-gate` | macOS and Ubuntu CI install the locked frontend dependencies with Node 22.22.0/npm 10.9.4, compile the production console, assert entry artifacts, and fail the audit at moderate severity or higher. | `services/demo-console/package.json`, `services/demo-console/package-lock.json`, `.github/workflows/tests.yml` | `services/demo-console/build.sh`, `tests/demo_console_test.bats`, `tests/validate.sh` | Green validation can skip Vite, omit production artifacts, or retain a known dependency advisory. | CI |
| `security-scanners` | Required CI runs pinned Bandit 1.9.4 over project Python sources, pip-audit 2.10.1 against the locked uv export, and ShellCheck over tracked shell entrypoints. | `.github/workflows/tests.yml`, `pyproject.toml`, `uv.lock` | `tests/validate.sh`, GitHub Actions `security` | Shell or Python security regressions and vulnerable locked dependencies can merge without a dedicated required signal. | Security |
| `ci-trigger-deduplication` | Feature-branch commits run the validation workflow through `pull_request` only, `push` validation remains enabled for `main`, superseded runs cancel only within the same PR number or ref, and the `validate`, `validate-base-cli-source`, and `validate-ubuntu` job IDs remain stable. | `.github/workflows/tests.yml` | `tests/validate.sh`, GitHub Actions | A PR commit can consume two full validation runs, unrelated branches can cancel one another, default-branch validation can disappear, or check names can drift. | CI |
| `release-identity` | `VERSION` is the authoritative stable SemVer identity; Python/uv metadata, frontend package metadata, the Base-style top README badge strip and release links, and the changelog heading agree, and only an explicit matching `vX.Y.Z` tag can publish a GitHub Release. | `VERSION`, `pyproject.toml`, `uv.lock`, `services/demo-console/package.json`, `README.md`, `CHANGELOG.md`, `.github/workflows/release.yml` | `bin/base-demo-release-check`, `tests/validate.sh`, GitHub Actions | Users, automation, or release provenance can disagree about the base-demo version, the current release can be hard to discover, the project-status strip can drift, or an unreviewed branch can publish a release. | Release |
| `ci-pinned-dependencies` | CI uses immutable full commits for the published Base v1.8.0 and base-bash-libs v2.0.0 contracts, plus full SHA-pinned GitHub Actions. | `.github/workflows/tests.yml` | `tests/validate.sh` | CI can drift with Base `main`, an older base-bash-libs release, or mutable action tags instead of validating the intended release capability contract. | CI |
Expand Down
19 changes: 19 additions & 0 deletions tests/validate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,25 @@ for job_id in ("validate", "validate-base-cli-source", "validate-ubuntu"):
)
PY

security_workflow_contracts=(
' security:'
'name: Security scanners'
'timeout-minutes: 20'
'actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065'
'python -m pip install --disable-pip-version-check uv==0.12.5'
'uv run --no-project --with bandit==1.9.4'
'uv run --no-project --with pip-audit==2.10.1'
'uv export --locked --no-dev --no-emit-project --format requirements-txt'
"git ls-files -z '*.sh' 'bin/base-demo-python-info'"
'shellcheck --severity=error'
)
for security_contract in "${security_workflow_contracts[@]}"; do
grep -Fq "$security_contract" .github/workflows/tests.yml || {
printf '.github/workflows/tests.yml is missing security contract: %s\n' "$security_contract" >&2
exit 1
}
done

grep -Fq 'pull_request_target:' .github/workflows/issue-branch-policy.yml || {
printf '.github/workflows/issue-branch-policy.yml does not validate pull_request_target events.\n' >&2
exit 1
Expand Down
Loading