Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
129 changes: 129 additions & 0 deletions .agentplane/tasks/202605011627-F40YFZ/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
---
id: "202605011627-F40YFZ"
title: "Add GHCR release image module"
status: "DOING"
priority: "high"
owner: "CODER"
revision: 5
origin:
system: "manual"
depends_on:
- "202605011626-HXH0R5"
tags:
- "code"
- "release"
verify:
- "bun run release:distribution:check"
- "docker build -t agentplane:release-smoke -f packages/agentplane/Dockerfile ."
plan_approval:
state: "approved"
updated_at: "2026-05-01T16:29:58.871Z"
updated_by: "ORCHESTRATOR"
note: null
verification:
state: "ok"
updated_at: "2026-05-01T17:52:04.041Z"
updated_by: "CODER"
note: "GHCR release image module builds the AgentPlane container from the local release tarball artifact, pushes version/tag/latest tags in publish.yml, and uploads ghcr-module evidence."
commit: null
comments:
-
author: "CODER"
body: "Start: add GHCR image packaging and release workflow evidence from release-distribution.json."
events:
-
type: "status"
at: "2026-05-01T17:27:30.196Z"
author: "CODER"
from: "TODO"
to: "DOING"
note: "Start: add GHCR image packaging and release workflow evidence from release-distribution.json."
-
type: "verify"
at: "2026-05-01T17:52:04.041Z"
author: "CODER"
state: "ok"
note: "GHCR release image module builds the AgentPlane container from the local release tarball artifact, pushes version/tag/latest tags in publish.yml, and uploads ghcr-module evidence."
doc_version: 3
doc_updated_at: "2026-05-01T17:52:04.074Z"
doc_updated_by: "CODER"
description: "Add a release module that builds and publishes a versioned GHCR image for AgentPlane and verifies the container can run the CLI."
sections:
Summary: |-
Add GHCR release image module

Add a release module that builds and publishes a versioned GHCR image for AgentPlane and verifies the container can run the CLI.
Scope: |-
- In scope: Add a release module that builds and publishes a versioned GHCR image for AgentPlane and verifies the container can run the CLI.
- Out of scope: unrelated refactors not required for "Add GHCR release image module".
Plan: "Plan: add a GHCR release image module, Dockerfile, image metadata labels, and workflow publication path that tags exact version, sha, and latest only after the release manifest is ready. Verification: distribution check and Docker build smoke when Docker is available."
Verify Steps: |-
1. Run `bun run release:distribution:check`. Expected: it succeeds and confirms the requested outcome for this task.
2. Run `docker build -t agentplane:release-smoke -f packages/agentplane/Dockerfile .`. Expected: it succeeds and confirms the requested outcome for this task.
3. Review the changed artifact or behavior for the `code` task. Expected: the requested outcome is visible and matches the approved scope.
4. Compare the final result against the task summary and touched scope. Expected: remaining follow-up is either resolved or explicit in ## Findings.
Verification: |-
<!-- BEGIN VERIFICATION RESULTS -->
### 2026-05-01T17:52:04.041Z — VERIFY — ok

By: CODER

Note: GHCR release image module builds the AgentPlane container from the local release tarball artifact, pushes version/tag/latest tags in publish.yml, and uploads ghcr-module evidence.

VerifyStepsRef: doc_version=3, doc_updated_at=2026-05-01T17:27:30.196Z, excerpt_hash=sha256:7bf0b5d3b4d965cf1b88c3b90d1f8590f9ba78bd961f0f976f3c22b1b41454da

<!-- END VERIFICATION RESULTS -->
Rollback Plan: |-
- Revert task-related commit(s).
- Re-run required checks to confirm rollback safety.
Findings: |-
- Observation: Checks: bun run release:ghcr:check; bun run release:distribution:check; docker build -t agentplane:release-smoke -f packages/agentplane/Dockerfile .; docker run --rm agentplane:release-smoke --version => 0.4.0; bun run workflows:command-check; bun test packages/agentplane/src/commands/release/publish-workflow-contract.test.ts; bun run docs:scripts:check; bun run lint:core; node .agentplane/policy/check-routing.mjs; agentplane doctor; git diff --check.
Impact: Next release publish job will produce a GHCR image and explicit ghcr-result.json evidence instead of stopping at npm/GitHub assets.
Resolution: Docker build avoids registry checksum drift by using the same npm pack tarball artifact generated for the release candidate; GHCR publish uses packages: write permission and records published status after pushes.
id_source: "generated"
---
## Summary

Add GHCR release image module

Add a release module that builds and publishes a versioned GHCR image for AgentPlane and verifies the container can run the CLI.

## Scope

- In scope: Add a release module that builds and publishes a versioned GHCR image for AgentPlane and verifies the container can run the CLI.
- Out of scope: unrelated refactors not required for "Add GHCR release image module".

## Plan

Plan: add a GHCR release image module, Dockerfile, image metadata labels, and workflow publication path that tags exact version, sha, and latest only after the release manifest is ready. Verification: distribution check and Docker build smoke when Docker is available.

## Verify Steps

1. Run `bun run release:distribution:check`. Expected: it succeeds and confirms the requested outcome for this task.
2. Run `docker build -t agentplane:release-smoke -f packages/agentplane/Dockerfile .`. Expected: it succeeds and confirms the requested outcome for this task.
3. Review the changed artifact or behavior for the `code` task. Expected: the requested outcome is visible and matches the approved scope.
4. Compare the final result against the task summary and touched scope. Expected: remaining follow-up is either resolved or explicit in ## Findings.

## Verification

<!-- BEGIN VERIFICATION RESULTS -->
### 2026-05-01T17:52:04.041Z — VERIFY — ok

By: CODER

Note: GHCR release image module builds the AgentPlane container from the local release tarball artifact, pushes version/tag/latest tags in publish.yml, and uploads ghcr-module evidence.

VerifyStepsRef: doc_version=3, doc_updated_at=2026-05-01T17:27:30.196Z, excerpt_hash=sha256:7bf0b5d3b4d965cf1b88c3b90d1f8590f9ba78bd961f0f976f3c22b1b41454da

<!-- END VERIFICATION RESULTS -->

## Rollback Plan

- Revert task-related commit(s).
- Re-run required checks to confirm rollback safety.

## Findings

- Observation: Checks: bun run release:ghcr:check; bun run release:distribution:check; docker build -t agentplane:release-smoke -f packages/agentplane/Dockerfile .; docker run --rm agentplane:release-smoke --version => 0.4.0; bun run workflows:command-check; bun test packages/agentplane/src/commands/release/publish-workflow-contract.test.ts; bun run docs:scripts:check; bun run lint:core; node .agentplane/policy/check-routing.mjs; agentplane doctor; git diff --check.
Impact: Next release publish job will produce a GHCR image and explicit ghcr-result.json evidence instead of stopping at npm/GitHub assets.
Resolution: Docker build avoids registry checksum drift by using the same npm pack tarball artifact generated for the release candidate; GHCR publish uses packages: write permission and records published status after pushes.
8 changes: 8 additions & 0 deletions .agentplane/tasks/202605011627-F40YFZ/pr/diffstat.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.github/workflows/publish.yml | 37 ++++
package.json | 1 +
packages/agentplane/Dockerfile | 17 ++
packages/agentplane/Dockerfile.dockerignore | 10 +
.../release/publish-workflow-contract.test.ts | 9 +
scripts/README.md | 1 +
scripts/render-ghcr-image-metadata.mjs | 203 +++++++++++++++++++++
7 files changed, 278 insertions(+)
40 changes: 40 additions & 0 deletions .agentplane/tasks/202605011627-F40YFZ/pr/github-body.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
## Summary

Add GHCR release image module

Add a release module that builds and publishes a versioned GHCR image for AgentPlane and verifies the container can run the CLI.

## Scope

- In scope: Add a release module that builds and publishes a versioned GHCR image for AgentPlane and verifies the container can run the CLI.
- Out of scope: unrelated refactors not required for "Add GHCR release image module".

## Verification

- State: ok
- Note: GHCR release image module builds the AgentPlane container from the local release tarball artifact, pushes version/tag/latest tags in publish.yml, and uploads ghcr-module evidence.
- Full verification checklist lives in local review.md.

## Handoff Notes

- No handoff notes recorded yet. Use `agentplane pr note ...` to append one.

<details>
<summary>Raw evidence</summary>

- Updated: 2026-05-01T17:52:20.837Z
- Branch: task/202605011627-F40YFZ/ghcr-release-image
- Head: 0132bad0de07

```text
.github/workflows/publish.yml | 37 ++++
package.json | 1 +
packages/agentplane/Dockerfile | 17 ++
packages/agentplane/Dockerfile.dockerignore | 10 +
.../release/publish-workflow-contract.test.ts | 9 +
scripts/README.md | 1 +
scripts/render-ghcr-image-metadata.mjs | 203 +++++++++++++++++++++
7 files changed, 278 insertions(+)
```

</details>
1 change: 1 addition & 0 deletions .agentplane/tasks/202605011627-F40YFZ/pr/github-title.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
release: Add GHCR release image module (F40YFZ)
14 changes: 14 additions & 0 deletions .agentplane/tasks/202605011627-F40YFZ/pr/meta.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"base": "main",
"branch": "task/202605011627-F40YFZ/ghcr-release-image",
"created_at": "2026-05-01T17:27:30.544Z",
"head_sha": "0132bad0de07df5e8f99ddb3eeeee994467bc0ec",
"last_verified_at": "2026-05-01T17:52:04.041Z",
"last_verified_sha": "3f889613cf8b31095fcb75999beb86d948781dc6",
"schema_version": 1,
"task_id": "202605011627-F40YFZ",
"updated_at": "2026-05-01T17:52:20.837Z",
"verify": {
"status": "pass"
}
}
Empty file.
65 changes: 65 additions & 0 deletions .agentplane/tasks/202605011627-F40YFZ/pr/review.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# PR Review

Created: 2026-05-01T17:27:30.544Z
Branch: task/202605011627-F40YFZ/ghcr-release-image

## Summary

Add GHCR release image module

Add a release module that builds and publishes a versioned GHCR image for AgentPlane and verifies the container can run the CLI.

## Scope

- In scope: Add a release module that builds and publishes a versioned GHCR image for AgentPlane and verifies the container can run the CLI.
- Out of scope: unrelated refactors not required for "Add GHCR release image module".

## Verification

### Plan

1. Run `bun run release:distribution:check`. Expected: it succeeds and confirms the requested outcome for this task.
2. Run `docker build -t agentplane:release-smoke -f packages/agentplane/Dockerfile .`. Expected: it succeeds and confirms the requested outcome for this task.
3. Review the changed artifact or behavior for the `code` task. Expected: the requested outcome is visible and matches the approved scope.
4. Compare the final result against the task summary and touched scope. Expected: remaining follow-up is either resolved or explicit in ## Findings.

### Current Status

- State: ok
- Note: GHCR release image module builds the AgentPlane container from the local release tarball artifact, pushes version/tag/latest tags in publish.yml, and uploads ghcr-module evidence.

## Risks

- Risk level: not recorded
- Breaking change: no

### Rollback

- Revert task-related commit(s).
- Re-run required checks to confirm rollback safety.

## Handoff Notes

- No handoff notes recorded yet. Use `agentplane pr note ...` to append one.

<!-- BEGIN AUTO SUMMARY -->
<details>
<summary>Raw evidence</summary>

- Updated: 2026-05-01T17:52:20.837Z
- Branch: task/202605011627-F40YFZ/ghcr-release-image
- Head: 0132bad0de07

```text
.github/workflows/publish.yml | 37 ++++
package.json | 1 +
packages/agentplane/Dockerfile | 17 ++
packages/agentplane/Dockerfile.dockerignore | 10 +
.../release/publish-workflow-contract.test.ts | 9 +
scripts/README.md | 1 +
scripts/render-ghcr-image-metadata.mjs | 203 +++++++++++++++++++++
7 files changed, 278 insertions(+)
```

</details>
<!-- END AUTO SUMMARY -->
Empty file.
37 changes: 37 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ permissions:
actions: read
contents: write
id-token: write
packages: write
pull-requests: write

concurrency:
Expand Down Expand Up @@ -331,6 +332,35 @@ jobs:
- name: Post-publish npm smoke
id: post_publish_smoke
run: bun run release:smoke:published
- name: Publish GHCR image
shell: bash
env:
GITHUB_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
node scripts/render-ghcr-image-metadata.mjs \
--manifest .agentplane/.release/publish/distribution/release-distribution.json \
--out .agentplane/.release/publish/ghcr
set -a
. .agentplane/.release/publish/ghcr/docker-build-args.env
set +a
echo "${GITHUB_TOKEN}" | docker login ghcr.io -u "${{ github.actor }}" --password-stdin
docker build \
-f packages/agentplane/Dockerfile \
--build-arg "AGENTPLANE_VERSION=${AGENTPLANE_VERSION}" \
--build-arg "AGENTPLANE_TARBALL_FILE=${AGENTPLANE_TARBALL_FILE}" \
--build-arg "AGENTPLANE_TARBALL_SHA256_FILE=${AGENTPLANE_TARBALL_SHA256_FILE}" \
-t "${GHCR_VERSION_TAG}" \
-t "${GHCR_RELEASE_TAG}" \
-t "${GHCR_LATEST_TAG}" \
.
docker push "${GHCR_VERSION_TAG}"
docker push "${GHCR_RELEASE_TAG}"
docker push "${GHCR_LATEST_TAG}"
node scripts/render-ghcr-image-metadata.mjs \
--manifest .agentplane/.release/publish/distribution/release-distribution.json \
--out .agentplane/.release/publish/ghcr \
--status published
- name: Push release tag
id: push_tag
if: steps.tag_state.outputs.tag_exists != 'true'
Expand Down Expand Up @@ -375,6 +405,13 @@ jobs:
name: scoop-module
path: .agentplane/.release/publish/scoop/
if-no-files-found: warn
- name: Upload ghcr-module artifact
if: always()
uses: actions/upload-artifact@v7
with:
name: ghcr-module
path: .agentplane/.release/publish/ghcr/
if-no-files-found: warn
- name: Write publish-result manifest
if: always()
shell: bash
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
"release:distribution:check": "node scripts/generate-release-distribution.mjs --check",
"release:homebrew:check": "node scripts/render-homebrew-formula.mjs --check",
"release:scoop:check": "node scripts/render-scoop-manifest.mjs --check",
"release:ghcr:check": "node scripts/render-ghcr-image-metadata.mjs --check",
"ci:release-extras": "bun run artifacts:check && bun run task-state:check && bun run build && bun run package:tarball:check && bun run package:install-smoke && bun run docs:cli:check && bun run docs:recipes:check && GIT_AUTHOR_NAME=agentplane-ci GIT_AUTHOR_EMAIL=agentplane-ci@example.com GIT_COMMITTER_NAME=agentplane-ci@example.com GIT_COMMITTER_EMAIL=agentplane-ci@example.com node scripts/run-vitest-suite.mjs release-ci-base && bun run coverage:workflow-suite && bun run coverage:significant-suite && GIT_AUTHOR_NAME=agentplane-ci GIT_AUTHOR_EMAIL=agentplane-ci@example.com GIT_COMMITTER_NAME=agentplane-ci@example.com GIT_COMMITTER_EMAIL=agentplane-ci@example.com bun run test:release:critical",
"release:ci-check": "bun run ci:contract && bun run ci:release-extras",
"release:prepublish:fast": "bun run release:check",
Expand Down
17 changes: 17 additions & 0 deletions packages/agentplane/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
FROM node:24-alpine

ARG AGENTPLANE_VERSION
ARG AGENTPLANE_TARBALL_FILE=.agentplane/.release/publish/ghcr/agentplane.tgz
ARG AGENTPLANE_TARBALL_SHA256_FILE=.agentplane/.release/publish/ghcr/agentplane.tgz.sha256

COPY ${AGENTPLANE_TARBALL_FILE} /tmp/agentplane.tgz
COPY ${AGENTPLANE_TARBALL_SHA256_FILE} /tmp/agentplane.tgz.sha256

RUN cd /tmp \
&& sha256sum -c agentplane.tgz.sha256 \
&& npm install -g /tmp/agentplane.tgz \
&& rm /tmp/agentplane.tgz \
&& if [ -n "${AGENTPLANE_VERSION}" ]; then agentplane --version | grep -Fx "${AGENTPLANE_VERSION}"; else agentplane --version; fi

ENTRYPOINT ["agentplane"]
CMD ["--help"]
10 changes: 10 additions & 0 deletions packages/agentplane/Dockerfile.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
*
!.agentplane/
!.agentplane/.release/
!.agentplane/.release/publish/
!.agentplane/.release/publish/ghcr/
!.agentplane/.release/publish/ghcr/agentplane.tgz
!.agentplane/.release/publish/ghcr/agentplane.tgz.sha256
!packages/
!packages/agentplane/
!packages/agentplane/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ describe("publish workflow contract", () => {
expect(workflow).toContain("node scripts/render-homebrew-formula.mjs");
expect(workflow).toContain("Render Scoop bucket manifest");
expect(workflow).toContain("node scripts/render-scoop-manifest.mjs");
expect(workflow).toContain("Publish GHCR image");
expect(workflow).toContain("node scripts/render-ghcr-image-metadata.mjs");
expect(workflow).toContain("docker login ghcr.io");
expect(workflow).toContain("docker build \\");
expect(workflow).toContain('--build-arg "AGENTPLANE_TARBALL_FILE=${AGENTPLANE_TARBALL_FILE}"');
expect(workflow).toContain('docker push "${GHCR_VERSION_TAG}"');
expect(workflow).toContain(
".agentplane/.release/publish/distribution/release-distribution.json",
);
Expand All @@ -48,6 +54,8 @@ describe("publish workflow contract", () => {
expect(workflow).toContain("path: .agentplane/.release/publish/homebrew/");
expect(workflow).toContain("name: scoop-module");
expect(workflow).toContain("path: .agentplane/.release/publish/scoop/");
expect(workflow).toContain("name: ghcr-module");
expect(workflow).toContain("path: .agentplane/.release/publish/ghcr/");
expect(workflow).toContain(
"--distribution-manifest .agentplane/.release/publish/distribution/release-distribution.json",
);
Expand All @@ -70,6 +78,7 @@ describe("publish workflow contract", () => {
expect(workflow).toContain("submodules: recursive");
expect(workflow).toContain("NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN || '' }}");
expect(workflow).toContain("NPM_TOKEN: ${{ secrets.NPM_TOKEN || '' }}");
expect(workflow).toContain("packages: write");
expect(workflow).toContain("name: Write npm auth config");
expect(workflow).toContain('if [ -n "${NODE_AUTH_TOKEN:-}" ]; then');
expect(workflow).toContain(
Expand Down
1 change: 1 addition & 0 deletions scripts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ Grouping policy: `ci`, `release`, `docs`, `test`, `coverage`, `arch`, `bench`, `
| `release:distribution:check` | `node scripts/generate-release-distribution.mjs --check` | Run release workflow: distribution check. |
| `release:distribution:generate` | `node scripts/generate-release-distribution.mjs` | Run release workflow: distribution generate. |
| `release:e2e:local` | `node scripts/run-local-release-e2e.mjs` | Run release workflow: e2e local. |
| `release:ghcr:check` | `node scripts/render-ghcr-image-metadata.mjs --check` | Run release workflow: ghcr check. |
| `release:homebrew:check` | `node scripts/render-homebrew-formula.mjs --check` | Run release workflow: homebrew check. |
| `release:parity` | `node scripts/check-release-parity.mjs` | Run release workflow: parity. |
| `release:prepublish` | `bun run release:prepublish:fast && bun run release:prepublish:heavy` | Run release workflow: prepublish. |
Expand Down
Loading