feat(ci): implement CI dry-run workflow and PR checklist for history rewrite process

This commit is contained in:
GitHub Actions
2025-12-09 02:36:10 +00:00
parent fe75c58861
commit 1adbd0aba4
6 changed files with 359 additions and 0 deletions
+175
View File
@@ -540,3 +540,178 @@ Implement real CrowdSec Hub preset sync + apply on backend (using cscli or direc
- Existing curated presets remain but are marked as bundled; UI should continue to show them even if hub unreachable.
- Stub endpoint `POST /admin/crowdsec/presets/pull/apply` is replaced by separate `pull` and `apply`; frontend must switch to new API paths before backend removal to avoid 404.
- Backward compatibility: keep returning 501 from old endpoint until frontend merged; remove once new routes live and tested.
---
**Automated CI Dry-Run & PR Checklist Plan**
-------------------------------------------
Objective: Add a CI dry-run workflow and a PR checklist enforcement job and template to reduce release/merge regressions. The dry-run will validate build/test/lint/packaging steps without publishing or writing secrets. The PR checklist job ensures contributors used the PR template.
Files to add / edit
- Add: `.github/workflows/dry-run.yml` — main dry-run workflow triggered on PR and schedule (weekly)
- Add: `.github/workflows/pr-checklist.yml` — PR body validation workflow to ensure PR checklist compliance
- Add: `.github/PULL_REQUEST_TEMPLATE/pr_template.md` — PR template with developer checklist
- Add: `scripts/ci/dry_run_build.sh` — wrapper script used by dry-run to orchestrate checks
- Add: `scripts/ci/dry_run_goreleaser.sh` — goreleaser snapshot dry-run runner
- Add: `scripts/ci/check_pr_checklist.sh` — standalone PR-checklist script (for local/CI usage)
- Edit: `.pre-commit-config.yaml` — recommend add `tsc --noEmit` and `golangci-lint` local hooks (if not present as mandatory checks)
- Review: `.gitignore`, `.gitattributes` — ensure `scripts/ci` temp artifacts are ignored and LFS/gitattribute rules still appropriate
Suggested job names & responsibilities
- `dry-run-backend` (backend build: `go build`, `go test` with coverage, `go vet`)
- `dry-run-frontend` (frontend build & tests, `npm ci`, `npm run build`, `npm run test:ci`)
- `dry-run-docker` (docker build only, `docker build`, no push; multi-platform on branches only)
- `dry-run-goreleaser` (goreleaser release in dry-run mode; `--snapshot` or `--skip-publish`)
- `dry-run-security` (Trivy fs scan of built binary and optional static scans; non-publish SARIF upload disabled for fork PRs)
- `validate-pr-checklist` (validate PR body contains required checklist items)
Workflow triggers
- `pull_request` (types: opened, edited, synchronize, reopened)
- `workflow_dispatch` (manual run)
- `schedule` (cron — e.g., `0 3 * * 0` weekly; optional daily lightweight run for repo health exists already via `repo-health.yml`)
Permissions and secrets considerations
- Default minimal perms: `contents: read` for checkout; use `checks: write` to set check statuses if necessary.
- Do not use `packages: write` or `GITHUB_TOKEN` write duties on PRs (unless gated to branch-origin PRs). Dry-run avoids publishing and won't require `packages: write`.
- Conditionally run `goreleaser` or any publish checks only when PR originates from repo owner and/or is a branch on the main repo (forks cannot access secrets): `if: ${{ github.event.pull_request.head.repo.full_name == github.repository }}`.
- `CHARON_TOKEN` or custom PAT should not be used in PR runs from forks to avoid secret leakage.
YAML job snippet samples
1) Example `dry-run-backend` job
```yaml
jobs:
dry-run-backend:
name: Backend Dry-Run
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v4
with: { go-version: '1.25' }
- name: Run repo health check
run: bash scripts/repo_health_check.sh
- name: Run backend tests
run: bash scripts/go-test-coverage.sh
```
2) Example `dry-run-frontend` job
```yaml
dry-run-frontend:
name: Frontend Dry-Run
runs-on: ubuntu-latest
needs: dry-run-backend
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: '24' }
- name: Install + Test
working-directory: frontend
run: |
npm ci
bash ../scripts/frontend-test-coverage.sh 2>&1 | tee frontend/test-output.txt
```
3) Example `dry-run-docker` job
```yaml
dry-run-docker:
name: Build Docker Image (No Push)
runs-on: ubuntu-latest
needs: dry-run-frontend
steps:
- uses: actions/checkout@v4
- name: Build Docker
run: docker build --platform linux/amd64 -t charon:pr-${{ github.sha }} .
```
4) Example `dry-run-goreleaser` job protected from fork PR secrets exposure
```yaml
dry-run-goreleaser:
name: GoReleaser Dry-Run
runs-on: ubuntu-latest
needs: dry-run-docker
if: ${{ github.event_name == 'workflow_dispatch' || github.repository == github.event.pull_request.head.repo.full_name }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v4
with: { go-version: '1.25' }
- name: Run GoReleaser (dry-run)
uses: goreleaser/goreleaser-action@v6
with: { args: 'release --snapshot --rm-dist --skip-publish' }
```
5) PR checklist validation job (using `github-script` or local script)
```yaml
jobs:
validate-pr-checklist:
name: Validate PR Checklist
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Validate checklist
uses: actions/github-script@v7
with:
script: |
const pr = await github.rest.pulls.get({owner: context.repo.owner, repo: context.repo.repo, pull_number: context.issue.number});
const body = (pr.data && pr.data.body) || '';
const required = [ 'Tests (backend/frontend) pass', 'Pre-commit checks pass', 'Lints and type checks pass', 'Changelog updated (if applicable)' ];
for (const r of required) {
if (!body.toLowerCase().includes(r.toLowerCase())) { core.setFailed('Missing checklist item: '+r); return; }
}
```
Expected behavior and gating strategy
- The dry-run workflow runs on PRs and fails the PR if build/test/goreleaser dry-run steps fail.
- For PRs from forks, goreleaser/publish and other actions requiring secrets must be gated and skipped.
- Maintain only lightweight jobs for PRs (run code checks, not artifact uploads). For nightly schedules, run heavier checks.
Edge cases & mitigation
- Fork PRs: secrets are not available. Skip secret-dependent steps and run only build/test/lint steps.
- Large builds or timeouts: Break checks into small jobs with `needs` to fail early, set timeouts on longest-running jobs and precautions for cache usage.
- Flaky tests: mark flaky steps non-blocking but create an issue/annotation when flaky tests flake.
CI Scheduler recommendation
- Keep the existing `repo-health.yml` schedule (daily). Add `dry-run.yml` with weekly schedule (`0 3 * * 0`) to validate the entire build pipeline weekly.
PR Template (simply create `.github/PULL_REQUEST_TEMPLATE/pr_template.md`) — basic checklist
```markdown
## Summary
## Checklist
- [ ] Tests (backend & frontend) validated locally and CI
- [ ] All tests pass in CI (Quality Checks)
- [ ] Lint and type checks pass (pre-commit hooks run locally)
- [ ] Changelog updated (if relevant)
- [ ] Docs updated (if user-facing change)
- [ ] No sensitive info or secrets in this PR
```
`.gitattributes`, `.gitignore`, and pre-commit checks review
- `.gitattributes`: ensure `*.db`, `*.sqlite`, `codeql-db/**` are LFS/binary as appropriate (file exists): verify no changes required; add new file patterns for scripts/ci artifacts if necessary.
- `.gitignore`: add `/.tmp-ci` or other ephemeral artifact patterns for CI scripts to avoid noise.
- `.pre-commit-config.yaml`: add a local `tsc` or `npx tsc --noEmit` hook if not present; keep `check-lfs-large-files` and `block-codeql-db-commits` enforced. Consider adding a new local `ci-dry-run` hook for pre-push gating (manual stage) but mainly rely on the CI workflows.
Testing plan & acceptance criteria
- Run `dry-run.yml` via `workflow_dispatch` for a test branch (internal) and validate the dry-run jobs pass.
- Open a sample PR with an incomplete checklist and confirm `pr-checklist` fails with actionable message.
- Verify `goreleaser` dry-run step will not run for forked PRs and is only executed for branches in the same repository.
- Acceptance: job completes successfully under normal code status; PR blocking on failures for `main` + `feature/beta-release`.
Next steps for maintainers
1) Create the initial `dry-run.yml` & `pr-checklist.yml` workflows and a test PR to check behavior.
2) Add `scripts/ci/dry_run_*` scripts and link them from the new workflows.
3) Add the PR template file in `.github/PULL_REQUEST_TEMPLATE` and update `CONTRIBUTING.md` to require PR checklist checks.
4) Test behavior for fork PRs and set branch protection rules to require these checks on relevant branches.
5) Iterate in a small number of PRs to tune the threshold and gating behavior.
Status: Implemented
Files added and wired into CI:
- `.github/workflows/dry-run-history-rewrite.yml` — runs a non-destructive history/large-file check on PRs and schedule.
- `.github/PULL_REQUEST_TEMPLATE/history-rewrite.md` — PR checklist for history rewrite PRs.
- `scripts/ci/dry_run_history_rewrite.sh` — CI wrapper that fails when banned paths or large historical objects are found.-.github/workflows/pr-checklist.yml — validates the PR body contains required checklist items for history-rewrite PRs.
Validation steps performed locally and via CI (dry-run):
- `scripts/ci/dry_run_history_rewrite.sh` returns non-zero when repo history contains objects or commits touching `backend/codeql-db` or other listed paths.
- The workflow uses `actions/checkout@v4` with `fetch-depth: 0` to ensure history is available for the check.
- PR template ensures contributors attach dry-run output and backup logs prior to destructive cleanups.
Next considerations:
- Add a `validate-pr-checklist` workflow to enforce general PR checklist items for all PRs if desired (future improvement).
+5
View File
@@ -76,3 +76,8 @@ Post rewrite maintenance
Communication & Approval
------------------------
Open a PR with dry-run logs and `preview_removals` output, tag maintainers for approval before `--force` is used.
CI automation
-------------
- A CI dry-run workflow `.github/workflows/dry-run-history-rewrite.yml` runs a non-destructive check that fails CI when banned history entries or large objects are found. It is triggered on PRs and a daily schedule.
- A PR checklist template `.github/PULL_REQUEST_TEMPLATE/history-rewrite.md` and a checklist validator `.github/workflows/pr-checklist.yml` ensure contributors attach the preview output and backups before seeking approval.