-
Notifications
You must be signed in to change notification settings - Fork 131
Publish pure agent runtime images with version tags #801
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
law-chain-hot
wants to merge
12
commits into
main
Choose a base branch
from
codex/agent-runtime-images-v2
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
3740bef
docs: design agent runtime image publishing
law-chain-hot 99a3df4
docs: plan agent runtime image publishing
law-chain-hot 5c0a7d2
docs: correct multi-arch daemon image plan
law-chain-hot 3624600
build: restore agent runtime Dockerfiles
law-chain-hot 5041b20
build: add versioned agent runtime image script
law-chain-hot a108b13
ci: publish agent runtime images
law-chain-hot d9285a8
chore: sync runtime image refs to v2 packages
law-chain-hot e55dc6b
docs: rename runtime image plans without dates
law-chain-hot 690b99d
fix: address runtime image review comments
law-chain-hot 543ef7c
fix: publish original runtime packages with version tags
law-chain-hot 23cebc9
docs: annotate agent runtime image publishing flow
law-chain-hot cc9e7da
fix: keep runtime images pure
law-chain-hot File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -13,7 +13,7 @@ apps/.nx | |
| # Build outputs | ||
| target | ||
| dist | ||
| apps/dist | ||
| apps/dist/* | ||
| coverage | ||
| apps/coverage | ||
| *.log | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,76 @@ | ||
| name: Publish Agent Runtime Images | ||
|
|
||
| on: | ||
| push: | ||
| branches: [main] # Publish only after the PR lands on main. | ||
| paths: | ||
| - '.dockerignore' # Docker context changes can change the published image contents. | ||
| - 'images/agent-runtime/VERSION' # Version bumps are the normal way to publish a new tag. | ||
| - 'images/agent-runtime/**' # Dockerfiles and version file directly define image contents. | ||
| - 'scripts/images/build-agent-runtime.sh' # Build script changes affect all published images. | ||
| - '.github/workflows/publish-agent-runtime-images.yml' # Workflow changes should validate themselves on main. | ||
| workflow_dispatch: | ||
| inputs: | ||
| version: | ||
| description: 'Version tag to publish, with or without leading v. Defaults to images/agent-runtime/VERSION.' | ||
| required: false | ||
| type: string | ||
|
|
||
| permissions: | ||
| contents: read # Checkout only needs repository read access. | ||
| packages: write # GHCR push requires package write access. | ||
|
|
||
| concurrency: | ||
| group: publish-agent-runtime-images-${{ github.ref }} # Serialize publishes per branch/ref. | ||
| cancel-in-progress: false # Do not cancel an in-flight release publish. | ||
|
|
||
| jobs: | ||
| publish: | ||
| name: Publish agent runtime images | ||
| runs-on: ubuntu-latest | ||
|
|
||
| steps: | ||
| - name: Checkout code | ||
| uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # Pin checkout for supply-chain stability. | ||
| with: | ||
| persist-credentials: false # Later steps do not need git credentials. | ||
|
|
||
| - name: Set up QEMU | ||
| uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # Enable cross-arch build emulation. | ||
|
|
||
| - name: Set up Docker Buildx | ||
| uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # Buildx is required for multi-arch images. | ||
|
|
||
| - name: Log in to GHCR | ||
| uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # Authenticate Docker so buildx can push to GHCR. | ||
| with: | ||
| registry: ghcr.io # Target registry for BoxLite runtime images. | ||
| username: ${{ github.actor }} # GitHub actor is accepted for GITHUB_TOKEN auth. | ||
| password: ${{ secrets.GITHUB_TOKEN }} # Built-in token has packages:write from workflow permissions. | ||
|
|
||
| - name: Determine image version | ||
| id: version | ||
| env: | ||
| INPUT_VERSION: ${{ github.event.inputs.version }} # Optional manual override from workflow_dispatch. | ||
| run: | | ||
| set -euo pipefail | ||
|
|
||
| if [ -n "${INPUT_VERSION:-}" ]; then | ||
| version="${INPUT_VERSION#v}" | ||
| else | ||
| version="$(tr -d '[:space:]' < images/agent-runtime/VERSION)" | ||
| fi | ||
|
|
||
| if ! echo "$version" | grep -Eq '^[0-9]+[.][0-9]+[.][0-9]+([-+][0-9A-Za-z.-]+)?$'; then | ||
| echo "Invalid version '$version'; expected MAJOR.MINOR.PATCH" >&2 | ||
| exit 1 | ||
| fi | ||
|
|
||
| echo "tag=v$version" >> "$GITHUB_OUTPUT" # Share normalized Docker tag with the publish step. | ||
|
|
||
| - name: Publish images | ||
| env: | ||
| TAG: ${{ steps.version.outputs.tag }} # Use the version resolved above. | ||
| PUSH: '1' # CI path must push to GHCR instead of local Docker. | ||
| PLATFORMS: linux/amd64,linux/arm64 # Publish both supported CPU architectures. | ||
| run: bash scripts/images/build-agent-runtime.sh | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
13 changes: 13 additions & 0 deletions
13
apps/dashboard/src/components/Box/supportedBoxImages.test.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| import { describe, expect, it } from 'vitest' | ||
| import { SUPPORTED_BOX_IMAGES } from './supportedBoxImages' | ||
|
|
||
| describe('supported box images', () => { | ||
| it('exposes the three versioned runtime image refs, base first', () => { | ||
| expect(SUPPORTED_BOX_IMAGES.map((image) => image.ref)).toEqual([ | ||
| 'ghcr.io/boxlite-ai/boxlite-agent-base:v0.1.0', | ||
| 'ghcr.io/boxlite-ai/boxlite-agent-python:v0.1.0', | ||
| 'ghcr.io/boxlite-ai/boxlite-agent-node:v0.1.0', | ||
| ]) | ||
| expect(SUPPORTED_BOX_IMAGES[0]).toMatchObject({ id: 'base', isDefault: true }) | ||
| }) | ||
| }) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| export const SUPPORTED_BOX_IMAGES = [ | ||
| { | ||
| id: 'base', | ||
| name: 'Base', | ||
| ref: 'ghcr.io/boxlite-ai/boxlite-agent-base:v0.1.0', // Default generic image shown first in Create Box. | ||
| isDefault: true, | ||
| }, | ||
| { | ||
| id: 'python', | ||
| name: 'Python', | ||
| ref: 'ghcr.io/boxlite-ai/boxlite-agent-python:v0.1.0', // Python option for users who need Python tooling preinstalled. | ||
| isDefault: false, | ||
| }, | ||
| { | ||
| id: 'node', | ||
| name: 'Node.js', | ||
| ref: 'ghcr.io/boxlite-ai/boxlite-agent-node:v0.1.0', // Node option for users who need Node tooling preinstalled. | ||
| isDefault: false, | ||
| }, | ||
| ] as const |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,90 @@ | ||
| # Agent Runtime Images Design | ||
|
|
||
| ## Goal | ||
|
|
||
| Publish the three BoxLite agent runtime images from source-controlled Dockerfiles through GitHub Actions, using the existing GHCR package names with version tags starting at `v0.1.0`. | ||
|
|
||
| These images are pure OCI images. They provide the filesystem and default tools that a Box can pull and run; they do not embed `boxlite-daemon`, `start-agent-runtime.sh`, or any BoxLite process supervisor. | ||
|
|
||
| ## Context | ||
|
|
||
| The image source now lives in this repository so the GHCR packages can be rebuilt from reviewed code instead of unpublished local Dockerfiles: | ||
|
|
||
| - `images/agent-runtime/base.Dockerfile` | ||
| - `images/agent-runtime/python.Dockerfile` | ||
| - `images/agent-runtime/node.Dockerfile` | ||
|
|
||
| The BoxLite runtime already pulls and loads image refs. The image should therefore stay limited to OS/runtime contents and a default keep-alive command. BoxLite control-plane or runner behavior belongs outside the image. | ||
|
|
||
| ## Naming And Versioning | ||
|
|
||
| Use the existing package names: | ||
|
|
||
| - `ghcr.io/boxlite-ai/boxlite-agent-base` | ||
| - `ghcr.io/boxlite-ai/boxlite-agent-python` | ||
| - `ghcr.io/boxlite-ai/boxlite-agent-node` | ||
|
|
||
| Use version tags derived from `images/agent-runtime/VERSION`. The initial version is `0.1.0`, published as `v0.1.0`. Each future agent-runtime image release increments that file and publishes the matching `vX.Y.Z` tag. | ||
|
|
||
| Do not delete or retag older package versions. | ||
|
|
||
| ## Architecture | ||
|
|
||
| Add Dockerfiles in `images/agent-runtime/` so local development and CI share one source of truth. Add a publish workflow that builds and pushes the three images as multi-architecture GHCR images for `linux/amd64` and `linux/arm64`. | ||
|
|
||
| The workflow reads the version from `images/agent-runtime/VERSION` by default and supports a manual override through `workflow_dispatch`. A shell build script remains available for local dry runs and for CI reuse where useful. | ||
|
|
||
| Multi-architecture support is handled by Docker Buildx. The Dockerfiles contain only packages and shell setup, so no architecture-specific BoxLite binary is copied into the image. | ||
|
|
||
| ## Data Flow | ||
|
|
||
| 1. Developer updates an agent runtime Dockerfile or bumps `images/agent-runtime/VERSION`. | ||
| 2. GitHub Actions validates the version and logs in to GHCR. | ||
| 3. Buildx builds each pure runtime image for `linux/amd64` and `linux/arm64`. | ||
| 4. GHCR receives the three existing package names with the same version tag. | ||
| 5. API allowlist, infra fallback env, and dashboard image picker point at the new refs. | ||
| 6. Dashboard creates boxes using the new refs, and API rejects refs outside the curated set. | ||
|
|
||
| ## Files To Change | ||
|
|
||
| - Add `images/agent-runtime/base.Dockerfile` | ||
| - Add `images/agent-runtime/python.Dockerfile` | ||
| - Add `images/agent-runtime/node.Dockerfile` | ||
| - Add `images/agent-runtime/VERSION` | ||
| - Add `scripts/images/build-agent-runtime.sh` | ||
| - Add `.github/workflows/publish-agent-runtime-images.yml` | ||
| - Modify `apps/api/src/box/constants/curated-images.constant.ts` | ||
| - Modify `apps/api/src/box/constants/curated-images.constant.spec.ts` | ||
| - Modify `apps/infra/sst.config.ts` | ||
| - Modify `apps/dashboard/src/components/Box/CreateBoxSheet.tsx` | ||
| - Add or update dashboard tests for the supported image refs. | ||
|
|
||
| ## Error Handling | ||
|
|
||
| The build script should fail fast when: | ||
|
|
||
| - `TAG` is empty or malformed. | ||
| - `PLATFORMS` contains anything outside `linux/amd64` and `linux/arm64`. | ||
| - A required Dockerfile is missing. | ||
|
|
||
| The workflow should not delete or retag existing image versions. It should push the requested version tag to the existing packages. | ||
|
|
||
| ## Testing | ||
|
|
||
| Use test-first changes for user-visible behavior: | ||
|
|
||
| - API allowlist test should expect the three `*:v0.1.0` refs and fail before implementation. | ||
| - Dashboard image picker test should expect the three `*:v0.1.0` refs and fail before implementation. | ||
|
|
||
| Then verify: | ||
|
|
||
| - `make test:apps` for API/dashboard unit coverage. | ||
| - A local dry-run build for one platform where Docker is available. | ||
| - The workflow YAML is syntactically valid by inspection and uses `packages: write`. | ||
|
|
||
| ## Out Of Scope | ||
|
|
||
| - Deleting old GHCR packages. | ||
| - Migrating existing boxes that already reference old images. | ||
| - Redesigning the image picker to fetch dynamic image refs from the API. | ||
| - Changing runner image pull authentication. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| 0.1.0 |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
better name