Skip to content

CreateRepo should wait for git-layer readiness; delete pool recycling machinery #6829

Description

@ggallen

Blocked by #6820. Closes #6701.

What happens

CreateRepo returns as soon as the GitHub API accepts the creation request. Callers that immediately perform git operations (create tree, commit, branch) hit eventual-consistency errors because the auto_init commit hasn't propagated:

  • 422 Tree SHA does not exist
  • 422 base_tree is not a valid tree oid
  • 409 Git Repository is empty
  • 404 Not Found

The current workaround — awaitCreation in ensure.go — polls GetRepo, which only proves API visibility, not git-layer readiness. The poll succeeds but the repo isn't actually usable yet.

4 behaviour test failures in a 2-day window (Aug 31) hit these errors, all during test setup on freshly created repos. See also #5671 (closed), #5774 (closed), #6701 (open, superseded by this issue).

What should happen

CreateRepo should not return until the repo is ready for git operations. Polling GetRef("heads/main") (or equivalent) after the create call confirms the auto_init commit and default branch ref have propagated. Once that succeeds, the repo is usable — git objects exist and permissions are settled.

Every existing CreateRepo caller immediately performs git operations on the result, so this benefits all call sites with no behavior change.

Cleanup

Once #6820 lands (ephemeral single-org repos with --per-repo-wif-repos "*" on the preview mint), the pool and recycling machinery becomes dead code. This is a significant simplification.

Pool recycling (already identified)

  • Delete repopool_external_mint.go — unused factory, bot-generated, never called
  • Delete resetRepo, awaitCreation, awaitDeletion, ensureRepoExists and related constants (resetMaxAttempts, resetRetryDelay)

Channel-based pool in composedDriver

With --per-repo-wif-repos "*" on the preview mint, repo names no longer need to be coordinated between the factory and the driver. Each repo is unique, created once, and deleted after its test. The pool pattern is unnecessary:

  • Remove names chan string, capacity field, Capacity() method
  • AllocateRepo generates a fresh bt-{uuid} name on the spot instead of pulling from a channel
  • DeallocateRepo no longer pushes names back to the channel — the repo is deleted, the name is never reused
  • Remove DefaultPoolSize, envPoolSize(), BEHAVIOUR_POOL_SIZE env var support
  • Remove buildEphemeralRepoList and the prefix parameter threading from factory → composed driver
  • If concurrency limiting is still needed, use a sync.Semaphore instead of a channel

Ensurer simplification

Each repo is unique and never reused, so caching and deduplication are unnecessary:

  • Remove ensured map and singleflight.Group from repoEnsurer
  • Remove InvalidateCache method and the ensurer interface's InvalidateCache contract
  • Collapse the ensurer interface into a simple function: CreateRepoinstallFullsendawaitWorkflowReady

Finalize cleanup

  • Simplify Finalize's lease reclamation — outstanding repos should be deleted, not pushed back to a pool
  • Mint teardown remains unchanged

Summary

The ensure flow simplifies from the current multi-step reset/create/validate/cache cycle to: CreateRepo (with git-readiness wait) → installFullsendawaitWorkflowReady. The composed driver becomes a thin wrapper around name generation, outstanding-repo tracking, and mint lifecycle.

Metadata

Metadata

Assignees

No one assigned

    Labels

    blockedBlocked by another issue or external dependencycomponent/e2eEnd-to-end testspriority/highSignificant impact, address soontype/bugConfirmed defect in existing behavior

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions