Skip to content

chore: move superpowers specs/plans to planning/ #7

chore: move superpowers specs/plans to planning/

chore: move superpowers specs/plans to planning/ #7

Workflow file for this run

name: main
on:
push:
branches:
- main
pull_request: {}
concurrency:
group: ${{ github.head_ref || github.run_id }}
cancel-in-progress: true
permissions:
contents: read
jobs:
lint:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- uses: extractions/setup-just@v2
- uses: astral-sh/setup-uv@v3
with:
enable-cache: true
cache-dependency-glob: "**/pyproject.toml"
- run: uv python install 3.10
- run: just install lint-ci
- name: Validate templates/semvertag.yml shape
# GitLab CI Catalog component descriptor — no published JSON Schema
# exists upstream (verified 2026-05-30: not in check-jsonschema's
# vendor.* builtins, not on schemastore.org). Fall back to a
# structural sanity check via the shared helper in
# tests/_descriptor_gate.py — the same module is exercised by
# tests/test_ci_descriptor_gate.py so the gate and its regression
# tests cannot drift. Upgrade path: switch to a real schema
# validator if/when GitLab publishes a Catalog component schema.
run: uv run --with pyyaml python -m tests._descriptor_gate templates/semvertag.yml
- name: Descriptor gate regression tests
# tests/test_ci_descriptor_gate.py uses pytest.importorskip("yaml") so
# it skips in the main `uv run pytest` job; this step exercises the
# full positive + negative-mutation suite against the shared helper.
run: uv run --with pyyaml pytest tests/test_ci_descriptor_gate.py -q
- run: uv build
- run: uv run --with-requirements docs/requirements.txt -- mkdocs build --strict
- id: loc_gate
name: LOC gate (NFR21)
run: |
# Non-blank, non-comment, non-docstring SLOC under semvertag/**/*.py.
# Docstring bodies are excluded per NFR21 wording ("non-blank non-comment").
# Recognises """-delimited docstrings only — this codebase doesn't use '''.
LOC=$(find semvertag -name '*.py' -type f -not -path '*/__pycache__/*' -print0 \
| xargs -0 awk '
BEGIN { total = 0 }
FNR == 1 { in_ds = 0 }
{
if (in_ds) {
if ($0 ~ /"""[[:space:]]*$/) { in_ds = 0 }
next
}
if ($0 ~ /^[[:space:]]*"""/) {
if ($0 ~ /^[[:space:]]*""".*"""[[:space:]]*$/) { next }
in_ds = 1
next
}
if (NF && $0 !~ /^[[:space:]]*#/) { total++ }
}
END { print total }
')
echo "::notice::semvertag/**/*.py = ${LOC} LOC (NFR21 soft target: 1500)"
echo "semvertag_loc=${LOC}" >> "$GITHUB_OUTPUT"
if [ "${LOC}" -gt 1500 ]; then
echo "::warning::LOC ${LOC} exceeds NFR21 soft target of 1500"
fi
pytest:
runs-on: ubuntu-latest
timeout-minutes: 15
strategy:
fail-fast: false
matrix:
python-version:
- "3.10"
- "3.11"
- "3.12"
- "3.13"
- "3.14"
steps:
- uses: actions/checkout@v4
- uses: extractions/setup-just@v2
- uses: astral-sh/setup-uv@v3
with:
enable-cache: true
cache-dependency-glob: "**/pyproject.toml"
- run: uv python install ${{ matrix.python-version }}
- run: just install
- run: just test . --cov=. --cov-report xml
# Fork-safe guard: explicit allowlist — push on main + same-repo PR. Any future
# event addition (schedule, workflow_dispatch, merge_group, pull_request_target)
# is excluded by default so CODECOV_TOKEN is not exposed to those contexts.
- if: ${{ github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository) }}
uses: codecov/codecov-action@v5.5.1
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
with:
files: ./coverage.xml
flags: unittests
name: codecov-${{ matrix.python-version }}
pip-audit:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- uses: extractions/setup-just@v2
- uses: astral-sh/setup-uv@v3
with:
enable-cache: true
cache-dependency-glob: "**/uv.lock"
- run: uv python install 3.10
- run: just install
# Export the resolved lockfile to requirements format so pip-audit scans the
# pinned versions semvertag actually ships (not whatever pyproject.toml
# resolves to fresh today — its specifiers are unbounded).
- run: uv export --format requirements-txt --frozen --no-hashes --output-file requirements-audit.txt
- uses: pypa/gh-action-pip-audit@v1.1.0
with:
inputs: requirements-audit.txt