feat(repo-settings): port per-repo settings module from .github-tofu#7
Merged
Merged
Conversation
Consolidates GitHub governance into this canonical repo so the same-day .github-tofu scaffold — which duplicated the org ruleset (collided on id 15555419) — can be retired before it ever applies. Ports only the repository-settings half of .github-tofu's nix-repo module: squash + rebase merges (no merge commit), auto-merge on, delete branch on merge, web commit signoff required, wiki off, Dependabot vulnerability alerts + security updates. The source module's per-repo rulesets are intentionally dropped — the org-level rulesets here already enforce signed commits, linear history, and Conventional Commits on every repo, so porting them would duplicate org-level coverage. Adapted to this repo's conventions: single org-scoped provider (no per-owner aliases — all seven nix-* repos now resolve to the org), no account login in config/*.yml (owner comes from the provider), inventory in config/repos.yml decoded via yamldecode, settings module under modules/repo-settings/. Secret scanning + push protection are scoped to PUBLIC repos only via a dynamic security_and_analysis block gated on visibility == public, so an apply never silently enables paid GitHub Advanced Security on a private repo. The source module hardcoded visibility=public and enabled these unconditionally. First apply reconciles existing repos via native Terraform import blocks (for_each over the inventory) instead of .github-tofu's import.sh. Cost impact: free. Secret scanning + push protection enabled on public repos only (free); private repos excluded from the security_and_analysis block, so no GHAS charge. All other settings are free on public and private repos. No Actions/Packages capacity allocated. Refs: #6 Assisted-by: Claude:claude-opus-4-8
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Mines the "gold" from
.github-tofubefore it is retired: ports its per-reposettings module into this canonical governance repo.
.github-tofuwas asame-day scaffold that duplicated the org-level ruleset (it collided on org
ruleset id
15555419, already owned here). Consolidating its useful half herelets
.github-tofube archived/deleted without losing the repo-settingsbaseline.
Ports only the repository-settings half of the source
nix-repomodule:The source module's per-repo
allruleset (signed commits) is intentionallynot ported — the org-level rulesets in
rulesets.tfalready enforce signedcommits, linear history, and Conventional Commits on every repo. Porting the
per-repo ruleset would duplicate org-level coverage.
How it matches this repo's conventions
owner (
nix_repo_jpe/nix_repo_dryvist) via aliased providers. All sevennix-* repos now resolve to the org (verified live), so they are managed by
the one
providers.tfprovider — no aliases, no per-repoowner.config/*.yml. Per AGENTS.md ("no account logins inconfig/*.yml"), the per-repoownerfield from the source is dropped; theowner comes from the provider.
config/repos.ymlcarries only the repo name(the governance subject),
visibility,description, andtopics.config/, decoded viayamldecode(file(...))into a localin the new topical file
repos.tf. Settings logic lives inmodules/repo-settings/.import {}blocks (for_eachover the inventory) replace thesource's
scripts/import.sh, so a first apply RECONCILES the existing reposinstead of trying to recreate them (which
prevent_destroywould block).Cost impact
Free. Secret scanning + secret-scanning push protection are enabled on
public repos only — free on public repos. The
security_and_analysisblockis emitted via a
dynamicblock gated onvisibility == "public", so theconfig can never silently enable paid GitHub Advanced Security (Secret
Protection) on a private repo; private repos are excluded from the block
entirely. All other managed settings (merge methods, auto-merge, branch
deletion, wiki, web-commit signoff, Dependabot alerts + security updates) are
free on public and private repos. No Actions/Packages capacity is allocated.
This corrects a latent cost bug in the source module, which hardcoded
visibility = "public"and enabled secret scanning unconditionally — thatwould have charged GHAS the moment a private repo entered the inventory.
Scope (first increment)
Inventory is the same nix- family*
.github-tofu/data/repos.yamlcovered,resolved to live visibility (all currently public):
nix-ainix-darwinnix-homenix-devenvnix-claude-codenix-pxe-bootstrapnix-ai-serverFollow-up: expand the inventory to every non-archived org repo (~38), per
the Phase 1 plan in the tracking issue. Intentionally out of scope here to keep
this increment reviewable.
Validation (local, no backend)
tofu fmt -check -recursive— cleantofu init -backend=false— successtofu validate— Success! The configuration is valid.tflint --recursive(root + module, with the repo's pre-commit--onlyset) — exit 0, no findings
tofu plan/applywere not run — they require the ORG_ADMIN token tierand the S3 backend.
Checkov suppressions (documented, per-resource)
Two Checkov GIT checks are skipped on
github_repository.thiswith inlinejustifications (visible in the diff), because both are false positives for this
governance model — not bypasses of real failures:
CKV_GIT_1("repository is Private") — these repos are intentionally public;the org cost policy depends on it (public = free secret scanning).
CKV2_GIT_1("branch protection associated") — branch protection is providedat the org level via
github_organization_rulesetinrulesets.tf, whichCheckov does not associate with the per-repo resource.
CI (
ci-gate.yml) does not run Checkov; these annotations are for the localpre-commit hook and reviewer transparency.
Operator must review
tofu planbefore applyThis is the first config in the repo that touches existing repos' settings
(not just org rulesets). On first apply the
import {}blocks adopt each repoplus its two Dependabot sub-resources into state, then reconcile settings. The
plan diff WILL show changes to live repos (merge methods, wiki, signoff,
Dependabot, secret scanning). Inspect the full
tofu planand confirm everydiff is intended before applying. Apply requires the ORG_ADMIN token tier.
Refs: #6
🤖 Generated with Claude Code