workflow: build, tag & publish the agent image on manual dispatch #7
Labels
No labels
bug
duplicate
enhancement
help wanted
invalid
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
serious-devs/ai-factory#7
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Goal
A Forgejo Actions workflow in this repository —
.forgejo/workflows/image.yml— triggered manually (workflow_dispatch, no inputs) that builds the agent image, tags it, pushes it to the instance registry, and reports the new tag. The chain build → tag → push must involve zero LLM calls.Why
Today this is manual (
docs/setup.md§3): docker build, docker push, a hand-made tag (20261013-1), then a hand edit of theagent-imagedefault in.forgejo/workflows/agent.yml. Automating the chain removes all of that. Merging stays with @mlvtito and deployment keeps its human gate: the workflow opens a small PR bumping the default tag, and merging that PR is his decision.Tag governance (decision)
YYYYMMDD-N— UTC build date + the workflow run number (e.g.20261114-3). Chronological, unique, cannot collide with the legacy hand-made tags.latestpushed alongside, always pointing at the newest build — human convenience only. Nothing in this repository may referencelatestfor the agent image: theagent-imagedefault stays pinned to immutable tags. (Mirrors the style of the tsuru base image, which is referenced aslatest.)20261114-N). The 1:1 string mapping makes the image ↔ workflow-version link greppable — no mapping table to maintain, no prefix to remember. Created after the image push succeeds (order: build → push image → create git tag → bump PR), so a git tag can never point at a commit whose image was not published.git tag -a $TAG -m "agent image $TAG — commit $GITHUB_SHA, registry digest $DIGEST"(digest captured from the pushed image). One lookup links image ↔ code ↔ digest.latestnever becomes a git tag — a mutable name has no meaning in git; only the immutable tag is created.npm installfloats). The base image stays ontsuru:latestBY DECISION of @mlvtito: tsuru is his own tool, evolves slowly, and only needs to bring the right tool versions — do not open digest-pinning issues for it.agent-imagedefault (the bump PR is created after the tag). That is correct: the git tag certifies what was built, the bump PR certifies what is deployed. Two different facts, deliberately kept apart.bot+BOT_TOKEN(same identity as everything else; avoids relying on the built-inGITHUB_TOKEN, whose tag-push behavior on this Forgejo version is unverified).Workflow sketch
Build tool: podman (Arnaud's preference — daemonless and rootless-capable; as a bonus it removes the docker-socket exposure the original docker plan needed).
.forgejo/workflows/image.yml:Implementation pitfalls to verify against the actual runner:
quay.io/podman/stablemay lackgit(Fedora-minimal base): if so,microdnf install -y gitin a pre-step. Checkout is a plaingit clonewith thebottoken, so node is NOT needed in the container at all.--device /dev/fuse+--storage-driver=vfs) before reaching for--privileged; verify what this act_runner version honors viacontainer.options. The--storage-driver=vfsis slower but the safest inside a container.bot(now collaborator on this repo): docker login asbotwith the org-level secretBOT_TOKEN, and the same token for the git tag push and the bump-PR API call — one identity for everything the workflow does. VerifyBOT_TOKENscopes cover all three: container/package write (registry push), repository write (git tag push + bump branch), and issue write (bump-PR comment if any). If a scope is missing, recreate the PAT with the required scopes — the first dispatch will show it (403 at the failing step). The login also covers pulling the base imagefactory.serious-devs.io/serious-devs/tsuru:latestreferenced byimage/Containerfile.docs/setup.mdsecurity notes.Out of scope
agent.ymlonmain(the bump is a PR).Acceptance criteria
image.ymlfrom the Actions tab succeeds on a cleanmainYYYYMMDD-N, is owned by userbotin the registry, and can be pulled from another machine (podman/docker/skopeo — the registry is OCI-compliant);:latestpoints at the same digestpodman push --digestfile, and it matches the digest embedded in the annotated git tag messageserious-devs/test_factory_ai, dispatch a plan run passingagent-image: factory.serious-devs.io/serious-devs/ai-factory:$TAGas input (no default change needed to test) → job completes, agent repliesmainchanging exactly theagent-imagedefault line in.forgejo/workflows/agent.yml; after merging it, a plain plan dispatch uses the new tag with no input overrideYYYYMMDD-Nexists on the built commit, is annotated, and its message contains the commit SHA and the registry digestGITHUB_TOKENor fallback secret) is documented in a workflow commentdocs/setup.md§3 rewritten to describe the manual dispatch instead of the local docker commands, and the file-name drift fixed (image/Containerfile, notimage/Dockerfile)Workflowpage Plumbing row must gain the newimage.ymlfile at merge time)First dispatch failed at
Build and push image(storage driver mismatch: login initialized anoverlayDB, build asked forvfs) — issue reopened since the acceptance criteria are not met yet. Fix in PR: use the vfs driver from /etc/containers/storage.conf before any podman command. Re-dispatch after merging it.