Readable job names, latest tracks main, and an AGENTS.md
Job names in the Gitea UI rendered as the raw matrix expression
("${{ fromJSON(needs.select.outputs.images) }}"). Gitea resolves a job's matrix
when it PARSES the workflow, before `needs` outputs exist, so matrix.image was
interpolated against an unresolved matrix. There is no way to win with a dynamic
matrix: jobparser.nameWithMatrix interpolates a name containing "${{ }}", and
appends "(<values>)" to one that doesn't — either way the raw expression shows.
See go-gitea/gitea#28207.
So drop the matrix. build.yaml now runs one job, "Build changed images", that
loops over the selected images and emits ::group:: markers, giving a collapsible
section per image. Also: every step has an explicit static name, because Gitea
does not interpolate expressions in names either ("Log in to ${{ env.REGISTRY }}"
rendered literally).
Tag scheme, per review: `latest` now tracks main rather than the newest release,
and `edge` is gone — it's an Alpine/Traefik convention, not a broad standard, and
`main-<sha>` already covers "a specific commit". `latest` has exactly one owner
so a release tag and a main build can't race to define it. Release tags remain
immutable `:vX.Y.Z`/`:vX.Y`/`:vX` for pinning. This also means the ToolHive
manifest's `:latest` resolves as soon as this lands on main, with no release tag
needed first.
hack/docker-tags.sh folded into hack/build-images.sh, which is now the whole
pipeline — tag, build, smoke-test, push — shared by `make build` and CI. It uses
plain `docker build` instead of buildx, dropping setup-buildx-action: it loads
into the local store so the test runs pre-publish, and emits a plain manifest
with no attestations for Gitea's registry.
Verified in a simulated runner (repo in a docker volume, socket mounted, real
runner image): select + build + group markers, all four tag modes, and the
multi-image loop with a scratch second image.
AGENTS.md records the conventions and, importantly, the three Gitea gotchas that
all look fine locally: no bind-mounting the workspace into a sibling container,
no dynamic matrix, no expressions in names.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
This commit is contained in:
@@ -23,12 +23,15 @@ The registry is public, so no pull secret is required.
|
||||
|
||||
## Tags
|
||||
|
||||
| Tag | Points at |
|
||||
| --- | --- |
|
||||
| `vX.Y.Z` / `vX.Y` / `vX` | a released build |
|
||||
| `latest` | the most recent release |
|
||||
| `edge` | the current tip of `main` |
|
||||
| `main-<sha>` | one specific commit on `main` |
|
||||
| Tag | Points at | Set by |
|
||||
| --- | --- | --- |
|
||||
| `latest` | the current tip of `main` | push to `main` |
|
||||
| `main-<sha>` | one specific commit on `main` | push to `main` |
|
||||
| `vX.Y.Z` / `vX.Y` / `vX` | an immutable released build | tag `<image>/vX.Y.Z` |
|
||||
| `pr-<n>` | a pull request build — built, never published | pull request |
|
||||
|
||||
`latest` has exactly one owner — `main` — so a release tag and a `main` build can
|
||||
never race to define it. Pin to `vX.Y.Z` when you want a build that will not move.
|
||||
|
||||
Releases are cut per image by pushing a tag named `<image>/vX.Y.Z`, which builds
|
||||
and publishes that image alone:
|
||||
@@ -51,23 +54,25 @@ cp -r template images/my-image
|
||||
here (`FROM gitea.libretechconsulting.com/rmcguire/node-agent:latest`).
|
||||
2. Fill in `images/my-image/README.md`.
|
||||
3. Extend `images/my-image/test.sh` to assert whatever the image promises.
|
||||
4. `make build test IMAGE=my-image`
|
||||
4. `make build IMAGE=my-image`
|
||||
|
||||
CI needs no changes — it discovers every directory under `images/` that contains
|
||||
a `Dockerfile`.
|
||||
a `Dockerfile`. See [AGENTS.md](AGENTS.md) for the full conventions.
|
||||
|
||||
## Local development
|
||||
|
||||
```sh
|
||||
make help # list targets
|
||||
make all # everything CI does
|
||||
make build test IMAGE=node-agent # one image
|
||||
make help # list targets
|
||||
make all # everything CI does
|
||||
make build IMAGE=node-agent # build and smoke-test one image
|
||||
```
|
||||
|
||||
## CI
|
||||
|
||||
Two Gitea workflows, both of which just call the `make` targets above:
|
||||
Two Gitea workflows, both of which just call the `make` and `hack/` entry points
|
||||
above, so a green `make all` locally means a green pipeline:
|
||||
|
||||
- **`lint.yaml`** — repository layout, `hadolint`, `shellcheck`.
|
||||
- **`build.yaml`** — builds only the images whose files changed, smoke-tests each
|
||||
one before anything is published, then pushes on `main` or a release tag.
|
||||
- **`build.yaml`** — works out which images changed, then builds, smoke-tests and
|
||||
(on `main` or a release tag) publishes each one. Nothing is pushed until its
|
||||
smoke test passes.
|
||||
|
||||
Reference in New Issue
Block a user