docs(release): tighten PRE_PUBLIC_AUDIT.md commit-count phrasing (QA … #99
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: CI — Validate & Package | |
| # ═══════════════════════════════════════════════════════════════════════ | |
| # E2E TEST HARNESS GATE — READ BEFORE ENABLING E2E TESTS IN CI | |
| # ═══════════════════════════════════════════════════════════════════════ | |
| # | |
| # The E2E tests under tests/e2e/ are DESTRUCTIVE — they delete KV store | |
| # records, mutate config files, clear tamper flags. Every destructive | |
| # helper is gated behind TWO checks: | |
| # | |
| # 1. WL_TEST_HARNESS=1 environment variable | |
| # 2. Container name "wl_manager_test" | |
| # | |
| # If you add an E2E job to this workflow, set WL_TEST_HARNESS=1 INLINE | |
| # on each step that runs a test, NEVER as a job-wide env block: | |
| # | |
| # - name: Run harness gate verification | |
| # run: WL_TEST_HARNESS=1 node tests/e2e/test_harness_gate.cjs | |
| # | |
| # - name: Run cooldown tamper tests | |
| # run: WL_TEST_HARNESS=1 node tests/e2e/test_cooldown_tamper.cjs | |
| # | |
| # DO NOT set WL_TEST_HARNESS=1 under `env:` at workflow or job scope — | |
| # that leaks the variable into unrelated steps and defeats the point | |
| # of the gate. | |
| # | |
| # DO NOT copy this env var to any other repository, `.env` file, or | |
| # shared shell profile. | |
| # | |
| # See tests/e2e/README.md for the full rationale. | |
| # ═══════════════════════════════════════════════════════════════════════ | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| permissions: | |
| contents: read | |
| jobs: | |
| validate: | |
| name: Validate App | |
| runs-on: ubuntu-latest | |
| # Per-job permissions (round 7, 2026-04-29). Even though the | |
| # workflow declares `permissions: contents: read` at the top | |
| # level, repeating it per-job means an audit of any single job | |
| # answers "what can this job touch?" without scrolling. It also | |
| # protects against a future workflow-level change (e.g., adding | |
| # `pull-requests: write` for a comment-bot job) silently | |
| # widening every existing job's scope. | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.11" | |
| - name: Run validation checks | |
| run: bash scripts/validate.sh | |
| - name: Build .spl package | |
| run: bash scripts/package.sh | |
| - name: Upload .spl artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: wl_manager-spl | |
| path: dist/*.spl | |
| retention-days: 30 | |
| doc-drift: | |
| name: Doc Drift Check | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Run doc-drift guard | |
| # Same script the pre-commit hook runs locally. Verifies | |
| # file paths in the docs exist + that bare "Build NNN" prose | |
| # stays in sync with default/app.conf. Origin: 2026-04-19 | |
| # incident where build numbers drifted across 6 builds | |
| # before the user noticed. | |
| run: bash scripts/pre-commit-doc-drift.sh | |
| unit-tests: | |
| name: Unit Tests | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.11" | |
| - name: Install Python dev deps | |
| # Pytest + hypothesis + freezegun. Excludes Playwright (the | |
| # E2E tests are gated by WL_TEST_HARNESS=1 and need a real | |
| # Splunk container — see the gate notice at top of file). | |
| # pytest 9.0.3+ required to close GHSA-6w46-j5rx-g56g | |
| # (round 7 B4, 2026-04-29 pip-audit run). | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install pytest==9.0.3 pytest-cov==5.0.0 freezegun==1.5.1 \ | |
| hypothesis==6.90.0 pytest-timeout==2.1.0 | |
| - name: Run unit tests | |
| # The unit suite mocks Splunk REST + filesystem layers; no | |
| # Splunk container required. ~7s for 539 tests locally. | |
| run: python -m pytest tests/unit/ -q --tb=short | |
| - name: Run module-level tests | |
| # Top-level tests/test_*.py files cover lower-layer modules | |
| # (wl_limits, wl_hmac_key, wl_fim_common, wl_expiration_cleanup) | |
| # with HMAC and period-boundary coverage that tests/unit/ does | |
| # not duplicate. Note: a former tests/test_wl_filelock.py | |
| # reference was removed during round 7 B4 — no such file | |
| # exists; the filelock paths are exercised inside | |
| # tests/unit/test_filelock.py. | |
| run: | | |
| python -m pytest tests/test_wl_limits.py \ | |
| tests/test_wl_hmac_key.py \ | |
| tests/test_wl_fim_common.py \ | |
| tests/test_wl_expiration_cleanup.py \ | |
| -q --tb=short | |
| js-unit-tests: | |
| # Ring 4 Day 1-3 added 46 Vitest unit tests under | |
| # tests/js/ that exercise pure-JS modules | |
| # (parseCSV, csvEscape, validateImportedCSV, | |
| # renderDiff, approval_ui helpers) via an AMD→CJS | |
| # bridge. They run in <250ms with no Splunk | |
| # container — ideal CI gate. | |
| # | |
| # Why a separate job (not folded into unit-tests): | |
| # Python and JS have unrelated dep stacks. Mixing | |
| # them in one job means a Python dep failure breaks | |
| # the JS signal and vice versa. Keeping them split | |
| # gives PR reviewers one green/red light per | |
| # ecosystem. | |
| name: JS Unit Tests | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Node.js | |
| # Node 20 LTS. Vitest 3.x requires Node ≥18; we | |
| # pin to the latest LTS so the toolchain matches | |
| # what most contributors run locally. | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: "20" | |
| # Cache npm dependencies keyed on package-lock.json | |
| # — every push reuses the cache unless deps | |
| # changed, cutting ~30s off the run. | |
| cache: "npm" | |
| - name: Install dev dependencies | |
| # `npm ci` requires package-lock.json (which exists) | |
| # and is strictly reproducible — fails if | |
| # package.json + lockfile are out of sync. Use | |
| # this rather than `npm install` to catch | |
| # accidentally-uncommitted lockfile drift. | |
| run: npm ci | |
| - name: Run JS unit tests | |
| # ~250ms for 46 tests locally; allow a generous | |
| # 2-minute hard cap in case GitHub runners are | |
| # slow. Failures here surface as a separate | |
| # check beside the Python unit-tests job. | |
| run: npm run test:js | |
| timeout-minutes: 2 |