Skip to content

feat: implement issue #798 — Story: SEED + DISTRIBUTE — baseline into repo-template, bootstrap, and deploy sync - #805

Merged
don-petry merged 6 commits into
mainfrom
dev-lead/issue-798-20260719-1945
Jul 19, 2026
Merged

feat: implement issue #798 — Story: SEED + DISTRIBUTE — baseline into repo-template, bootstrap, and deploy sync#805
don-petry merged 6 commits into
mainfrom
dev-lead/issue-798-20260719-1945

Conversation

@don-petry

@don-petry don-petry commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Closes #798

Implemented by dev-lead agent. Please review.

Summary by CodeRabbit

  • New Features

    • Added automated seeding of a standardized secrets baseline to new repository .gitignore files.
    • Added synchronization that refreshes the shared baseline across repositories while preserving repository-specific ignore rules.
    • Added dry-run support to preview synchronization changes without creating pull requests.
  • Bug Fixes

    • Bootstrap progress and validation now include .gitignore baseline setup.
  • Tests

    • Added coverage for insertion, replacement, preservation, idempotency, negation rules, and dry-run behavior.

Copilot AI review requested due to automatic review settings July 19, 2026 20:03
@don-petry
don-petry requested a review from a team as a code owner July 19, 2026 20:03
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@coderabbitai

coderabbitai Bot commented Jul 19, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@don-petry, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 10 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 25003ed5-b555-4760-8522-c886117eb9a7

📥 Commits

Reviewing files that changed from the base of the PR and between db5c8d4 and 663289b.

📒 Files selected for processing (8)
  • .github/workflows/gitignore-baseline-tests.yml
  • scripts/bootstrap-new-repo.sh
  • scripts/lib/gitignore-baseline.sh
  • scripts/seed-repo-template.sh
  • scripts/sync-gitignore-baseline.sh
  • test/scripts/lib/gitignore-baseline.bats
  • test/scripts/sync-gitignore-baseline/dry-run.bats
  • tests/test_seed_repo_template_gitignore.bats
📝 Walkthrough

Walkthrough

Adds a reusable marker-delimited .gitignore baseline library, seeds it in repository templates and new-repository bootstrap, and synchronizes it across repositories through optional dry-run or PR-based updates while preserving L2 entries.

Changes

Gitignore baseline distribution

Layer / File(s) Summary
Baseline extraction and idempotent upsert
scripts/lib/gitignore-baseline.sh, test/scripts/lib/gitignore-baseline.bats
Defines marker constants, canonical block extraction, L1 replacement/insertion, L2 preservation, and tests for idempotency and negation handling.
Repository template baseline emission
.dev-lead/scripts/seed-repo-template.sh, tests/test_seed_repo_template_gitignore.bats
Emits the marker-wrapped baseline followed by template-specific ignore entries and validates ordering and required anchors.
New-repository bootstrap integration
scripts/bootstrap-new-repo.sh, tests/test_bootstrap_new_repo.bats
Adds the gitignore bootstrap step, dry-run output, cross-repository PR flow, progress updates, and failure-path coverage.
Fleet synchronization and dry-run behavior
scripts/sync-gitignore-baseline.sh, test/scripts/sync-gitignore-baseline/dry-run.bats
Fetches repository gitignore files, preserves L2 content, skips unchanged or exempt repositories, and creates synchronization PRs when needed.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related issues

  • Issue 797 — Provides the canonical marker-wrapped secrets baseline that this PR extracts, upserts, and distributes.

Possibly related PRs

Sequence Diagram(s)

sequenceDiagram
  participant SyncGitignoreBaseline
  participant GitHubContentsAPI
  participant GitignoreBaseline
  participant SDDeployViaPR
  SyncGitignoreBaseline->>GitHubContentsAPI: fetch repository .gitignore
  GitHubContentsAPI-->>SyncGitignoreBaseline: return encoded content or missing file
  SyncGitignoreBaseline->>GitignoreBaseline: insert or refresh L1 baseline
  SyncGitignoreBaseline->>SDDeployViaPR: create PR when content changes
Loading
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR covers bootstrap, sync helper, and tests, but the summary does not show the required repo-template/.gitignore or deploy-standard-workflows.sh updates. Add the marker-wrapped L1 block to repo-template/.gitignore and wire the deploy path to use upsert_gitignore_baseline() or the new sync helper.
Docstring Coverage ⚠️ Warning Docstring coverage is 57.14% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is specific and matches the main change: seeding and distributing the gitignore baseline across template, bootstrap, and sync paths.
Out of Scope Changes check ✅ Passed The changes stay focused on gitignore baseline seeding, synchronization, and tests, with no obvious unrelated code additions.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dev-lead/issue-798-20260719-1945

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a shared mechanism to seed and sync an organization-wide secrets baseline (L1 block) in .gitignore files across repositories, including bootstrapping updates, a fleet-wide sync script, and comprehensive BATS tests. The review feedback highlights several opportunities to improve script robustness, such as stripping carriage returns (\r) to prevent Windows CRLF line endings from breaking awk matches, utilizing global arrays and EXIT traps for reliable temporary file cleanup, refining jq filters to handle non-JSON API responses gracefully, and ensuring BATS tests use $BATS_TEST_TMPDIR for temporary directories.

Comment thread scripts/lib/gitignore-baseline.sh Outdated
Comment thread scripts/lib/gitignore-baseline.sh Outdated
Comment thread scripts/bootstrap-new-repo.sh Outdated
Comment thread scripts/sync-gitignore-baseline.sh Outdated
Comment thread scripts/sync-gitignore-baseline.sh
Comment thread scripts/sync-gitignore-baseline.sh
Comment thread test/scripts/sync-gitignore-baseline/dry-run.bats Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Implements org-wide seeding and distribution mechanics for the marker-wrapped .gitignore secrets baseline (L1), primarily by introducing a shared upsert_gitignore_baseline() library, wiring it into bootstrap-new-repo.sh, and adding a PR-based fleet sync script plus bats coverage.

Changes:

  • Add scripts/lib/gitignore-baseline.sh with gib_extract_baseline_block() and upsert_gitignore_baseline() to insert/refresh L1 while preserving per-repo L2.
  • Add scripts/sync-gitignore-baseline.sh to sweep repos and open PRs that insert/refresh the baseline.
  • Extend scripts/bootstrap-new-repo.sh with a new .gitignore seeding step and add/extend bats tests around the new behavior.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
tests/test_seed_repo_template_gitignore.bats New bats assertions intended to validate template .gitignore emission includes the marker-wrapped baseline and preserves L2 rules.
tests/test_bootstrap_new_repo.bats Extends bootstrap DRY_RUN coverage to include .gitignore baseline seeding.
test/scripts/sync-gitignore-baseline/dry-run.bats Adds dry-run coverage for the new fleet sync script behavior.
test/scripts/lib/gitignore-baseline.bats Adds unit tests for baseline extraction/upsert behaviors and negation discipline.
scripts/sync-gitignore-baseline.sh New PR-based fleet sweep to insert/refresh .gitignore baseline across repos.
scripts/lib/gitignore-baseline.sh New shared pure-text lib implementing marker block extraction and idempotent upsert.
scripts/bootstrap-new-repo.sh Adds .gitignore baseline seeding/refresh step (PR-based) to new repo bootstrap flow.

Comment thread tests/test_seed_repo_template_gitignore.bats
Comment thread tests/test_seed_repo_template_gitignore.bats Outdated
Comment thread scripts/lib/gitignore-baseline.sh
Comment thread scripts/sync-gitignore-baseline.sh
Comment thread scripts/sync-gitignore-baseline.sh
Comment thread scripts/sync-gitignore-baseline.sh
@donpetry-bot

Copy link
Copy Markdown
Contributor

CI checks on this PR are still running. Once they complete, re-mention @donpetry-bot to trigger a fresh review.

Posted by the donpetry-bot PR-review cascade.

@don-petry

Copy link
Copy Markdown
Contributor Author

Dev-Lead — review-changes (applied)

Changes committed and pushed.

@don-petry
don-petry enabled auto-merge (squash) July 19, 2026 20:31
@don-petry
don-petry disabled auto-merge July 19, 2026 20:31

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
tests/test_bootstrap_new_repo.bats (1)

40-63: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Missing coverage for the non-dry-run .gitignore write path.

Only DRY_RUN=true and the missing-canonical-file failure are tested for step_gitignore; the actual write branch (existing-content fetch + upsert_gitignore_baseline + _cross_repo_file_pr) has no test. Additionally, _stub_gh's default case returns a bare {"full_name":"stub/repo"} for any GET, so a gh api repos/.../contents/.gitignore --jq '.content' call would not yield a realistic base64 content payload — the stub would need a contents/.gitignore-aware branch (similar to the existing contents/personas special-case) before this path is testable.

Also applies to: 286-317

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_bootstrap_new_repo.bats` around lines 40 - 63, Extend tests for
step_gitignore to cover the non-dry-run existing-content path, including
fetching .gitignore content, calling upsert_gitignore_baseline, and invoking
_cross_repo_file_pr. Update _stub_gh with a contents/.gitignore-specific
response containing realistic base64 content, then assert the write path and
resulting behavior; retain the existing dry-run and missing-canonical-file
coverage.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@scripts/lib/gitignore-baseline.sh`:
- Around line 83-86: Normalize CRLF input before marker detection in
scripts/lib/gitignore-baseline.sh: in lines 83-86 sanitize existing with tr -d
'\r'; in lines 43-44 strip trailing carriage returns in the awk extraction; in
lines 52-53 sanitize content from standard input; and in lines 76-77 sanitize
the loaded block. Apply these changes to the existing read paths so all upsert
comparisons operate on LF-only text.

In `@scripts/sync-gitignore-baseline.sh`:
- Line 65: Update the help-output extraction command in the script’s --help
handling to include the complete header comment through line 26, so the GH_TOKEN
requirement text is displayed without truncation.
- Line 131: Update the printf format string assigned to body in the sync script
to remove the backslashes surrounding `.gitignore`, while preserving the literal
backticks and all other message text and substitutions.
- Around line 177-179: Update the repository loop invoking sync_repo so a
non-zero result from one repository is handled without triggering set -e
termination. Preserve recording or reporting the failure as appropriate, then
continue processing every remaining entry in REPOS.

---

Outside diff comments:
In `@tests/test_bootstrap_new_repo.bats`:
- Around line 40-63: Extend tests for step_gitignore to cover the non-dry-run
existing-content path, including fetching .gitignore content, calling
upsert_gitignore_baseline, and invoking _cross_repo_file_pr. Update _stub_gh
with a contents/.gitignore-specific response containing realistic base64
content, then assert the write path and resulting behavior; retain the existing
dry-run and missing-canonical-file coverage.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: b3fbefb0-84a4-449c-9e0f-202667b2b33d

📥 Commits

Reviewing files that changed from the base of the PR and between 3725615 and db5c8d4.

📒 Files selected for processing (8)
  • .dev-lead/scripts/seed-repo-template.sh
  • scripts/bootstrap-new-repo.sh
  • scripts/lib/gitignore-baseline.sh
  • scripts/sync-gitignore-baseline.sh
  • test/scripts/lib/gitignore-baseline.bats
  • test/scripts/sync-gitignore-baseline/dry-run.bats
  • tests/test_bootstrap_new_repo.bats
  • tests/test_seed_repo_template_gitignore.bats

Comment thread scripts/lib/gitignore-baseline.sh
Comment thread scripts/sync-gitignore-baseline.sh
Comment thread scripts/sync-gitignore-baseline.sh
Comment thread scripts/sync-gitignore-baseline.sh
@don-petry

Copy link
Copy Markdown
Contributor Author

@coderabbitai resolve

@don-petry

Copy link
Copy Markdown
Contributor Author

Dev-Lead — review-changes (applied)

Changes committed and pushed.

@don-petry
don-petry enabled auto-merge (squash) July 19, 2026 20:42
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jul 19, 2026
@coderabbitai

coderabbitai Bot commented Jul 19, 2026

Copy link
Copy Markdown
✅ Action performed

Comments resolved and changes approved.

@don-petry
don-petry disabled auto-merge July 19, 2026 20:42
@don-petry

Copy link
Copy Markdown
Contributor Author

Note

@don-petry I reviewed this PR and no code changes were needed, but it still has blocking checks or reviews (failing or cancelled checks, or changes-requested reviews), so I cannot mark it done yet. I'll re-check automatically.
Next attempt after: 2026-07-19T21:18:33Z

@don-petry
don-petry enabled auto-merge (squash) July 19, 2026 20:48
@don-petry
don-petry disabled auto-merge July 19, 2026 21:07
@don-petry

Copy link
Copy Markdown
Contributor Author

Dev-Lead — waiting on PR blockers (intent: review-changes)

PR: #805
No changes were committed, but the PR still has blocking checks or reviews (failing or cancelled checks, or changes-requested reviews). The retry cron will re-attempt automatically. Next attempt after: 2026-07-19T21:40:47Z

@don-petry
don-petry enabled auto-merge (squash) July 19, 2026 21:10
@don-petry don-petry added the dev-lead:hands-off Exclude this PR/issue from the dev-lead agent label Jul 19, 2026
… scripts/

The seed script was committed under .dev-lead/scripts/ — dev-lead's internal
working directory — so the deliverable lived in a git-ignored, ephemeral
location and the test invoked it from there. Move it to scripts/, adjust the
STANDARDS_DIR default depth (one level up now, not two) and the shellcheck
source directive, and point the bats test at the committed path.

Resolves the Copilot review threads on PR #805.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fa6TNhxEXj6WAKpaJLHvNK
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jul 19, 2026
…te.sh

The dedicated CI runner still referenced the old .dev-lead/scripts path in its
shellcheck target and PR/push path filters, so the relocation broke the gate.
Point all references at the committed scripts/ path.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fa6TNhxEXj6WAKpaJLHvNK
@sonarqubecloud

Copy link
Copy Markdown

@donpetry-bot donpetry-bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated review — APPROVED ✓

Risk: MEDIUM
Reviewed commit: 663289b6986aa107152e1fa7aa15f16ab541baea
Review mode: triage-approved (single reviewer)

Summary

Implements issue #798 (SEED + DISTRIBUTE .gitignore secrets baseline): a pure-text shared lib (upsert_gitignore_baseline / gib_extract_baseline_block), a PR-based bootstrap step (6/6), a fleet-wide sync sweep script, a repo-template generator, a dedicated hardened test workflow, and thorough bats coverage. Triage assessment confirmed; no blocking findings.

Linked issue analysis

Issue #798 deliverables are substantively addressed: (1) template seeding via scripts/seed-repo-template.sh --emit-baseline .gitignore, which emits the marker-wrapped L1 block on top and ecosystem L2 below END, with tests enforcing the STORY3 anchors (.env, *.pem, *.key) and the negation discipline (no L2 re-ignore of !.env.example); (2) distribution via a new step_gitignore in bootstrap-new-repo.sh (PR-based, never a direct push) and the dedicated sync-gitignore-baseline.sh sweep (the issue explicitly allowed a dedicated helper); (3) reusable, idempotent upsert_gitignore_baseline() in scripts/lib/, unit-tested for absent→insert, present→replace-in-place, L2 preservation, negation ordering, idempotency, and half-open marker refusal. Cross-file assumptions verified on the head SHA: sd_deploy_via_pr() exists in scripts/lib/standards-deploy.sh, _cross_repo_file_pr() exists in bootstrap, and the canonical /.gitignore carries the BEGIN/END markers.

Findings

No blocking issues. Verified: new workflow is least-privilege (permissions: contents: read), has a concurrency group and timeout, and pins actions/checkout to 9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0, confirmed via the GitHub API as the real v7.0.0 tag commit. The lib is pure text (no gh/network), refuses half-open marker states rather than duplicating markers, and preserves bytes it did not author. Non-blocking nits: (a) scripts/sync-gitignore-baseline.sh is mode 100644 while sibling scripts are 755 (always invoked via bash, so harmless); (b) branch-date formats differ between bootstrap (%Y-%m-%d) and sync (%Y%m%d) — cosmetic; (c) in sync_repo, temp files are appended to the EXIT-trap array and also removed inline, leaving stale array entries (harmless with rm -f); (d) step_gitignore sets/clears its own EXIT trap — safe today since bootstrap-new-repo.sh defines no other EXIT trap, but a future trap elsewhere in that script would be clobbered. Secret scan: the run_secret_scanning MCP tool is not available in this environment; the gitleaks CI check passed and no secret-like content appears in the diff (patterns only, no values).

CI status

All validating checks green on 663289b: Lint and bats (new Gitignore Baseline Tests workflow), ShellCheck, bats, CodeQL, Secret scan (gitleaks), Agent Security Scan, AgentShield, SonarCloud Quality Gate (0 new issues), npm audit. CANCELLED entries are superseded dev-lead dispatch/ci-relay automation runs, not validators. 0 unresolved review threads; CodeRabbit's final review state is APPROVED (earlier CHANGES_REQUESTED was addressed and dismissed through two dev-lead fix cycles).


Reviewed automatically by the PR-review agent (single-reviewer mode: fable 5). Reply if you need a human review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dev-lead:hands-off Exclude this PR/issue from the dev-lead agent

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Story: SEED + DISTRIBUTE — baseline into repo-template, bootstrap, and deploy sync

3 participants