external modules: a pin on the remote's default branch name never advances past the clone-time commit #60

Open
opened 2026-09-02 10:12:15 +02:00 by julian · 0 comments
Owner

Found while checking the rev-parse guard in #40 against a running git, confirmed pre-existing by that PR's sixth review (same result on 4e8defb and on the branch head; --no-checkout neither causes nor changes it).

What happens

OPSDECK_EXTERNAL_MODULES=…/mod.git#main, where main is also the remote's default branch. git clone creates a local branch main; checkoutConfiguredRef tries the ref as given first, so checkout --detach main resolves to that local branch — and fetch --tags origin only ever moves origin/main. The local branch is never updated by anything, so every boot checks out the same commit the first clone landed on:

boot1 HEAD: 6168d0d  src: 6168d0d
boot2 via 'main':        HEAD=6168d0d  src=790e996   # stale
boot2 via 'origin/main': HEAD=790e996

The module never fails and nothing is logged — it simply runs the version it was first cloned at, forever, until the work tree is removed by hand or by a recovery. The unpinned case (ref empty) is unaffected: it goes through remoteDefaultBranch() and checks out origin/<default>.

Why it wasn't fixed in #40

That PR is six rounds deep on a different fault, and the fix has a semantics question of its own rather than being mechanical:

  • Prefer origin/<ref> first and it is correct for branches, but a branch shadows a tag of the same name — a deployment pinned to tag v2 on a repo that also has a branch v2 silently changes meaning.
  • Prefer the tag and it needs an explicit refs/tags/<ref> probe before the branch attempt, which is a third round-trip on the pre-Deno.serve path.

Either way the resolution order becomes part of the configured-ref contract and wants documenting in docs/modules.md, plus a test per shape: branch, tag, sha, and the branch-and-tag-of-one-name collision.

Note for whoever takes it: checkoutConfiguredRef now makes its second (origin/<ref>) attempt only when rev-parse --verify --quiet origin/<ref>^{commit} says there is such a branch, so the probe this fix needs is already half there.

Source: #40 (comment) ("Found on the way, not fixed here"), confirmed in the review at #40 round 6.

Found while checking the `rev-parse` guard in #40 against a running git, confirmed pre-existing by that PR's sixth review (same result on `4e8defb` and on the branch head; `--no-checkout` neither causes nor changes it). ## What happens `OPSDECK_EXTERNAL_MODULES=…/mod.git#main`, where `main` is also the remote's default branch. `git clone` creates a **local** branch `main`; `checkoutConfiguredRef` tries the ref as given first, so `checkout --detach main` resolves to that local branch — and `fetch --tags origin` only ever moves `origin/main`. The local branch is never updated by anything, so every boot checks out the same commit the first clone landed on: ``` boot1 HEAD: 6168d0d src: 6168d0d boot2 via 'main': HEAD=6168d0d src=790e996 # stale boot2 via 'origin/main': HEAD=790e996 ``` The module never fails and nothing is logged — it simply runs the version it was first cloned at, forever, until the work tree is removed by hand or by a recovery. The unpinned case (`ref` empty) is unaffected: it goes through `remoteDefaultBranch()` and checks out `origin/<default>`. ## Why it wasn't fixed in #40 That PR is six rounds deep on a different fault, and the fix has a semantics question of its own rather than being mechanical: - **Prefer `origin/<ref>` first** and it is correct for branches, but a branch shadows a *tag* of the same name — a deployment pinned to tag `v2` on a repo that also has a branch `v2` silently changes meaning. - **Prefer the tag** and it needs an explicit `refs/tags/<ref>` probe before the branch attempt, which is a third round-trip on the pre-`Deno.serve` path. Either way the resolution order becomes part of the configured-ref contract and wants documenting in `docs/modules.md`, plus a test per shape: branch, tag, sha, and the branch-and-tag-of-one-name collision. Note for whoever takes it: `checkoutConfiguredRef` now makes its second (`origin/<ref>`) attempt only when `rev-parse --verify --quiet origin/<ref>^{commit}` says there is such a branch, so the probe this fix needs is already half there. Source: https://git.imhof.cloud/OpsDeck/core/pulls/40#issuecomment-1186 ("Found on the way, not fixed here"), confirmed in the review at https://git.imhof.cloud/OpsDeck/core/pulls/40 round 6.
Sign in to join this conversation.
No labels
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
OpsDeck/core#60
No description provided.