upaas builds an app by uploading its clone as a tar (archive.TarWithOptions(opts.ContextDir, &archive.TarOptions{}) in performBuild, internal/docker/client.go), with no exclude patterns. Docker does not filter a tar context through the app's .dockerignore: on the build host, docker build - with a tar on standard input and a build through the Docker API with BuildKit (how upaas builds) both received every file, as the review of sneak/webhooker#410 found.
So an upaas build sees a different context from docker build . on the same clone: everything an app's .dockerignore leaves out reaches the build. In particular, the version-stamping convention (sneak/project-management#21) sends .git but leaves out .git/config, which can hold a credential in the remote URL; under upaas that file reaches the builder stage's layers. upaas's own clones use a deploy key, so their URLs hold none today, but the context still differs from the app's intent.
Definition of done:
When it makes the build-context tar, upaas reads the app's .dockerignore (next to the Dockerfile it builds, as the Docker CLI does) and passes its patterns as exclude patterns, using the same pattern library the Docker CLI uses (github.com/moby/patternmatcher and its ignorefile reader), so an upaas build sees exactly the context docker build . sees.
An app without a .dockerignore builds exactly as today.
A test builds the tar for a context with a .dockerignore that excludes a file and a ! re-include, and checks which files are in it.
Model: opus-5-5
upaas builds an app by uploading its clone as a tar (`archive.TarWithOptions(opts.ContextDir, &archive.TarOptions{})` in `performBuild`, `internal/docker/client.go`), with no exclude patterns. Docker does not filter a tar context through the app's `.dockerignore`: on the build host, `docker build -` with a tar on standard input and a build through the Docker API with BuildKit (how upaas builds) both received every file, as the review of https://git.eeqj.de/sneak/webhooker/pulls/410 found.
So an upaas build sees a different context from `docker build .` on the same clone: everything an app's `.dockerignore` leaves out reaches the build. In particular, the version-stamping convention (https://git.eeqj.de/sneak/project-management/issues/21) sends `.git` but leaves out `.git/config`, which can hold a credential in the remote URL; under upaas that file reaches the builder stage's layers. upaas's own clones use a deploy key, so their URLs hold none today, but the context still differs from the app's intent.
Definition of done:
- When it makes the build-context tar, upaas reads the app's `.dockerignore` (next to the Dockerfile it builds, as the Docker CLI does) and passes its patterns as exclude patterns, using the same pattern library the Docker CLI uses (`github.com/moby/patternmatcher` and its `ignorefile` reader), so an upaas build sees exactly the context `docker build .` sees.
- An app without a `.dockerignore` builds exactly as today.
- A test builds the tar for a context with a `.dockerignore` that excludes a file and a `!` re-include, and checks which files are in it.
Model: opus-5-5
Implementer's brief for #274 (the build-context tar ignores the app's .dockerignore).
Goal. When upaas builds an app, the tar it sends as the build context holds exactly the files docker build would send for the same clone. Today performBuild in internal/docker/client.go calls archive.TarWithOptions(opts.ContextDir, &archive.TarOptions{}) with no exclude patterns, and Docker does not filter a tar context through .dockerignore itself.
What to do.
Fresh clone of next in your own mktemp -d /srv/code/tmp/... directory; read the issue in full.
Before making the tar, read the app's ignore file the way the Docker CLI does and pass its patterns as ExcludePatterns: a <Dockerfile name>.dockerignore next to the Dockerfile if one exists, otherwise .dockerignore at the root of the build context. Check the Docker CLI's own rule before you rely on this summary, and match it. Use github.com/moby/patternmatcher and its ignorefile reader (already in go.mod as an indirect dependency; it becomes direct), not a hand-written parser.
The trap: the CLI never lets the patterns drop the Dockerfile or the ignore file itself from the context (an app whose .dockerignore lists Dockerfile or .dockerignore still builds with docker build). upaas must behave the same.
An app without an ignore file builds exactly as today. A missing file is not an error; an unreadable or malformed one fails the build with a plain error message.
Test: build the tar for a temporary context whose .dockerignore excludes a file and re-includes one with !, and check exactly which files are in it. Add a case showing the Dockerfile stays in when the patterns would exclude it.
make check. Remove any image or container you create.
Branch and PR. Branch off current next; PR base next, never main. Pull next before starting, and pull-rebase-resolve again right before pushing, re-running make check after any resolution (another worker is changing the auth tests and possibly script/test at the same time). Commit title ends (closes #274). Label the PR needs-review, assign clawbot. Push every commit at once.
Rules.
Gate only through make targets or script/ (make check, make test, make lint, make fmt); never raw go test/go vet/golangci-lint. All linting runs in Docker through make lint.
No scripted edits: never change a file with sed -i, perl -pi, awk, a python replace or a shell splice. Read and edit by hand; formatting only through make fmt.
Comprehensibility is a merge criterion: a newcomer must follow the change in one reading; no coined identifiers or terms; small and plain beats clever.
Shared host (~18 sessions): run docker build, make lint and your one authoritative make check under flock -w 1800 /srv/code/tmp/docker-gate.lock ...; flock -w exits 1 without running the command on timeout, so tell that apart from a red gate. Reap only processes you started (record PIDs, trap/wait); never pkill, killall or anything chosen from ps. Name any exit-status file by head SHA. Stay under 2 to 3 GiB of memory; no container memory flags.
Tracker text: plain language, no jargon, full links (https://git.eeqj.de/sneak/upaas/issues/N or /pulls/N, never a bare #N), PR body at most about 250 words, no logs, timings or pass/fail notes, escape </> as </>, no 4-byte emoji. Every comment, the PR body and the commit body end with Model: opus-5-5. Never mention any company or product name, no Co-Authored-By or session trailers.
Never ask an interactive question; nobody is at the terminal. Decide from this brief and the issue; a point only sneak can settle goes on the PR as a question with your recommendation, then stop.
upaas has one installation (sneak's); no migrations or compatibility code.
Cleanup at the end: two separate Bash calls, first only cd /srv/code/tmp, then only rm -rf <your temp dir>.
Final report: PR link, any disclosure, then a line done.
Model: opus-5-5
Implementer's brief for https://git.eeqj.de/sneak/upaas/issues/274 (the build-context tar ignores the app's `.dockerignore`).
**Goal.** When upaas builds an app, the tar it sends as the build context holds exactly the files `docker build` would send for the same clone. Today `performBuild` in `internal/docker/client.go` calls `archive.TarWithOptions(opts.ContextDir, &archive.TarOptions{})` with no exclude patterns, and Docker does not filter a tar context through `.dockerignore` itself.
**What to do.**
1. Fresh clone of `next` in your own `mktemp -d /srv/code/tmp/...` directory; read the issue in full.
2. Before making the tar, read the app's ignore file the way the Docker CLI does and pass its patterns as `ExcludePatterns`: a `<Dockerfile name>.dockerignore` next to the Dockerfile if one exists, otherwise `.dockerignore` at the root of the build context. Check the Docker CLI's own rule before you rely on this summary, and match it. Use `github.com/moby/patternmatcher` and its `ignorefile` reader (already in `go.mod` as an indirect dependency; it becomes direct), not a hand-written parser.
3. The trap: the CLI never lets the patterns drop the Dockerfile or the ignore file itself from the context (an app whose `.dockerignore` lists `Dockerfile` or `.dockerignore` still builds with `docker build`). upaas must behave the same.
4. An app without an ignore file builds exactly as today. A missing file is not an error; an unreadable or malformed one fails the build with a plain error message.
5. Test: build the tar for a temporary context whose `.dockerignore` excludes a file and re-includes one with `!`, and check exactly which files are in it. Add a case showing the Dockerfile stays in when the patterns would exclude it.
6. `make check`. Remove any image or container you create.
**Branch and PR.** Branch off current `next`; PR base `next`, never `main`. Pull `next` before starting, and pull-rebase-resolve again right before pushing, re-running `make check` after any resolution (another worker is changing the auth tests and possibly `script/test` at the same time). Commit title ends ` (closes #274)`. Label the PR `needs-review`, assign `clawbot`. Push every commit at once.
**Rules.**
- Gate only through `make` targets or `script/` (`make check`, `make test`, `make lint`, `make fmt`); never raw `go test`/`go vet`/`golangci-lint`. All linting runs in Docker through `make lint`.
- No scripted edits: never change a file with `sed -i`, `perl -pi`, `awk`, a python replace or a shell splice. Read and edit by hand; formatting only through `make fmt`.
- Comprehensibility is a merge criterion: a newcomer must follow the change in one reading; no coined identifiers or terms; small and plain beats clever.
- Shared host (~18 sessions): run `docker build`, `make lint` and your one authoritative `make check` under `flock -w 1800 /srv/code/tmp/docker-gate.lock ...`; `flock -w` exits 1 without running the command on timeout, so tell that apart from a red gate. Reap only processes you started (record PIDs, `trap`/`wait`); never `pkill`, `killall` or anything chosen from `ps`. Name any exit-status file by head SHA. Stay under 2 to 3 GiB of memory; no container memory flags.
- Tracker text: plain language, no jargon, full links (`https://git.eeqj.de/sneak/upaas/issues/N` or `/pulls/N`, never a bare `#N`), PR body at most about 250 words, no logs, timings or pass/fail notes, escape `<`/`>` as `<`/`>`, no 4-byte emoji. Every comment, the PR body and the commit body end with `Model: opus-5-5`. Never mention any company or product name, no `Co-Authored-By` or session trailers.
- Never ask an interactive question; nobody is at the terminal. Decide from this brief and the issue; a point only sneak can settle goes on the PR as a question with your recommendation, then stop.
- upaas has one installation (sneak's); no migrations or compatibility code.
- Cleanup at the end: two separate Bash calls, first only `cd /srv/code/tmp`, then only `rm -rf <your temp dir>`.
- Final report: PR link, any disclosure, then a line `done`.
Model: opus-5-5
clawbot
self-assigned this 2026-10-03 02:20:20 +02:00
Built in #275: the build leaves out of the tar the files the app's ignore file names, read as docker build reads it (an ignore file next to the Dockerfile, such as Dockerfile.dockerignore, otherwise .dockerignore at the root of the clone). The Dockerfile and .dockerignore always stay in, as with the Docker CLI.
Model: opus-5-5
Built in https://git.eeqj.de/sneak/upaas/pulls/275: the build leaves out of the tar the files the app's ignore file names, read as `docker build` reads it (an ignore file next to the Dockerfile, such as `Dockerfile.dockerignore`, otherwise `.dockerignore` at the root of the clone). The Dockerfile and `.dockerignore` always stay in, as with the Docker CLI.
Model: opus-5-5
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
upaas builds an app by uploading its clone as a tar (
archive.TarWithOptions(opts.ContextDir, &archive.TarOptions{})inperformBuild,internal/docker/client.go), with no exclude patterns. Docker does not filter a tar context through the app's.dockerignore: on the build host,docker build -with a tar on standard input and a build through the Docker API with BuildKit (how upaas builds) both received every file, as the review of sneak/webhooker#410 found.So an upaas build sees a different context from
docker build .on the same clone: everything an app's.dockerignoreleaves out reaches the build. In particular, the version-stamping convention (sneak/project-management#21) sends.gitbut leaves out.git/config, which can hold a credential in the remote URL; under upaas that file reaches the builder stage's layers. upaas's own clones use a deploy key, so their URLs hold none today, but the context still differs from the app's intent.Definition of done:
.dockerignore(next to the Dockerfile it builds, as the Docker CLI does) and passes its patterns as exclude patterns, using the same pattern library the Docker CLI uses (github.com/moby/patternmatcherand itsignorefilereader), so an upaas build sees exactly the contextdocker build .sees..dockerignorebuilds exactly as today..dockerignorethat excludes a file and a!re-include, and checks which files are in it.Model: opus-5-5
Implementer's brief for #274 (the build-context tar ignores the app's
.dockerignore).Goal. When upaas builds an app, the tar it sends as the build context holds exactly the files
docker buildwould send for the same clone. TodayperformBuildininternal/docker/client.gocallsarchive.TarWithOptions(opts.ContextDir, &archive.TarOptions{})with no exclude patterns, and Docker does not filter a tar context through.dockerignoreitself.What to do.
nextin your ownmktemp -d /srv/code/tmp/...directory; read the issue in full.ExcludePatterns: a<Dockerfile name>.dockerignorenext to the Dockerfile if one exists, otherwise.dockerignoreat the root of the build context. Check the Docker CLI's own rule before you rely on this summary, and match it. Usegithub.com/moby/patternmatcherand itsignorefilereader (already ingo.modas an indirect dependency; it becomes direct), not a hand-written parser..dockerignorelistsDockerfileor.dockerignorestill builds withdocker build). upaas must behave the same..dockerignoreexcludes a file and re-includes one with!, and check exactly which files are in it. Add a case showing the Dockerfile stays in when the patterns would exclude it.make check. Remove any image or container you create.Branch and PR. Branch off current
next; PR basenext, nevermain. Pullnextbefore starting, and pull-rebase-resolve again right before pushing, re-runningmake checkafter any resolution (another worker is changing the auth tests and possiblyscript/testat the same time). Commit title ends(closes #274). Label the PRneeds-review, assignclawbot. Push every commit at once.Rules.
maketargets orscript/(make check,make test,make lint,make fmt); never rawgo test/go vet/golangci-lint. All linting runs in Docker throughmake lint.sed -i,perl -pi,awk, a python replace or a shell splice. Read and edit by hand; formatting only throughmake fmt.docker build,make lintand your one authoritativemake checkunderflock -w 1800 /srv/code/tmp/docker-gate.lock ...;flock -wexits 1 without running the command on timeout, so tell that apart from a red gate. Reap only processes you started (record PIDs,trap/wait); neverpkill,killallor anything chosen fromps. Name any exit-status file by head SHA. Stay under 2 to 3 GiB of memory; no container memory flags.https://git.eeqj.de/sneak/upaas/issues/Nor/pulls/N, never a bare#N), PR body at most about 250 words, no logs, timings or pass/fail notes, escape</>as</>, no 4-byte emoji. Every comment, the PR body and the commit body end withModel: opus-5-5. Never mention any company or product name, noCo-Authored-Byor session trailers.cd /srv/code/tmp, then onlyrm -rf <your temp dir>.done.Model: opus-5-5
Built in #275: the build leaves out of the tar the files the app's ignore file names, read as
docker buildreads it (an ignore file next to the Dockerfile, such asDockerfile.dockerignore, otherwise.dockerignoreat the root of the clone). The Dockerfile and.dockerignorealways stay in, as with the Docker CLI.Model: opus-5-5
On
nextas7cf7059(#275), in milestone PR #244.Model: opus-5-5