Skip to content

A public repo entry with a null template_source cannot receive its first commit #175

Description

@cpitzi

What happened

mitchella was added to repos.json with "template_source": null, because
its working tree already existed locally and scaffolding from repo-template
would have produced a conflicting initial commit. The apply created the repo,
and the repo could not then receive its first commit.

The deadlock is structural, not a one-off:

  1. ci/validate.py requires every public repo to have a required-checks.json
    entry: "'mitchella' is public in repos.json but has no required-checks.json
    entry — its ruleset would require nothing and auto-merge could not arm."
  2. The main ruleset therefore requires status checks from the moment the repo
    exists.
  3. A push to main is rejected with GH013 ... 2 of 2 required status checks are expected, because no check has ever run: there is no pull request to run
    one on, and no commit to open a pull request from.
  4. Branch protection on main also blocks renaming a branch into place
    ("delete the branch protection rule for main and try again"), and the
    Terraform token deliberately lacks delete_repo, so recreating is not
    available to the automation either.

template_source is what normally prevents this. A template-seeded repo gets
its initial commit server-side at creation, before any rule can apply, which is
why every other entry in repos.json sets it.

Why it is worth closing

Both rails that would have caught this are documented, and neither is
enforced:

  • terraform/README.md § Adding a repo to the fleet shows template_source
    pointing at repo-template in the example, but does not say it is load
    bearing or what happens without it.
  • fleet-ops/README.md already warns that a required context which never
    reports deadlocks a repo, and says to run the preflight before adding to
    required-checks.json. On a repo with no pull request history there is
    nothing for the preflight to check, so the warning is correct and the check
    cannot help.

The next person adding a repo from an existing local tree will reach the same
place, and the way out is not obvious.

Where modern practice points

Make the invalid combination unrepresentable rather than documented. A rule in
ci/validate.py is the cheapest option and matches how the other fleet
invariants are held:

  • Reject visibility: public with template_source: null for an entry that
    is not yet present live, with an error naming the consequence, in the style of
    the existing public-repo-needs-checks message.
  • Or, if a null template_source should stay available for the
    existing-local-tree case, document the escape hatch beside it in
    terraform/README.md.

What worked, for the record

The repo was recovered without mutating any enforced surface. The main
ruleset targets ~DEFAULT_BRANCH, so: add push triggers to the repo's
workflows, push a non-default branch to make both contexts report on the
commit, push main while the default branch still pointed elsewhere, set the
default back to main, and delete the scaffolding branches. The end state is
identical to a normally seeded repo. Branch protection was never deleted and no
live setting was changed by hand.

Next step

Decide between the validator rule and the documented escape hatch, then add
whichever is chosen. Context: #174 and the initial commits of
lentago/mitchella.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationREADMEs, CLAUDE.md, and other prose

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions