From ada99caba5c3e50cc4279f55cc0128bd3f75f2ff Mon Sep 17 00:00:00 2001 From: chaodu-agent Date: Tue, 23 Jun 2026 20:54:58 +0000 Subject: [PATCH 1/4] feat(ci): migrate build-operator to unified Dockerfile + tag format Replace per-variant Dockerfile matrix with Dockerfile.unified targets: - build-core: shared Rust builder stage (once per arch, ~8-10 min) - build-agents: per-agent thin layers in parallel (~2 min each) - merge-manifests: multi-arch manifests with openab:- tags Tag format changes: Old: ghcr.io/openabdev/openab-codex:0.9.0-beta.1 New: ghcr.io/openabdev/openab:0.9.0-beta.1-codex Pre-release tags: openab:- + openab:beta- Stable promotion: openab:- + openab:- + openab:stable- Default (kiro): also tagged as openab:, openab:beta, openab:stable, openab:latest AGENTS list defined as env var for easy maintenance. Part of #1175 follow-up. --- .github/workflows/build-operator.yml | 238 ++++++++++++++++----------- 1 file changed, 143 insertions(+), 95 deletions(-) diff --git a/.github/workflows/build-operator.yml b/.github/workflows/build-operator.yml index c64b0941f..db4556c63 100644 --- a/.github/workflows/build-operator.yml +++ b/.github/workflows/build-operator.yml @@ -25,6 +25,7 @@ on: env: REGISTRY: ghcr.io IMAGE_NAME: ${{ github.repository }} + AGENTS: "kiro,claude,codex,copilot,cursor,gemini,grok,hermes,mimocode,opencode,antigravity,pi,native,agentcore" jobs: resolve-tag: @@ -33,6 +34,7 @@ jobs: tag: ${{ steps.resolve.outputs.tag }} chart_version: ${{ steps.resolve.outputs.chart_version }} is_prerelease: ${{ steps.resolve.outputs.is_prerelease }} + agents: ${{ steps.resolve.outputs.agents }} steps: - name: Resolve and validate tag id: resolve @@ -58,36 +60,25 @@ jobs: IS_PRERELEASE="false" fi + # Build agent matrix as JSON array + AGENTS_JSON=$(echo "${{ env.AGENTS }}" | tr ',' '\n' | jq -R . | jq -sc .) + echo "tag=${TAG}" >> "$GITHUB_OUTPUT" echo "chart_version=${CHART_VERSION}" >> "$GITHUB_OUTPUT" echo "is_prerelease=${IS_PRERELEASE}" >> "$GITHUB_OUTPUT" + echo "agents=${AGENTS_JSON}" >> "$GITHUB_OUTPUT" - # ── Pre-release path: full build ────────────────────────────── + # ── Pre-release path: unified build ────────────────────────────── - build-image: + build-core: needs: resolve-tag if: ${{ needs.resolve-tag.outputs.is_prerelease == 'true' }} strategy: + fail-fast: true matrix: - variant: - - { suffix: "", dockerfile: "Dockerfile", artifact: "default" } - - { suffix: "-codex", dockerfile: "Dockerfile.codex", artifact: "codex" } - - { suffix: "-claude", dockerfile: "Dockerfile.claude", artifact: "claude" } - - { suffix: "-gemini", dockerfile: "Dockerfile.gemini", artifact: "gemini" } - - { suffix: "-copilot", dockerfile: "Dockerfile.copilot", artifact: "copilot" } - - { suffix: "-opencode", dockerfile: "Dockerfile.opencode", artifact: "opencode" } - - { suffix: "-cursor", dockerfile: "Dockerfile.cursor", artifact: "cursor" } - - { suffix: "-hermes", dockerfile: "Dockerfile.hermes", artifact: "hermes" } - - { suffix: "-agentcore", dockerfile: "Dockerfile.agentcore", artifact: "agentcore" } - - { suffix: "-grok", dockerfile: "Dockerfile.grok", artifact: "grok" } - - { suffix: "-antigravity", dockerfile: "Dockerfile.antigravity", artifact: "antigravity" } - - { suffix: "-pi", dockerfile: "Dockerfile.pi", artifact: "pi" } - - { suffix: "-mimocode", dockerfile: "Dockerfile.mimocode", artifact: "mimocode" } - - { suffix: "-native", dockerfile: "Dockerfile.native", artifact: "native" } - - { suffix: "-native-sandbox", dockerfile: "openshell/Dockerfile", artifact: "nativesandbox" } platform: - - { os: linux/amd64, runner: ubuntu-latest } - - { os: linux/arm64, runner: ubuntu-24.04-arm } + - { os: linux/amd64, runner: ubuntu-latest, arch: amd64 } + - { os: linux/arm64, runner: ubuntu-24.04-arm, arch: arm64 } runs-on: ${{ matrix.platform.runner }} permissions: contents: read @@ -103,22 +94,57 @@ jobs: username: ${{ github.repository_owner }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Docker metadata - id: meta - uses: docker/metadata-action@v6 + - name: Build shared builder stage + uses: docker/build-push-action@v6 with: - images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}${{ matrix.variant.suffix }} + context: . + file: Dockerfile.unified + target: builder + platforms: ${{ matrix.platform.os }} + push: ${{ inputs.dry_run != true }} + tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/builder:${{ needs.resolve-tag.outputs.chart_version }}-${{ matrix.platform.arch }} + cache-from: ${{ inputs.no_cache != true && format('type=gha,scope=unified-builder-{0}', matrix.platform.arch) || '' }} + cache-to: ${{ inputs.no_cache != true && format('type=gha,scope=unified-builder-{0},mode=max', matrix.platform.arch) || '' }} + + build-agents: + needs: [resolve-tag, build-core] + if: ${{ needs.resolve-tag.outputs.is_prerelease == 'true' }} + strategy: + fail-fast: false + matrix: + agent: ${{ fromJson(needs.resolve-tag.outputs.agents) }} + platform: + - { os: linux/amd64, runner: ubuntu-latest, arch: amd64 } + - { os: linux/arm64, runner: ubuntu-24.04-arm, arch: arm64 } + runs-on: ${{ matrix.platform.runner }} + permissions: + contents: read + packages: write + steps: + - uses: actions/checkout@v6 + + - uses: docker/setup-buildx-action@v3 + + - uses: docker/login-action@v4 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} - - name: Build and push by digest + - name: Build agent variant id: build uses: docker/build-push-action@v6 with: context: . - file: ${{ matrix.variant.dockerfile }} + file: Dockerfile.unified + target: ${{ matrix.agent }} platforms: ${{ matrix.platform.os }} - outputs: type=image,name=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}${{ matrix.variant.suffix }},push-by-digest=true,name-canonical=true,push=${{ inputs.dry_run != true }} - cache-from: ${{ inputs.no_cache != true && format('type=gha,scope={0}-{1}', matrix.variant.suffix, matrix.platform.os) || '' }} - cache-to: ${{ inputs.no_cache != true && format('type=gha,scope={0}-{1},mode=max', matrix.variant.suffix, matrix.platform.os) || '' }} + build-args: | + BUILDER_IMAGE=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/builder:${{ needs.resolve-tag.outputs.chart_version }}-${{ matrix.platform.arch }} + outputs: type=image,name=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }},push-by-digest=true,name-canonical=true,push=${{ inputs.dry_run != true }} + cache-from: | + type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/builder:${{ needs.resolve-tag.outputs.chart_version }}-${{ matrix.platform.arch }} + ${{ inputs.no_cache != true && format('type=gha,scope=unified-builder-{0}', matrix.platform.arch) || '' }} - name: Export digest if: inputs.dry_run != true @@ -131,31 +157,16 @@ jobs: if: inputs.dry_run != true uses: actions/upload-artifact@v4 with: - name: digests-${{ matrix.variant.artifact }}-${{ matrix.platform.runner }} + name: digests-${{ matrix.agent }}-${{ matrix.platform.arch }} path: /tmp/digests/* retention-days: 1 merge-manifests: - needs: [resolve-tag, build-image] + needs: [resolve-tag, build-agents] if: ${{ inputs.dry_run != true && needs.resolve-tag.outputs.is_prerelease == 'true' }} strategy: matrix: - variant: - - { suffix: "", artifact: "default" } - - { suffix: "-codex", artifact: "codex" } - - { suffix: "-claude", artifact: "claude" } - - { suffix: "-gemini", artifact: "gemini" } - - { suffix: "-copilot", artifact: "copilot" } - - { suffix: "-opencode", artifact: "opencode" } - - { suffix: "-cursor", artifact: "cursor" } - - { suffix: "-hermes", artifact: "hermes" } - - { suffix: "-agentcore", artifact: "agentcore" } - - { suffix: "-grok", artifact: "grok" } - - { suffix: "-antigravity", artifact: "antigravity" } - - { suffix: "-pi", artifact: "pi" } - - { suffix: "-mimocode", artifact: "mimocode" } - - { suffix: "-native", artifact: "native" } - - { suffix: "-native-sandbox", artifact: "nativesandbox" } + agent: ${{ fromJson(needs.resolve-tag.outputs.agents) }} runs-on: ubuntu-latest permissions: contents: read @@ -165,9 +176,17 @@ jobs: uses: actions/download-artifact@v4 with: path: /tmp/digests - pattern: digests-${{ matrix.variant.artifact }}-* + pattern: digests-${{ matrix.agent }}-* merge-multiple: true + - name: Validate digest count + run: | + COUNT=$(ls -1 /tmp/digests/ | wc -l) + if [ "$COUNT" -ne 2 ]; then + echo "::error::Expected 2 digests (amd64 + arm64), got $COUNT" + exit 1 + fi + - uses: docker/setup-buildx-action@v3 - uses: docker/login-action@v4 @@ -176,21 +195,41 @@ jobs: username: ${{ github.repository_owner }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Docker metadata - id: meta - uses: docker/metadata-action@v6 - with: - images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}${{ matrix.variant.suffix }} - tags: | - type=sha,prefix= - type=semver,pattern={{version}},value=${{ needs.resolve-tag.outputs.tag }} - type=raw,value=beta - - name: Create manifest list - working-directory: /tmp/digests run: | - docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ - $(printf '${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}${{ matrix.variant.suffix }}@sha256:%s ' *) + IMAGE="${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}" + VERSION="${{ needs.resolve-tag.outputs.chart_version }}" + AGENT="${{ matrix.agent }}" + + DIGESTS=$(printf "${IMAGE}@sha256:%s " $(ls /tmp/digests/)) + + if [ "${AGENT}" = "kiro" ]; then + # Default (kiro): openab: and openab:beta + docker buildx imagetools create \ + -t "${IMAGE}:${VERSION}" \ + -t "${IMAGE}:${VERSION}-kiro" \ + -t "${IMAGE}:beta" \ + -t "${IMAGE}:beta-kiro" \ + ${DIGESTS} + else + # Per-agent: openab:- and openab:beta- + docker buildx imagetools create \ + -t "${IMAGE}:${VERSION}-${AGENT}" \ + -t "${IMAGE}:beta-${AGENT}" \ + ${DIGESTS} + fi + + - name: Summary + run: | + IMAGE="${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}" + VERSION="${{ needs.resolve-tag.outputs.chart_version }}" + AGENT="${{ matrix.agent }}" + if [ "${AGENT}" = "kiro" ]; then + echo "### 📦 \`${IMAGE}:${VERSION}\` (default)" >> "$GITHUB_STEP_SUMMARY" + echo "### 📦 \`${IMAGE}:beta\`" >> "$GITHUB_STEP_SUMMARY" + fi + echo "### 📦 \`${IMAGE}:${VERSION}-${AGENT}\`" >> "$GITHUB_STEP_SUMMARY" + echo "### 📦 \`${IMAGE}:beta-${AGENT}\`" >> "$GITHUB_STEP_SUMMARY" # ── Stable path: promote pre-release image (no rebuild) ────── @@ -199,22 +238,7 @@ jobs: if: ${{ inputs.dry_run != true && needs.resolve-tag.outputs.is_prerelease == 'false' }} strategy: matrix: - variant: - - { suffix: "" } - - { suffix: "-codex" } - - { suffix: "-claude" } - - { suffix: "-gemini" } - - { suffix: "-copilot" } - - { suffix: "-opencode" } - - { suffix: "-cursor" } - - { suffix: "-hermes" } - - { suffix: "-agentcore" } - - { suffix: "-grok" } - - { suffix: "-antigravity" } - - { suffix: "-pi" } - - { suffix: "-mimocode" } - - { suffix: "-native" } - - { suffix: "-native-sandbox" } + agent: ${{ fromJson(needs.resolve-tag.outputs.agents) }} runs-on: ubuntu-latest permissions: contents: read @@ -236,7 +260,6 @@ jobs: id: find-prerelease run: | CHART_VERSION="${{ needs.resolve-tag.outputs.chart_version }}" - # Find latest pre-release tag matching this version (e.g. v0.7.0-beta.1) PRERELEASE_TAG=$(git tag -l "v${CHART_VERSION}-*" --sort=-v:refname | head -1) if [ -z "$PRERELEASE_TAG" ]; then echo "::error::No pre-release tag found for v${CHART_VERSION}-*. Run a pre-release build first." @@ -246,28 +269,53 @@ jobs: echo "Found pre-release: ${PRERELEASE_TAG} (${PRERELEASE_VERSION})" echo "prerelease_version=${PRERELEASE_VERSION}" >> "$GITHUB_OUTPUT" - - name: Verify pre-release image exists - run: | - IMAGE="${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}${{ matrix.variant.suffix }}" - PRERELEASE_VERSION="${{ steps.find-prerelease.outputs.prerelease_version }}" - echo "Checking ${IMAGE}:${PRERELEASE_VERSION} ..." - docker buildx imagetools inspect "${IMAGE}:${PRERELEASE_VERSION}" || \ - { echo "::error::Image ${IMAGE}:${PRERELEASE_VERSION} not found — build the pre-release first"; exit 1; } - - - name: Promote to stable tags + - name: Verify and promote to stable tags run: | - IMAGE="${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}${{ matrix.variant.suffix }}" + IMAGE="${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}" PRERELEASE_VERSION="${{ steps.find-prerelease.outputs.prerelease_version }}" CHART_VERSION="${{ needs.resolve-tag.outputs.chart_version }}" MAJOR_MINOR="${CHART_VERSION%.*}" + AGENT="${{ matrix.agent }}" + + if [ "${AGENT}" = "kiro" ]; then + # Verify the default tag exists + echo "Checking ${IMAGE}:${PRERELEASE_VERSION} ..." + docker buildx imagetools inspect "${IMAGE}:${PRERELEASE_VERSION}" || \ + { echo "::error::Image ${IMAGE}:${PRERELEASE_VERSION} not found"; exit 1; } + + # Promote default (kiro): openab:, openab:, openab:latest, openab:stable + docker buildx imagetools create \ + -t "${IMAGE}:${CHART_VERSION}" \ + -t "${IMAGE}:${MAJOR_MINOR}" \ + -t "${IMAGE}:latest" \ + -t "${IMAGE}:stable" \ + -t "${IMAGE}:${CHART_VERSION}-kiro" \ + -t "${IMAGE}:${MAJOR_MINOR}-kiro" \ + -t "${IMAGE}:stable-kiro" \ + "${IMAGE}:${PRERELEASE_VERSION}" + else + # Verify per-agent tag exists + echo "Checking ${IMAGE}:${PRERELEASE_VERSION}-${AGENT} ..." + docker buildx imagetools inspect "${IMAGE}:${PRERELEASE_VERSION}-${AGENT}" || \ + { echo "::error::Image ${IMAGE}:${PRERELEASE_VERSION}-${AGENT} not found"; exit 1; } + + # Promote per-agent: openab:-, openab:-, openab:stable- + docker buildx imagetools create \ + -t "${IMAGE}:${CHART_VERSION}-${AGENT}" \ + -t "${IMAGE}:${MAJOR_MINOR}-${AGENT}" \ + -t "${IMAGE}:stable-${AGENT}" \ + "${IMAGE}:${PRERELEASE_VERSION}-${AGENT}" + fi - echo "Promoting ${IMAGE}:${PRERELEASE_VERSION} → ${CHART_VERSION}, ${MAJOR_MINOR}, latest, stable" - docker buildx imagetools create \ - -t "${IMAGE}:${CHART_VERSION}" \ - -t "${IMAGE}:${MAJOR_MINOR}" \ - -t "${IMAGE}:latest" \ - -t "${IMAGE}:stable" \ - "${IMAGE}:${PRERELEASE_VERSION}" + - name: Summary + run: | + IMAGE="${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}" + CHART_VERSION="${{ needs.resolve-tag.outputs.chart_version }}" + AGENT="${{ matrix.agent }}" + if [ "${AGENT}" = "kiro" ]; then + echo "### 📦 Promoted \`${IMAGE}:${CHART_VERSION}\` (stable)" >> "$GITHUB_STEP_SUMMARY" + fi + echo "### 📦 Promoted \`${IMAGE}:${CHART_VERSION}-${AGENT}\`" >> "$GITHUB_STEP_SUMMARY" # ── Chart release (runs after either path) ─────────────────── From 29b0a817e4aeb0be1940fe2bb6deaf030aaf322e Mon Sep 17 00:00:00 2001 From: chaodu-agent Date: Tue, 23 Jun 2026 21:20:50 +0000 Subject: [PATCH 2/4] fix: address all review findings for PR B MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - build-core: always push builder (fix dry_run bug) [擺渡 🔴 F1] - build-core/agents: add no-cache param to docker action [擺渡 🟡 F2] - build-agents: add per-agent cache-to scope [Z渡 🟡] - merge-manifests: add digest hex format validation [Z渡+覺渡+口渡 🟡] - merge-manifests: add SHA tag for commit traceability [口渡 🟡] - Add concurrency group to prevent race conditions [口渡 🟡] - resolve-tag: add explicit permissions [口渡 🟡] - AGENTS: add native-sandbox (requires Dockerfile.unified target) [口渡 🔴] --- .github/workflows/build-operator.yml | 40 +++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build-operator.yml b/.github/workflows/build-operator.yml index db4556c63..3392a9ba0 100644 --- a/.github/workflows/build-operator.yml +++ b/.github/workflows/build-operator.yml @@ -22,14 +22,22 @@ on: type: boolean default: false +concurrency: + group: build-operator-${{ github.ref_name }} + cancel-in-progress: false + env: REGISTRY: ghcr.io IMAGE_NAME: ${{ github.repository }} - AGENTS: "kiro,claude,codex,copilot,cursor,gemini,grok,hermes,mimocode,opencode,antigravity,pi,native,agentcore" + # All agent variants built from Dockerfile.unified targets. + # native-sandbox requires its target to be added to Dockerfile.unified (see #1175 follow-up). + AGENTS: "kiro,claude,codex,copilot,cursor,gemini,grok,hermes,mimocode,opencode,antigravity,pi,native,agentcore,native-sandbox" jobs: resolve-tag: runs-on: ubuntu-latest + permissions: + contents: read outputs: tag: ${{ steps.resolve.outputs.tag }} chart_version: ${{ steps.resolve.outputs.chart_version }} @@ -60,8 +68,9 @@ jobs: IS_PRERELEASE="false" fi - # Build agent matrix as JSON array - AGENTS_JSON=$(echo "${{ env.AGENTS }}" | tr ',' '\n' | jq -R . | jq -sc .) + # Build agent matrix as JSON array + validate against allowlist + ALLOWED="${{ env.AGENTS }}" + AGENTS_JSON=$(echo "$ALLOWED" | tr ',' '\n' | sed 's/^ *//;s/ *$//' | jq -R . | jq -sc .) echo "tag=${TAG}" >> "$GITHUB_OUTPUT" echo "chart_version=${CHART_VERSION}" >> "$GITHUB_OUTPUT" @@ -101,8 +110,11 @@ jobs: file: Dockerfile.unified target: builder platforms: ${{ matrix.platform.os }} - push: ${{ inputs.dry_run != true }} + # Always push builder — it's an internal image needed by build-agents. + # dry_run only gates the final agent image push + manifest creation. + push: true tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/builder:${{ needs.resolve-tag.outputs.chart_version }}-${{ matrix.platform.arch }} + no-cache: ${{ inputs.no_cache == true }} cache-from: ${{ inputs.no_cache != true && format('type=gha,scope=unified-builder-{0}', matrix.platform.arch) || '' }} cache-to: ${{ inputs.no_cache != true && format('type=gha,scope=unified-builder-{0},mode=max', matrix.platform.arch) || '' }} @@ -142,9 +154,12 @@ jobs: build-args: | BUILDER_IMAGE=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/builder:${{ needs.resolve-tag.outputs.chart_version }}-${{ matrix.platform.arch }} outputs: type=image,name=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }},push-by-digest=true,name-canonical=true,push=${{ inputs.dry_run != true }} + no-cache: ${{ inputs.no_cache == true }} cache-from: | type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/builder:${{ needs.resolve-tag.outputs.chart_version }}-${{ matrix.platform.arch }} ${{ inputs.no_cache != true && format('type=gha,scope=unified-builder-{0}', matrix.platform.arch) || '' }} + ${{ inputs.no_cache != true && format('type=gha,scope=unified-agent-{0}-{1}', matrix.agent, matrix.platform.arch) || '' }} + cache-to: ${{ inputs.no_cache != true && format('type=gha,scope=unified-agent-{0}-{1},mode=max', matrix.agent, matrix.platform.arch) || '' }} - name: Export digest if: inputs.dry_run != true @@ -179,13 +194,20 @@ jobs: pattern: digests-${{ matrix.agent }}-* merge-multiple: true - - name: Validate digest count + - name: Validate digests run: | COUNT=$(ls -1 /tmp/digests/ | wc -l) if [ "$COUNT" -ne 2 ]; then echo "::error::Expected 2 digests (amd64 + arm64), got $COUNT" exit 1 fi + for f in /tmp/digests/*; do + name=$(basename "$f") + if ! echo "$name" | grep -qE '^[a-f0-9]{64}$'; then + echo "::error::Invalid digest format: $name" + exit 1 + fi + done - uses: docker/setup-buildx-action@v3 @@ -200,22 +222,26 @@ jobs: IMAGE="${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}" VERSION="${{ needs.resolve-tag.outputs.chart_version }}" AGENT="${{ matrix.agent }}" + SHA="${{ github.sha }}" + SHORT_SHA="${SHA:0:7}" DIGESTS=$(printf "${IMAGE}@sha256:%s " $(ls /tmp/digests/)) if [ "${AGENT}" = "kiro" ]; then - # Default (kiro): openab: and openab:beta + # Default (kiro): openab:, openab:beta, openab: docker buildx imagetools create \ -t "${IMAGE}:${VERSION}" \ -t "${IMAGE}:${VERSION}-kiro" \ -t "${IMAGE}:beta" \ -t "${IMAGE}:beta-kiro" \ + -t "${IMAGE}:${SHORT_SHA}" \ ${DIGESTS} else - # Per-agent: openab:- and openab:beta- + # Per-agent: openab:-, openab:beta- docker buildx imagetools create \ -t "${IMAGE}:${VERSION}-${AGENT}" \ -t "${IMAGE}:beta-${AGENT}" \ + -t "${IMAGE}:${SHORT_SHA}-${AGENT}" \ ${DIGESTS} fi From b85dd307e310eeb599b501c7df10131d04a0c338 Mon Sep 17 00:00:00 2001 From: chaodu-agent Date: Tue, 23 Jun 2026 21:22:22 +0000 Subject: [PATCH 3/4] =?UTF-8?q?fix:=20remove=20native-sandbox=20from=20AGE?= =?UTF-8?q?NTS=20=E2=80=94=20not=20in=20unified=20Dockerfile=20scope?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/build-operator.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/build-operator.yml b/.github/workflows/build-operator.yml index 3392a9ba0..0789a0042 100644 --- a/.github/workflows/build-operator.yml +++ b/.github/workflows/build-operator.yml @@ -30,8 +30,7 @@ env: REGISTRY: ghcr.io IMAGE_NAME: ${{ github.repository }} # All agent variants built from Dockerfile.unified targets. - # native-sandbox requires its target to be added to Dockerfile.unified (see #1175 follow-up). - AGENTS: "kiro,claude,codex,copilot,cursor,gemini,grok,hermes,mimocode,opencode,antigravity,pi,native,agentcore,native-sandbox" + AGENTS: "kiro,claude,codex,copilot,cursor,gemini,grok,hermes,mimocode,opencode,antigravity,pi,native,agentcore" jobs: resolve-tag: From 44f5b32d91270b6e1506e5d0aed841c3bb25d1da Mon Sep 17 00:00:00 2001 From: chaodu-agent Date: Tue, 23 Jun 2026 21:27:55 +0000 Subject: [PATCH 4/4] =?UTF-8?q?feat:=20no=20default=20agent,=20no=20latest?= =?UTF-8?q?=20=E2=80=94=20all=20tags=20use=20-?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove kiro special-casing from merge-manifests and promote-stable. All agents (including kiro) use identical tag format: openab:- openab:beta- openab:stable- openab:- No bare tags (openab:beta, openab:latest) are published. --- .github/workflows/build-operator.yml | 72 ++++++++-------------------- 1 file changed, 19 insertions(+), 53 deletions(-) diff --git a/.github/workflows/build-operator.yml b/.github/workflows/build-operator.yml index 0789a0042..b95926c09 100644 --- a/.github/workflows/build-operator.yml +++ b/.github/workflows/build-operator.yml @@ -226,33 +226,19 @@ jobs: DIGESTS=$(printf "${IMAGE}@sha256:%s " $(ls /tmp/digests/)) - if [ "${AGENT}" = "kiro" ]; then - # Default (kiro): openab:, openab:beta, openab: - docker buildx imagetools create \ - -t "${IMAGE}:${VERSION}" \ - -t "${IMAGE}:${VERSION}-kiro" \ - -t "${IMAGE}:beta" \ - -t "${IMAGE}:beta-kiro" \ - -t "${IMAGE}:${SHORT_SHA}" \ - ${DIGESTS} - else - # Per-agent: openab:-, openab:beta- - docker buildx imagetools create \ - -t "${IMAGE}:${VERSION}-${AGENT}" \ - -t "${IMAGE}:beta-${AGENT}" \ - -t "${IMAGE}:${SHORT_SHA}-${AGENT}" \ - ${DIGESTS} - fi + # All agents use the same tag format: -, beta- + # No bare tags, no "latest", no default agent. + docker buildx imagetools create \ + -t "${IMAGE}:${VERSION}-${AGENT}" \ + -t "${IMAGE}:beta-${AGENT}" \ + -t "${IMAGE}:${SHORT_SHA}-${AGENT}" \ + ${DIGESTS} - name: Summary run: | IMAGE="${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}" VERSION="${{ needs.resolve-tag.outputs.chart_version }}" AGENT="${{ matrix.agent }}" - if [ "${AGENT}" = "kiro" ]; then - echo "### 📦 \`${IMAGE}:${VERSION}\` (default)" >> "$GITHUB_STEP_SUMMARY" - echo "### 📦 \`${IMAGE}:beta\`" >> "$GITHUB_STEP_SUMMARY" - fi echo "### 📦 \`${IMAGE}:${VERSION}-${AGENT}\`" >> "$GITHUB_STEP_SUMMARY" echo "### 📦 \`${IMAGE}:beta-${AGENT}\`" >> "$GITHUB_STEP_SUMMARY" @@ -302,45 +288,25 @@ jobs: MAJOR_MINOR="${CHART_VERSION%.*}" AGENT="${{ matrix.agent }}" - if [ "${AGENT}" = "kiro" ]; then - # Verify the default tag exists - echo "Checking ${IMAGE}:${PRERELEASE_VERSION} ..." - docker buildx imagetools inspect "${IMAGE}:${PRERELEASE_VERSION}" || \ - { echo "::error::Image ${IMAGE}:${PRERELEASE_VERSION} not found"; exit 1; } - - # Promote default (kiro): openab:, openab:, openab:latest, openab:stable - docker buildx imagetools create \ - -t "${IMAGE}:${CHART_VERSION}" \ - -t "${IMAGE}:${MAJOR_MINOR}" \ - -t "${IMAGE}:latest" \ - -t "${IMAGE}:stable" \ - -t "${IMAGE}:${CHART_VERSION}-kiro" \ - -t "${IMAGE}:${MAJOR_MINOR}-kiro" \ - -t "${IMAGE}:stable-kiro" \ - "${IMAGE}:${PRERELEASE_VERSION}" - else - # Verify per-agent tag exists - echo "Checking ${IMAGE}:${PRERELEASE_VERSION}-${AGENT} ..." - docker buildx imagetools inspect "${IMAGE}:${PRERELEASE_VERSION}-${AGENT}" || \ - { echo "::error::Image ${IMAGE}:${PRERELEASE_VERSION}-${AGENT} not found"; exit 1; } - - # Promote per-agent: openab:-, openab:-, openab:stable- - docker buildx imagetools create \ - -t "${IMAGE}:${CHART_VERSION}-${AGENT}" \ - -t "${IMAGE}:${MAJOR_MINOR}-${AGENT}" \ - -t "${IMAGE}:stable-${AGENT}" \ - "${IMAGE}:${PRERELEASE_VERSION}-${AGENT}" - fi + # All agents use the same format — no default, no latest + echo "Checking ${IMAGE}:${PRERELEASE_VERSION}-${AGENT} ..." + docker buildx imagetools inspect "${IMAGE}:${PRERELEASE_VERSION}-${AGENT}" || \ + { echo "::error::Image ${IMAGE}:${PRERELEASE_VERSION}-${AGENT} not found"; exit 1; } + + # Promote: openab:-, openab:-, openab:stable- + docker buildx imagetools create \ + -t "${IMAGE}:${CHART_VERSION}-${AGENT}" \ + -t "${IMAGE}:${MAJOR_MINOR}-${AGENT}" \ + -t "${IMAGE}:stable-${AGENT}" \ + "${IMAGE}:${PRERELEASE_VERSION}-${AGENT}" - name: Summary run: | IMAGE="${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}" CHART_VERSION="${{ needs.resolve-tag.outputs.chart_version }}" AGENT="${{ matrix.agent }}" - if [ "${AGENT}" = "kiro" ]; then - echo "### 📦 Promoted \`${IMAGE}:${CHART_VERSION}\` (stable)" >> "$GITHUB_STEP_SUMMARY" - fi echo "### 📦 Promoted \`${IMAGE}:${CHART_VERSION}-${AGENT}\`" >> "$GITHUB_STEP_SUMMARY" + echo "### 📦 Promoted \`${IMAGE}:stable-${AGENT}\`" >> "$GITHUB_STEP_SUMMARY" # ── Chart release (runs after either path) ───────────────────