Send .git without its config; correct shallow-clone and version comments
check / check (push) Waiting to run

.dockerignore lists .git/config, which holds the clone's remote URL and
any credential in it; the build stage is the final image, so it would
otherwise ship. git describe does not need it. The build-context test
asserts the entry, and the README says the image carries .git without
its config.

The README now says a shallow clone stamps a tag only when the cloned
commit itself carries one, and otherwise the short commit. The comment in
src/index.ts says a build reports the version script/build stamps into
dist/package.json, and package.json's own version only from source.

Model: opus-5-5
This commit is contained in:
2026-10-02 03:02:54 +00:00
parent eaf839442f
commit 1efb02acd1
4 changed files with 23 additions and 10 deletions
+4 -1
View File
@@ -3,7 +3,10 @@
# and dropping it would change what the lint phase's prettier check sees. # and dropping it would change what the lint phase's prettier check sees.
# #
# .git is deliberately NOT excluded: the build derives the version it stamps # .git is deliberately NOT excluded: the build derives the version it stamps
# from it (script/version). # from it (script/version). It is sent without its config, which holds the
# clone's remote URL and any credential in it, and which the build stage, the
# final image, would otherwise carry. git describe does not need it.
.git/config
# OS # OS
.DS_Store .DS_Store
+9 -7
View File
@@ -195,13 +195,15 @@ The build fails if the checkout has `.git` and the version still comes out
empty, `dev` or `unknown`: such a build could not be traced back to its commit. empty, `dev` or `unknown`: such a build could not be traced back to its commit.
`.dockerignore` therefore does not leave out `.git`, so any `docker build .` of `.dockerignore` therefore does not leave out `.git`, so any `docker build .` of
a clone stamps the commit it was built from; a shallow clone of one branch has a clone stamps the commit it was built from; a shallow clone stamps a tag only
no tags and stamps the short commit. `script/docker` (and so `make docker`) and when the cloned commit itself carries one, and otherwise the short commit. It
`script/cibuild` pass the version they resolve on the host, with `--dirty`, as leaves out `.git/config`, which holds the clone's remote URL and any credential
the build arg, which takes precedence. The image's in it, so the image carries `.git` without its config; `git describe` does not
`org.opencontainers.image.version` label carries that build arg only, so a build need that file. `script/docker` (and so `make docker`) and `script/cibuild` pass
given none leaves it empty. `make build-bin` bundles the built `dist/`, so the the version they resolve on the host, with `--dirty`, as the build arg, which
single binary reports the stamped version too. takes precedence. The image's `org.opencontainers.image.version` label carries
that build arg only, so a build given none leaves it empty. `make build-bin`
bundles the built `dist/`, so the single binary reports the stamped version too.
## Rationale ## Rationale
+4 -2
View File
@@ -1,5 +1,7 @@
// package.json is the one place the version is written. tsc copies it to // A build reports the version script/build stamps into dist/package.json;
// dist/package.json, so this path resolves from source and from dist/src/. // package.json's own version is reported only when running from source. tsc
// copies package.json to dist/package.json, so this path resolves from source
// and from dist/src/.
import pkg from "../package.json" with { type: "json" }; import pkg from "../package.json" with { type: "json" };
export const VERSION: string = pkg.version; export const VERSION: string = pkg.version;
+6
View File
@@ -54,6 +54,12 @@ describe(".dockerignore", () => {
expect(dockerignore).not.toContain(".git/"); expect(dockerignore).not.toContain(".git/");
}); });
// The build stage is the final image, so a .git/config sent in would
// ship the clone's remote URL and any credential in it.
it("sends .git without its config", () => {
expect(dockerignore).toContain(".git/config");
});
// BuildKit lets a `Dockerfile.dockerignore` shadow the root one; such a // BuildKit lets a `Dockerfile.dockerignore` shadow the root one; such a
// file would silently give the build a different, unreviewed context — // file would silently give the build a different, unreviewed context —
// and eslint's flat config does not ignore dot-directories, so a stray // and eslint's flat config does not ignore dot-directories, so a stray