fix(docker): INFRA-908 fail loudly on shared Dockerfile collisions - #199
fix(docker): INFRA-908 fail loudly on shared Dockerfile collisions#199amanda-orin wants to merge 4 commits into
Conversation
| "artifacts (%q and %q); goci cannot build distinct images from a "+ | ||
| "shared Dockerfile path. Give each app its own build.docker.file", | ||
| prev.app, name, dockerfileDisplayName(launch.Dockerfile), | ||
| prev.artifact, artifact, |
There was a problem hiding this comment.
minor - i think the artifacts are going to print as pointer addresses?
I've also noticed that circle ci will blank out custom fields in messages with *****. I'm not sure if this will display well in the circleci build. It might be fine to just drop printing the artifacts and hope the surround message around the blanked out bits is enough.
There was a problem hiding this comment.
Every value we interpolate here is a plain string. prev.app and name are string map keys, dockerfileDisplayName(...) returns a string, and artifact and prev.artifact are the ArtifactName string from AppConfig — all through %q, so they render as quoted names like "worker-a". I added TestBuildTargets_CollisionErrorMessage, which checks the exact rendered err.Error() to make sure we have test coverage for this.
On the CircleCI ***** masking — good flag, and it can genuinely happen since we set APP_NAME as a context var and it could appear in these names. I reworked the message to lead with the diagnosis, the Dockerfile path, and the fix, and moved the app/artifact names to the end:
shared Dockerfile path collision: %q is claimed by two apps that publish to different artifacts, so goci cannot build distinct images from it. Give each app its own build.docker.file. Conflicting apps: %q (artifact %q) and %q (artifact %q)
The leading part never contains APP_NAME, so even if masking blanks the trailing names the message is still fully actionable. TestBuildTargets_CollisionErrorMessage pins this exact output too.
Clever Coding Standards Agreement
Linear
INFRA-908
About
BuildTargetskeys its output map by Dockerfile path. When two apps publish to different artifacts but resolve to the same Dockerfile path (e.g. both omitbuild.docker.fileand land on the defaultDockerfile), the second app silently overwrote the first in the map — one image was never built or pushed, and which app "won" depended on Go's map iteration order.This is what happened with
lms-connect-ingest-google-users-dockerandlms-connect-update-google-mappings-docker: the ingest image went missing and deploys timed out, with no error surfaced anywhere in CI.This PR makes
BuildTargetsdetect the collision and return an error instead of silently dropping an image.gocisurfaces it as aValidationError(exit code 2) with a message naming both apps and telling the developer to give each app its ownbuild.docker.file. Apps that legitimately share an artifact name still dedupe to a single build, unchanged.Checklist
Testing
TestBuildTargets(internal/docker/targets_test.go) covering: distinct artifacts with distinct Dockerfile paths (each builds), distinct artifacts sharing the default Dockerfile path (errors), distinct artifacts sharing an explicit Dockerfile path (errors), apps sharing one artifact name (dedupes to a single build), lambda apps (no docker targets), and a single docker app.go test ./...green;go vet,gofmt,staticcheckclean on the changed package.