First-push checklist & CI bring-up (WW-42)¶
Everything in WorkWingman has been built, gated, and committed locally — the repo has never been pushed. The first push is the user's call (the autonomous build never pushes). This doc is the pre-flight: what was verified before that push, what the push triggers, and how to confirm it landed clean. Clearing it unblocks WW-33 (prove the security CI jobs on a real GitHub runner).
1. Pre-push hygiene — verified¶
Run from the repo root; all of these were green at the time of writing.
| Check | Command | Result |
|---|---|---|
| Remote configured | git remote -v |
✅ origin → github.com/andrewjonesdev/WorkWingman.git |
| No build artifacts tracked | git ls-files \| grep -E '(^\|/)(bin\|obj\|node_modules)/\|\.(dll\|exe\|pdb)$' |
✅ empty |
.gitignore present |
test -f .gitignore |
✅ |
.gitattributes normalizes CI-sensitive files |
cat .gitattributes |
✅ SVGs -text (byte-identical for the diagram drift-check), *.sh eol=lf (LF shebangs on Linux runners) |
| No large blobs (>500 KB) | size sweep over git ls-files |
✅ none |
| No hardcoded secrets in source | git grep -nIE '(password\|secret\|apikey\|token)\s*=\s*["'"'"'][^"'"'"']{8,}' over src/frontend/src |
✅ none (secrets live in the KeePass vault / env / IConfiguration, never in source) |
| Secret-scan config present | test -e .gitleaks.toml |
✅ (the secrets job runs gitleaks over full history against it) |
| Test settings present | test -e test.runsettings |
✅ |
| Dependency allowlist present | .github/dependency-allowlist.txt |
✅ |
| Stryker configs present | per-project (tests/WorkWingman.Tests/stryker-config.json, frontend/stryker.conf.json) |
✅ |
SECURITY.md published |
docs/SECURITY.md (+ plain/technical variants) |
✅ |
| Working tree clean | git status --porcelain (excluding docs/business/) |
✅ |
Line endings note: the working copy is on Windows with
core.autocrlfactive, sogitreports "LF will be replaced by CRLF" on commit. The repo stores LF; only the SVGs and shell scripts are pinned via.gitattributes(the two places CRLF would actually break CI). Source files round-trip fine. If line-ending churn ever shows up in diffs, add* text=auto— not needed today.
2. What the first push triggers¶
Two workflows fire on push / pull_request to the default branch. This is their first run on
a hosted runner (they've only been validated locally in Docker so far — that's the WW-33 gap).
.github/workflows/ci.yml — the main gate, jobs:
- backend — dotnet build -c Release + dotnet test (with test.runsettings), Playwright chromium installed.
- frontend — npm ci + Angular unit tests.
- sast — Semgrep (p/csharp p/typescript p/javascript p/security-audit p/secrets), --error hard-fails on findings; inline // nosemgrep: <rule> -- <reason> suppressions.
- secrets — gitleaks over the FULL history (fetch-depth: 0) against .gitleaks.toml. Hard gate.
- dast — OWASP ZAP baseline against the running API on 127.0.0.1:5211.
- security — npm audit --audit-level=high (hard gate on high/critical).
- churn / docs / diagrams — doc + diagram drift checks (the D2 SVGs must match their source).
- dotnet-e2e — the Playwright E2E project builds and runs.
.github/workflows/mutation.yml — Stryker mutation testing (backend from tests/WorkWingman.Tests, frontend from frontend/). This is the WW-34 surface; it uploads the mutation report as an artifact.
3. The push (user action — the build never pushes)¶
git -C <repo> push -u origin master
If GitHub rejects the branch name or the repo wants main, rename first (git branch -m master main)
— but confirm the workflows' branch filters match whatever you land on.
4. Post-push verification (this is WW-33)¶
- Open the repo's Actions tab; the two workflows should appear on the pushed commit.
- Confirm each ci.yml job goes green. The likely first-run friction points, and what they mean:
- dast needs the API reachable on
:5211inside the job — if it can't bind, the job step that launches the API is the thing to check, not the ZAP step. - secrets scanning full history can surface something an incremental local scan missed — read any finding before assuming a false positive; add to
.gitleaks.tomlonly with a justification. - sast findings are hard failures — triage each; suppress inline only with a reason.
- If a hosted-runner-only failure appears (a tool version, a container permission, a path-case mismatch), fix it on a branch and re-push — do not disable the job to make it green.
- Once all jobs are green on the hosted runner, WW-33 is satisfied and can be closed.
5. Not covered here (still blocked, by design)¶
- WW-32 — Workday selectors on a real tenant (needs a live tenant).
- WW-34 — mutation-coverage thresholds for the apply vertical (the workflow runs; ratcheting the score is its own task).