Skip to content

fix(org): exclude archived repos from drift detection - #77

Merged
robinbowes merged 2 commits into
mainfrom
fix/exclude-archived-from-drift-check
Aug 25, 2026
Merged

fix(org): exclude archived repos from drift detection#77
robinbowes merged 2 commits into
mainfrom
fix/exclude-archived-from-drift-check

Conversation

@robinbowes

Copy link
Copy Markdown
Contributor

What changed

modules/org/data.tf narrows the drift-detection query from
org:<org> fork:false to org:<org> fork:false archived:false. Archived repos
now drop out of both check "unmanaged_repos" and the non-fork admin-bypass
set.

Also updates the default_branch_ruleset_non_fork_bypass_actors description
and adds a CLAUDE.md convention, so neither describes the old query.

Why

yo61/python-template carried a permanent one-resource plan diff proposing to
remove a template block (owner = "BrianPugh"). It could never converge:

  • template_repository is immutable creation provenance. PATCH /repos/{owner}/{repo}
    accepts 26 body parameters and none of them is template_repository.
  • Provider v6.13.0 resourceGithubRepositoryRead (line 890) unconditionally
    sets template from repo.TemplateRepository; resourceGithubRepositoryUpdate
    never references the field, and ends by calling Read.

Applying it was tested: the diff returned on the very next plan.

Clearing the attribution therefore required recreating the repo. The original
was renamed to python-template-archived and archived rather than deleted,
which left a repo with no data file tripping unmanaged_repos on every plan —
the noise this PR removes.

Why not give the archived repo a data file

modules/github-repo manages github_repository_collaborators unconditionally,
and a minimal file (builtin_ruleset_names: []) would plan to delete the two
rulesets the repo still carries. GitHub rejects writes to archived repos, so
those calls fail at apply time. Managing an archived repo is not something the
module supports.

Verification

org:yo61 fork:false -> 28
org:yo61 fork:false archived:false -> 27
org:yo61 fork:false archived:true -> python-template-archived

task plan reports No changes. Your infrastructure matches the configuration.
with no unmanaged_repos warning.

The repo swap itself was applied separately: 3 added, 3 changed, 0 destroyed,
and needed no state surgery — resources keyed on repo name re-bound on refresh,
while the two rulesets and Pages (keyed on numeric ids) planned as ordinary
creates.

Trade-off

Archiving a managed repo out-of-band now drops it from drift detection silently
instead of flagging it. An archived repo is frozen by definition and its config
can no longer be applied, so there is nothing actionable to report. The reverse
direction is unaffected: its data file is still rendered, so state and config
keep agreeing. CLAUDE.md documents the trap — a managed repo that gets
archived will otherwise plan archived: true -> false.

Decision records

  • decisions/2026-08-25-exclude-archived-from-drift-detection.md
  • decisions/2026-08-25-python-template-recreate-to-drop-template-link.md

🤖 Generated with Claude Code

robinbowesand others added 2 commits August 25, 2026 18:41
The drift-detection query becomes `fork:false archived:false`, so
archived repos drop out of both `check "unmanaged_repos"` and the
non-fork admin-bypass set.
GitHub rejects writes to an archived repo, so a data file for one could
not be applied and a bypass on its ruleset would be inert. Reporting it
as unmanaged is noise the reader learns to skip, which is how a real
unmanaged repo would later go unnoticed.
Verified: `org:yo61 fork:false` returns 28, with `archived:false` 27,
and `archived:true` returns exactly python-template-archived. Plan is
"No changes" with no warning.
The data source keeps the name `non_fork` because
default_branch_ruleset_non_fork_bypass_actors is part of the module's
public interface; the comment records that the set is now narrower than
the name suggests.
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
GitHub stores template_repository as immutable creation provenance --
PATCH /repos/{owner}/{repo} has no such parameter -- and the provider
reads it back on every refresh, so the plan diff proposing to remove the
template block could never converge. Applying it was tested and the diff
returned on the next plan.
Recreating the repo was the only way to clear the attribution. Records
the sequence used, the alternatives that fix only the plan noise, and
what the archived original still holds.
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

@yo61-lastlightyo61-lastlightBot 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.

The PR narrows org drift detection to active non-fork repos, updates the bypass description, and records the python-template recreation rationale. I checked the changed Terraform paths and their consumers; the query/result contract remains consistent with the documented trade-off.

@robinbowes
robinbowes merged commit 886e94e into mainAug 25, 2026
2 checks passed
@robinbowes
robinbowes deleted the fix/exclude-archived-from-drift-check branch August 25, 2026 17:51
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@robinbowes