Skip to content

Move the build environment under package/, behind an entry point - #1222

Closed
yiyi-wang-rv wants to merge 1 commit into
masterfrom
package-build-entry-point
Closed

yiyi-wang-rv wants to merge 1 commit into
masterfrom
package-build-entry-point

Conversation

@yiyi-wang-rv

Copy link
Copy Markdown

Why

The build recipe (package/debian/build-package) has always lived under package/, versioned
with the source it builds. The build environment did not — it was
.github/workflows/Dockerfile, reachable only from a GitHub workflow. And the knowledge of how
to drive it was written down nowhere executable at all: which LLVM version pairs with which
Ubuntu release, which build args the Dockerfile needs, how to map the calling user into the
container, where to mount the checkout. That lived partly in two composite actions and partly in
the head of whoever wrote the next caller.

Moving CI to the internal forge deletes .github/ outright, which ends that arrangement whether
or not we plan for it. So rather than move the same shape sideways, this puts the environment
next to the recipe and gives it two entry points that a forge workflow, the release repository,
and a developer's shell can all call identically:

package/build-env/build-deb noble
package/build-env/test-deb  noble

What moved

Before After
.github/workflows/Dockerfile package/build-env/Dockerfile
build args spread across .github/actions/{with-docker,test-package} package/build-env/build-deb
the bare-image test invocation, inline in a composite action package/build-env/test-deb
the distro→LLVM pairing, restated by every caller package/build-env/common.sh

Both composite actions keep working — their dockerfile: default is repointed, and nothing else
about the GitHub path changes. package/debian/build-package and test-package are untouched.

Two real bugs found on the way, both fixed here

1. The checkout must not mount at /opt/workspace. dpkg-buildpackage writes its output to
the parent of the directory it builds in, and build-package then moves it back. Mount the
checkout at /opt/workspace and that parent is /, which the non-root build user cannot write.
The existing GitHub path gets away with it by accident: it checks out into a k-<distro>/
subdirectory and mounts the parent, so .. lands on the runner workspace. Anything that mounts
the checkout directly — which is the obvious thing to do, and what the release repository
currently does — fails from inside dpkg-buildpackage, naming neither the mount nor the reason.

Reproduced both ways, and fixed by making the layout explicit: the Dockerfile creates
/opt/workspace owned by the build user, and build-deb mounts the checkout at
/opt/workspace/source.

2. Passing the caller's account name into the image collides with the base image.
ubuntu:noble ships an ubuntu account at uid/gid 1000, and users (gid 100) is the primary
group of many developer accounts. Either one makes the Dockerfile's groupadd/useradd fail —
several minutes into the build, with a message that never mentions a build arg.

Only the ids ever mattered: they exist so files written to the bind mount come back owned by
the caller. So the Dockerfile now names the account itself (builder), callers pass ids alone,
and -o lets those ids be shared with an existing account rather than deleting a system account
something else is using. with-docker passes ids too, and runs the container with a numeric
--user.

This is why CI builds today but the same Dockerfile fails on a developer machine: the runner
accounts happen to sit outside the ranges that collide.

Not in this PR

  • Deleting .github/. That belongs to the forge migration. This only makes the migration
    possible without taking the deb build down with it.
  • Changing what gets built. package/debian/* is untouched; the produced deb is the same.
  • The /home/user/.tmp-maven oddity in the Dockerfile — it ADDs to a literal /home/user/
    that is nobody's home. It works by side effect (the warm cache lands in ~/.m2), and untangling
    it is a separate change from moving the file.

How to verify

package/build-env/build-deb jammy
package/build-env/test-deb  jammy

CI exercises the same Dockerfile through the unchanged composite actions, so a green test.yml
plus clang-format-check.yml covers the move itself.

What I checked locally: the jammy image builds as uid 1000 / gid 100 — the collision that fails
on master — and inside it the account resolves to a real home, lit is on PATH, and both
the bind mount and its parent are writable. Argument handling and engine selection were checked
against a stub engine, run from a subdirectory as well as the repo root. shellcheck -x clean.

Not checked locally: a full deb build, which needs submodules and a long C++ compile.
package/debian/* is unchanged, so what this PR alters is the environment and the invocation.

🤖 Generated with Claude Code

The build RECIPE (package/debian/build-package) has always lived under package/,
versioned with the source it builds. The build ENVIRONMENT did not: it was
.github/workflows/Dockerfile, reachable only from a GitHub workflow. And the
knowledge of how to DRIVE it -- which LLVM version pairs with which Ubuntu
release, which build args the Dockerfile needs, how to map the calling user into
the container, where to mount the checkout -- was written down nowhere
executable, only spread across two composite actions.

Moving CI to the internal forge deletes .github/ outright, which ends that
arrangement whether or not we plan for it. So the environment moves next to the
recipe, behind two entry points a forge workflow, the release repository and a
developer's shell can all call the same way:

    package/build-env/build-deb noble
    package/build-env/test-deb  noble

They share common.sh, which holds the distro table: the LLVM version that pairs
with each Ubuntu release now lives in one place rather than being restated by
every caller, so adding a release is one edit here and one in the CI matrix.

package/debian/* is untouched and the produced deb is the same. The composite
actions keep working -- only their `dockerfile:` default moves -- so the GitHub
path is unchanged until the migration deletes it.

Two real bugs turned up while writing this down, both fixed here.

The checkout must not mount at /opt/workspace. dpkg-buildpackage writes its
output to the PARENT of the directory it builds in, and build-package moves it
back from there; with the checkout at /opt/workspace that parent is /, which the
non-root build user cannot write. The GitHub path gets away with it by accident
-- it checks out into k-<distro>/ and mounts the parent, so .. lands on the
runner workspace. Anything mounting the checkout directly, which is the obvious
thing to do and what rv-release currently does, fails from inside
dpkg-buildpackage naming neither the mount nor the reason. The Dockerfile now
creates /opt/workspace owned by the build user and build-deb mounts the checkout
at /opt/workspace/source.

Passing the caller's account NAME into the image collides with the base image.
ubuntu:noble ships an `ubuntu` account at uid/gid 1000 and `users` is gid 100,
so groupadd/useradd fails several minutes into the build with a message that
never mentions a build arg. Only the ids ever mattered -- they exist so files
written to the bind mount come back owned by the caller -- so the Dockerfile
names the account itself and callers pass ids alone, with -o so the ids can be
shared rather than deleting a system account something else uses.

Verified: the jammy image builds as uid 1000 / gid 100, which fails on master;
inside it the account resolves to a real home, lit is on PATH, and both the bind
mount and its PARENT are writable, which is the fix above. Argument handling and
engine selection checked against a stub engine, from a subdirectory as well as
the root. shellcheck -x clean.

Not verified: a full deb build, which needs submodules and a long C++ compile.
package/debian/* is unchanged, so what this commit alters is the environment and
the invocation, and those are covered.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant