chore: move superpowers specs/plans to planning/ #7
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 |