fix: re-pull the repo on every rebuild instead of reusing the stale clone
Some checks failed
CI / test (push) Has been cancelled

buildInstallation ran nixpacks against whatever was cloned at draft
creation time and never re-synced — every "rebuild" from the panel
silently rebuilt the same old commit forever, even after pushing new
commits. Confirmed repeatedly while iterating against a live repo
(had to git pull manually each time to actually pick up a fix).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-10-08 21:03:57 +02:00
parent 7b6e1b5855
commit f11a23fb00
2 changed files with 20 additions and 0 deletions

View File

@@ -2,6 +2,16 @@
Recurring mistakes and gotchas found while building and operating this project, and how to avoid or work around them. Recurring mistakes and gotchas found while building and operating this project, and how to avoid or work around them.
## "Rebuild" must re-clone, not reuse the original checkout
`buildInstallation` used to run `nixpacks build` directly against the repo directory left over
from `createDraftInstallation`'s one-time clone — it never re-pulled. Every "rebuild" from the
panel silently rebuilt the exact same old commit forever, even after pushing new commits to the
repo; it looked like the rebuild worked (new image, new timestamp) but the code never changed.
Found repeatedly while iterating on `nixpacks.toml` fixes against a live repo. Fixed by having
`buildInstallation` call `cloneOrUpdateRepo` again (same as the initial clone) before every
build.
## A pinned external image's *contents* can still change ## A pinned external image's *contents* can still change
The Dockerfile pinned `ghcr.io/railwayapp/nixpacks:1.41.0` and copied `/usr/bin/nixpacks` out The Dockerfile pinned `ghcr.io/railwayapp/nixpacks:1.41.0` and copied `/usr/bin/nixpacks` out

View File

@@ -69,6 +69,16 @@ export async function buildInstallation(id: string): Promise<Installation> {
if (!installation) throw new Error("installation not found"); if (!installation) throw new Error("installation not found");
updateInstallation(id, { status: "building", statusDetail: null }); updateInstallation(id, { status: "building", statusDetail: null });
// The clone on disk is otherwise only ever made once, at draft creation — without this,
// every "rebuild" silently reused that same stale checkout forever, never picking up new
// commits pushed to the repo afterwards.
try {
await cloneOrUpdateRepo(installation.slug, installation.repoUrl, installation.gitRef);
} catch (err) {
return updateInstallation(id, { status: "error", statusDetail: `git pull failed: ${(err as Error).message}` });
}
const imageTag = `mcpmgr/${installation.slug}:latest`; const imageTag = `mcpmgr/${installation.slug}:latest`;
const previousImageId = installation.imageTag ? await getImageId(installation.imageTag) : undefined; const previousImageId = installation.imageTag ? await getImageId(installation.imageTag) : undefined;