Compare commits
1 Commits
3a218497b8
...
61448b0c4e
| Author | SHA1 | Date | |
|---|---|---|---|
| 61448b0c4e |
@@ -10,10 +10,7 @@
|
|||||||
# context root. A host-built binary is the usual case, and it must be
|
# context root. A host-built binary is the usual case, and it must be
|
||||||
# written anchored: `/myapp`, never `**/myapp`. The prefixed form also
|
# written anchored: `/myapp`, never `**/myapp`. The prefixed form also
|
||||||
# matches `cmd/myapp/`, which deletes the package directory from the
|
# matches `cmd/myapp/`, which deletes the package directory from the
|
||||||
# context. In-repo agent scratch is the other case, for the same reason
|
# context. In-repo agent scratch is the other case, for the same reason.
|
||||||
# — with the caveat recorded at that entry: anchoring is exact only
|
|
||||||
# where agents run at the repo root, and a repo where they do not must
|
|
||||||
# add its own entries.
|
|
||||||
#
|
#
|
||||||
# Matching is case-sensitive, so `**/*.key` does not match
|
# Matching is case-sensitive, so `**/*.key` does not match
|
||||||
# `certs/SERVER.KEY`, which is reachable on the case-insensitive
|
# `certs/SERVER.KEY`, which is reachable on the case-insensitive
|
||||||
@@ -41,24 +38,12 @@
|
|||||||
# `--build-arg VERSION=...`; see the version rule in REPO_POLICIES.md.
|
# `--build-arg VERSION=...`; see the version rule in REPO_POLICIES.md.
|
||||||
.git
|
.git
|
||||||
|
|
||||||
# In-repo agent scratch: a directory holding a full additional checkout
|
# In-repo agent scratch: one directory at the context root, holding a
|
||||||
# of the repo for each in-flight agent. Anchored because it occurs
|
# full additional checkout of the repo for each in-flight agent. Written
|
||||||
# exactly once *where agents run at the repo root*, which is the
|
# anchored because it occurs exactly once — the `**/` form would also
|
||||||
# convention this file assumes; the `**/` form would also match any
|
# match a nested directory of that name. Not case-folded, unlike the
|
||||||
# nested directory of that name and delete it from the build.
|
# secret patterns below: tooling creates this in exactly one spelling,
|
||||||
#
|
# and a miss costs build-context bloat rather than exposure.
|
||||||
# KNOWN GAP, and it is not hypothetical: the directory is created in the
|
|
||||||
# agent's working directory. If agents in this repo run in
|
|
||||||
# subdirectories — a monorepo with a per-service agent, say — then
|
|
||||||
# `services/api/.claude/` is NOT excluded by the line below and still
|
|
||||||
# reaches the build context and the image, which is the exposure this
|
|
||||||
# entry exists to close. A repo in that shape adds its own anchored
|
|
||||||
# entries (`/services/api/.claude`), or `**/.claude` after confirming no
|
|
||||||
# legitimately named nested directory would be caught.
|
|
||||||
#
|
|
||||||
# Not case-folded, unlike the secret patterns below: tooling creates
|
|
||||||
# this directory in exactly one spelling, so a folded pattern would add
|
|
||||||
# no coverage.
|
|
||||||
.claude
|
.claude
|
||||||
|
|
||||||
# Environment files. `*.env` covers both the bare `.env` name (`*` matches
|
# Environment files. `*.env` covers both the bare `.env` name (`*` matches
|
||||||
|
|||||||
35
TODO.md
35
TODO.md
@@ -27,26 +27,21 @@ fmt-check, and commit.
|
|||||||
reaching the image: another session's unreviewed, sometimes uncommitted work,
|
reaching the image: another session's unreviewed, sometimes uncommitted work,
|
||||||
inflating the context by a multiple of the repo and invalidating `COPY` for
|
inflating the context by a multiple of the repo and invalidating `COPY` for
|
||||||
reasons unrelated to the repo's own content. The `.dockerignore` entry is
|
reasons unrelated to the repo's own content. The `.dockerignore` entry is
|
||||||
root-anchored, because the directory occurs exactly once where agents run at
|
root-anchored, because the directory occurs exactly once and the `**/` form
|
||||||
the repo root and the `**/` form additionally deletes any nested directory of
|
additionally deletes any nested directory of that name; the `.gitignore` entry
|
||||||
that name — with the residual gap that follows from anchoring (a monorepo
|
is unanchored, because `.gitignore` patterns already match at every depth, and
|
||||||
running agents in subdirectories still ships `services/api/.claude/`) stated
|
each file is written to its own semantics rather than derived from the other.
|
||||||
in the canonical `.dockerignore`, the policy and the existing-repo checklist,
|
Also closed the consequence that ships broken silently: excluding `.git` means
|
||||||
since consuming repos receive the files rather than the tracker; the
|
`git describe` cannot run in any build stage and yields an empty version
|
||||||
`.gitignore` entry is unanchored, because `.gitignore` patterns already match
|
without erroring, so `script/docker` and `script/cibuild` now compute the
|
||||||
at every depth, and each file is written to its own semantics rather than
|
version on the host and pass `--build-arg VERSION`, and `REPO_POLICIES.md`
|
||||||
derived from the other. Also closed the consequence that ships broken
|
states where `VERSION` comes from instead of leaving the reader to fill the
|
||||||
silently: excluding `.git` means `git describe` cannot run in any build stage
|
gap with `git describe` inside the build. The two Go documents that carry the
|
||||||
and yields an empty version without erroring, so `script/docker` and
|
`GOLDFLAGS` pattern were corrected in the same pass, from `:=` to `?=`, since
|
||||||
`script/cibuild` now compute the version on the host and pass
|
a `$(shell git describe)` evaluated inside a build stage is exactly the empty
|
||||||
`--build-arg VERSION`, and `REPO_POLICIES.md` states where `VERSION` comes
|
version this closes. Verified by enumerating a probe image before, after, and
|
||||||
from instead of leaving the reader to fill the gap with `git describe` inside
|
against the `**/`-prefixed form, with a positive control and the `CHECK_EPOCH`
|
||||||
the build. The two Go documents that carry the `GOLDFLAGS` pattern were
|
cache verification re-run under the changed build context.
|
||||||
corrected in the same pass, from `:=` to `?=`, since a `$(shell git describe)`
|
|
||||||
evaluated inside a build stage is exactly the empty version this closes.
|
|
||||||
Verified by enumerating a probe image before, after, and against the
|
|
||||||
`**/`-prefixed form, with a positive control and the `CHECK_EPOCH` cache
|
|
||||||
verification re-run under the changed build context.
|
|
||||||
- 2026-08-09: Closed the secret exposure in the canonical `.dockerignore`: a
|
- 2026-08-09: Closed the secret exposure in the canonical `.dockerignore`: a
|
||||||
developer's local `.env`, `*.pem` or `*.key` was reaching the Docker build
|
developer's local `.env`, `*.pem` or `*.key` was reaching the Docker build
|
||||||
context under `COPY . .`, invisible to every git-based check because
|
context under `COPY . .`, invisible to every git-based check because
|
||||||
|
|||||||
@@ -49,19 +49,13 @@ last_modified: 2026-08-09
|
|||||||
```
|
```
|
||||||
|
|
||||||
```make
|
```make
|
||||||
# ?= rather than := because this `$(shell git describe ...)` is only
|
# ?= so a Docker build can supply the value. `.dockerignore` excludes
|
||||||
# correct on the host. `.dockerignore` excludes `.git`, so evaluated
|
# `.git`, so inside a build stage `$(shell git describe ...)` expands to
|
||||||
# inside a build stage it expands to the empty string without failing
|
# the empty string without failing and the binary reports no version at
|
||||||
# and the binary reports no version at all. The version is computed on
|
# all. The Dockerfile declares `ARG VERSION` in the stage that compiles,
|
||||||
# the host by `script/docker` / `script/cibuild` and passed with
|
# which puts it in the environment where this `?=` defers to it, and
|
||||||
# `--build-arg VERSION=...`. If this repo's Dockerfile compiles by
|
# `script/docker` / `script/cibuild` compute it on the host. See the
|
||||||
# invoking make (`RUN make build`), `ARG VERSION` in that stage puts the
|
# git-describe rule in REPO_POLICIES.md.
|
||||||
# value in the environment and `?=` defers to it. The canonical Go
|
|
||||||
# template in REPO_POLICIES.md instead runs `go build` directly with
|
|
||||||
# `-ldflags "... -X main.Version=${VERSION}"`, so there this Makefile is
|
|
||||||
# a host-only path — but it is still `?=`, because a repo that later
|
|
||||||
# moves the build behind make must not silently start shipping an empty
|
|
||||||
# version. See the git-describe rule in REPO_POLICIES.md.
|
|
||||||
VERSION ?= $(shell git describe --always --dirty)
|
VERSION ?= $(shell git describe --always --dirty)
|
||||||
BUILDARCH := $(shell uname -m)
|
BUILDARCH := $(shell uname -m)
|
||||||
|
|
||||||
|
|||||||
@@ -52,15 +52,6 @@ with your task.
|
|||||||
the context by a multiple of it and can copy another session's unreviewed
|
the context by a multiple of it and can copy another session's unreviewed
|
||||||
work into an image layer. Confirm by enumerating the image, not by reading
|
work into an image layer. Confirm by enumerating the image, not by reading
|
||||||
the file — `.gitignore` hides these from `git status` too.
|
the file — `.gitignore` hides these from `git status` too.
|
||||||
- [ ] **Do agents in this repo run anywhere other than the repo root?** The
|
|
||||||
scratch directory is created in the agent's working directory, so the
|
|
||||||
canonical anchored entry misses `services/api/.claude/` in a monorepo with
|
|
||||||
a per-service agent — it still reaches the build context and the image. An
|
|
||||||
existing repo is where such a layout already exists, so check it here
|
|
||||||
rather than assuming the canonical entry covers you: add anchored entries
|
|
||||||
for the subdirectories that have one (`/services/api/.claude`), or
|
|
||||||
`**/.claude` once you have confirmed no legitimately named nested
|
|
||||||
directory would be caught.
|
|
||||||
- [ ] If the repo embeds a version in a binary, that version is computed on the
|
- [ ] If the repo embeds a version in a binary, that version is computed on the
|
||||||
host and passed with `--build-arg VERSION=...` by `script/docker` and
|
host and passed with `--build-arg VERSION=...` by `script/docker` and
|
||||||
`script/cibuild`. No stage calls `git describe`: `.dockerignore` excludes
|
`script/cibuild`. No stage calls `git describe`: `.dockerignore` excludes
|
||||||
|
|||||||
@@ -991,13 +991,11 @@ func main() {
|
|||||||
Use ldflags to inject version information at build time:
|
Use ldflags to inject version information at build time:
|
||||||
|
|
||||||
```makefile
|
```makefile
|
||||||
# ?= rather than := because this `$(shell git describe ...)` is only correct
|
# ?= so a Docker build can supply the value. `.dockerignore` excludes `.git`,
|
||||||
# on the host: `.dockerignore` excludes `.git`, so evaluated inside a build
|
# so inside a build stage `$(shell git describe ...)` expands to the empty
|
||||||
# stage it expands to the empty string without failing and the binary reports
|
# string without failing and the binary reports no version. The Dockerfile
|
||||||
# no version. The version is computed on the host by `script/docker` /
|
# declares `ARG VERSION` in the stage that compiles, and `script/docker` /
|
||||||
# `script/cibuild` and passed with `--build-arg VERSION=...`; where the build
|
# `script/cibuild` compute it on the host — see REPO_POLICIES.md.
|
||||||
# stage invokes make, `ARG VERSION` puts it in the environment and `?=` defers
|
|
||||||
# to it. See the git-describe rule in REPO_POLICIES.md.
|
|
||||||
VERSION ?= $(shell git describe --tags --always)
|
VERSION ?= $(shell git describe --tags --always)
|
||||||
BUILDARCH := $(shell go env GOARCH)
|
BUILDARCH := $(shell go env GOARCH)
|
||||||
|
|
||||||
|
|||||||
@@ -64,10 +64,7 @@ Template files can be fetched from:
|
|||||||
the context root, so the copied form leaves `config/.env` in the build
|
the context root, so the copied form leaves `config/.env` in the build
|
||||||
context while reading as solved. See the `.dockerignore` rule in
|
context while reading as solved. See the `.dockerignore` rule in
|
||||||
`REPO_POLICIES.md`. The canonical file's `.claude` entry is anchored for
|
`REPO_POLICIES.md`. The canonical file's `.claude` entry is anchored for
|
||||||
the same reason as a repo-root binary; leave it that way, but note it only
|
the same reason as a repo-root binary; leave it that way.
|
||||||
covers agents running at the repo root — if this repo will run them in
|
|
||||||
subdirectories, `services/api/.claude/` is not excluded and needs its own
|
|
||||||
anchored entry.
|
|
||||||
- If the image embeds a version in a binary, the version is computed on the
|
- If the image embeds a version in a binary, the version is computed on the
|
||||||
host and passed with `--build-arg VERSION=...`. `ARG VERSION=dev` is
|
host and passed with `--build-arg VERSION=...`. `ARG VERSION=dev` is
|
||||||
declared in the stage that compiles, and **no stage calls `git describe`**
|
declared in the stage that compiles, and **no stage calls `git describe`**
|
||||||
@@ -116,30 +113,20 @@ are thin shims calling them. Model scripts:
|
|||||||
- [ ] `script/projectname` — outputs the project name (used by `script/docker`
|
- [ ] `script/projectname` — outputs the project name (used by `script/docker`
|
||||||
for the image tag)
|
for the image tag)
|
||||||
- [ ] `script/docker` / `make docker` — builds Docker image, tagged via
|
- [ ] `script/docker` / `make docker` — builds Docker image, tagged via
|
||||||
`script/projectname` (byte-identical across repos); carries the same three
|
`script/projectname` (byte-identical across repos); assigns
|
||||||
version lines as `script/cibuild` below, and passes
|
`epoch="$(date +%s%N)$$"` and the `git describe` version on their own
|
||||||
`--build-arg CHECK_EPOCH="$epoch"` and `--build-arg VERSION="$version"`
|
lines, and passes `--build-arg CHECK_EPOCH="$epoch"` and
|
||||||
- [ ] `script/cibuild` — cd to repo root, then, each on its own line:
|
`--build-arg VERSION="$version"`
|
||||||
|
- [ ] `script/cibuild` — cd to repo root, assign `epoch="$(date +%s%N)$$"` and
|
||||||
```sh
|
`version="$(git describe --tags --always --dirty 2>/dev/null || echo unknown)"`
|
||||||
epoch="$(date +%s%N)$$"
|
on their own lines, then run
|
||||||
version="$(git describe --tags --always --dirty 2>/dev/null || true)"
|
`docker build --build-arg CHECK_EPOCH="$epoch" --build-arg VERSION="$version" .`
|
||||||
[ -n "$version" ] || version="unknown"
|
(what CI runs). Both build args are mandatory, and both assignments must
|
||||||
docker build \
|
be on their own line: a failing command substitution inside an argument
|
||||||
--build-arg CHECK_EPOCH="$epoch" \
|
does not trip `set -e`, so the inline form degrades silently to an empty
|
||||||
--build-arg VERSION="$version" \
|
constant. See the `CHECK_EPOCH` and git-describe rules in
|
||||||
.
|
`REPO_POLICIES.md` for why each element is load-bearing. A bare
|
||||||
```
|
`docker build .` fails closed by design.
|
||||||
|
|
||||||
(what CI runs). Both build args are mandatory, and both assignments must be
|
|
||||||
on their own line: a failing command substitution inside an argument does
|
|
||||||
not trip `set -e`, so the inline form degrades silently to an empty
|
|
||||||
constant. The `[ -n "$version" ]` line is a live check that fires on an
|
|
||||||
export with no `.git` and on a repo with no commits — keep it, and do not
|
|
||||||
collapse it into `|| echo unknown`, which makes it unreachable. See the
|
|
||||||
`CHECK_EPOCH` and git-describe rules in `REPO_POLICIES.md` for why each
|
|
||||||
element is load-bearing. A bare `docker build .` fails closed by design.
|
|
||||||
|
|
||||||
- [ ] `script/precommit` — called by the pre-commit hook; runs `script/check`
|
- [ ] `script/precommit` — called by the pre-commit hook; runs `script/check`
|
||||||
- [ ] `script/install-precommit` — installs the pre-commit hook that runs
|
- [ ] `script/install-precommit` — installs the pre-commit hook that runs
|
||||||
`script/precommit`
|
`script/precommit`
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ style conventions are in separate documents:
|
|||||||
|
|
||||||
```sh
|
```sh
|
||||||
epoch="$(date +%s%N)$$"
|
epoch="$(date +%s%N)$$"
|
||||||
version="$(git describe --tags --always --dirty 2>/dev/null || true)"
|
version="$(git describe --tags --always --dirty 2>/dev/null || echo unknown)"
|
||||||
[ -n "$version" ] || version="unknown"
|
[ -n "$version" ] || version="unknown"
|
||||||
docker build \
|
docker build \
|
||||||
--build-arg CHECK_EPOCH="$epoch" \
|
--build-arg CHECK_EPOCH="$epoch" \
|
||||||
@@ -391,23 +391,10 @@ style conventions are in separate documents:
|
|||||||
reasons that have nothing to do with the repo's own content. In `.gitignore`
|
reasons that have nothing to do with the repo's own content. In `.gitignore`
|
||||||
the entry is `.claude/`, unanchored, which already matches at every depth. In
|
the entry is `.claude/`, unanchored, which already matches at every depth. In
|
||||||
`.dockerignore` it is `.claude`, anchored and with **no** `**/` prefix: the
|
`.dockerignore` it is `.claude`, anchored and with **no** `**/` prefix: the
|
||||||
directory occurs exactly once **where agents run at the repo root**, and the
|
directory occurs exactly once, at the context root, and the prefixed form
|
||||||
prefixed form would also match any nested directory of that name and delete it
|
would also match any nested directory of that name. It is not case-folded the
|
||||||
from the build. It is not case-folded the way the secret patterns are, because
|
way the secret patterns are, because tooling creates it in exactly one
|
||||||
tooling creates it in exactly one spelling, so a folded pattern would add no
|
spelling and a miss costs context bloat rather than exposure.
|
||||||
coverage.
|
|
||||||
|
|
||||||
**Known gap that comes with the anchored form.** The directory is created in
|
|
||||||
the agent's working directory, so the "exactly once, at the root" premise is
|
|
||||||
a property of how agents are run and not of the tooling. Where agents run in
|
|
||||||
subdirectories — a monorepo with a per-service agent is the ordinary case —
|
|
||||||
`services/api/.claude/` is **not** excluded by the canonical entry and still
|
|
||||||
reaches the build context and the image, which is the exposure the entry
|
|
||||||
exists to close. A repo in that shape adds its own anchored entries
|
|
||||||
(`/services/api/.claude`), or `**/.claude` once it has confirmed no
|
|
||||||
legitimately named nested directory would be caught. This is stated in the
|
|
||||||
canonical `.dockerignore` itself, since that file is what consuming repos
|
|
||||||
receive.
|
|
||||||
|
|
||||||
- **`.dockerignore` matching is case-sensitive, so cover capitalisation with
|
- **`.dockerignore` matching is case-sensitive, so cover capitalisation with
|
||||||
character classes rather than by doubling patterns.** `**/*.key` does not
|
character classes rather than by doubling patterns.** `**/*.key` does not
|
||||||
@@ -451,7 +438,7 @@ style conventions are in separate documents:
|
|||||||
# Assign on its own line: a failing command substitution inside an
|
# Assign on its own line: a failing command substitution inside an
|
||||||
# argument does not trip `set -e`, so the inline form degrades to an
|
# argument does not trip `set -e`, so the inline form degrades to an
|
||||||
# empty constant — the same silent-empty failure this rule is about.
|
# empty constant — the same silent-empty failure this rule is about.
|
||||||
version="$(git describe --tags --always --dirty 2>/dev/null || true)"
|
version="$(git describe --tags --always --dirty 2>/dev/null || echo unknown)"
|
||||||
[ -n "$version" ] || version="unknown"
|
[ -n "$version" ] || version="unknown"
|
||||||
docker build \
|
docker build \
|
||||||
--build-arg CHECK_EPOCH="$epoch" \
|
--build-arg CHECK_EPOCH="$epoch" \
|
||||||
@@ -460,21 +447,14 @@ style conventions are in separate documents:
|
|||||||
```
|
```
|
||||||
|
|
||||||
`--always` makes an untagged repo yield the abbreviated commit hash instead
|
`--always` makes an untagged repo yield the abbreviated commit hash instead
|
||||||
of failing. `|| true` keeps a failing `git describe` from tripping `set -e`
|
of failing, and the `unknown` fallback covers a build from an export with no
|
||||||
and leaves the value empty, so the `[ -n "$version" ]` line is the single
|
`.git` at all. Both are non-empty by construction: an empty version reads as
|
||||||
place the fallback is applied — and it is a **live** check, not defence in
|
a successful one, which is precisely the failure being closed. The
|
||||||
depth: it fires on a build from an export with no `.git`, and on a
|
Dockerfile's side is `ARG VERSION=dev` in the stage that compiles, declared
|
||||||
repository with no commits yet. Do not fold the fallback into the
|
there and not inherited, because `ARG` is stage-scoped exactly as
|
||||||
substitution as `|| echo unknown`; that makes the guard unreachable, and a
|
`CHECK_EPOCH` is. Passing `VERSION` to a repo whose Dockerfile declares no
|
||||||
guard that cannot fire is indistinguishable from one that works to everyone
|
such `ARG` is silently ignored by BuildKit and costs nothing, which is why
|
||||||
who copies it. The result is non-empty by construction either way, which is
|
the scripts stay byte-identical rather than growing a per-repo variant.
|
||||||
the point: an empty version reads as a successful one, while `unknown` is
|
|
||||||
visibly wrong. The Dockerfile's side is `ARG VERSION=dev` in the stage that
|
|
||||||
compiles, declared there and not inherited, because `ARG` is stage-scoped
|
|
||||||
exactly as `CHECK_EPOCH` is. Passing `VERSION` to a repo whose Dockerfile
|
|
||||||
declares no such `ARG` is silently ignored by BuildKit and costs nothing,
|
|
||||||
which is why the scripts stay byte-identical rather than growing a per-repo
|
|
||||||
variant.
|
|
||||||
|
|
||||||
One consequence for CI: the standard checkout action clones shallow and
|
One consequence for CI: the standard checkout action clones shallow and
|
||||||
fetches no tags, so `git describe --tags` there falls back to a bare commit
|
fetches no tags, so `git describe --tags` there falls back to a bare commit
|
||||||
|
|||||||
@@ -17,12 +17,10 @@ main() {
|
|||||||
# VERSION must be computed here, on the host: .dockerignore excludes
|
# VERSION must be computed here, on the host: .dockerignore excludes
|
||||||
# .git, so `git describe` cannot run in any build stage and fails
|
# .git, so `git describe` cannot run in any build stage and fails
|
||||||
# quietly there rather than erroring. Same own-line discipline as the
|
# quietly there rather than erroring. Same own-line discipline as the
|
||||||
# epoch. `|| true` keeps a failing describe from tripping `set -e`
|
# epoch, plus a non-empty fallback, so a repo built from an export
|
||||||
# and leaves the value empty; the guard below is then the single
|
# with no .git reports `unknown` rather than an empty version that
|
||||||
# place the fallback is applied, and it does fire — on an export with
|
# reads as a successful one.
|
||||||
# no .git, or a repo with no commits yet. `unknown` is visibly wrong
|
version="$(git describe --tags --always --dirty 2>/dev/null || echo unknown)"
|
||||||
# in a binary in a way that an empty version is not.
|
|
||||||
version="$(git describe --tags --always --dirty 2>/dev/null || true)"
|
|
||||||
[ -n "$version" ] || version="unknown"
|
[ -n "$version" ] || version="unknown"
|
||||||
docker build \
|
docker build \
|
||||||
--build-arg CHECK_EPOCH="$epoch" \
|
--build-arg CHECK_EPOCH="$epoch" \
|
||||||
|
|||||||
@@ -19,12 +19,10 @@ main() {
|
|||||||
# VERSION must be computed here, on the host: .dockerignore excludes
|
# VERSION must be computed here, on the host: .dockerignore excludes
|
||||||
# .git, so `git describe` cannot run in any build stage and fails
|
# .git, so `git describe` cannot run in any build stage and fails
|
||||||
# quietly there rather than erroring. Same own-line discipline as the
|
# quietly there rather than erroring. Same own-line discipline as the
|
||||||
# epoch. `|| true` keeps a failing describe from tripping `set -e`
|
# epoch, plus a non-empty fallback, so a repo built from an export
|
||||||
# and leaves the value empty; the guard below is then the single
|
# with no .git reports `unknown` rather than an empty version that
|
||||||
# place the fallback is applied, and it does fire — on an export with
|
# reads as a successful one.
|
||||||
# no .git, or a repo with no commits yet. `unknown` is visibly wrong
|
version="$(git describe --tags --always --dirty 2>/dev/null || echo unknown)"
|
||||||
# in a binary in a way that an empty version is not.
|
|
||||||
version="$(git describe --tags --always --dirty 2>/dev/null || true)"
|
|
||||||
[ -n "$version" ] || version="unknown"
|
[ -n "$version" ] || version="unknown"
|
||||||
docker build \
|
docker build \
|
||||||
--build-arg CHECK_EPOCH="$epoch" \
|
--build-arg CHECK_EPOCH="$epoch" \
|
||||||
|
|||||||
Reference in New Issue
Block a user