Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 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
10 changes: 10 additions & 0 deletions .github/actions/build-base-image-platform/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@
name: build-base-image-platform
description: Build and publish one immutable base image digest for a platform.

outputs:
amd64-digest:
description: Exact amd64 digest when this action built the amd64 lane.
value: ${{ steps.job-output.outputs.amd64_digest }}
arm64-digest:
description: Exact arm64 digest when this action built the arm64 lane.
value: ${{ steps.job-output.outputs.arm64_digest }}

inputs:
agent:
description: Agent identifier used for build arguments and artifact names.
Expand Down Expand Up @@ -129,6 +137,7 @@ runs:
'test -x /usr/bin/dos2unix; test "$(command -v dos2unix)" = /usr/bin/dos2unix; dos2unix --version >/dev/null'

- name: Export platform digest
id: job-output
shell: bash
env:
ARCH: ${{ inputs.arch }}
Expand All @@ -145,6 +154,7 @@ runs:
fi
mkdir -p "$RUNNER_TEMP/digests"
touch "$RUNNER_TEMP/digests/${ARCH}-${DIGEST#sha256:}"
printf '%s_digest=%s\n' "$ARCH" "$DIGEST" >> "$GITHUB_OUTPUT"

- name: Upload platform digest
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
Expand Down
50 changes: 44 additions & 6 deletions .github/actions/publish-base-image-manifest/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,21 @@
name: publish-base-image-manifest
description: Validate platform digests and publish one multi-platform base image manifest.

outputs:
contract-base64:
description: Exact validated base-image contract for dependent jobs.
value: ${{ steps.contract-output.outputs.contract_base64 }}

inputs:
agent:
description: Agent identifier stored in the managed base image contract.
required: true
amd64-digest:
description: Exact amd64 platform digest from the producer job.
required: true
arm64-digest:
description: Exact arm64 platform digest from the producer job.
required: true
display-name:
description: Agent name used in validation errors.
required: true
Expand All @@ -27,12 +38,23 @@ inputs:
runs:
using: composite
steps:
- name: Download platform digests
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
pattern: ${{ inputs.agent }}-base-digest-${{ github.run_id }}-${{ github.run_attempt }}-*
path: ${{ runner.temp }}/digests
merge-multiple: true
- name: Restore exact platform digests
shell: bash
env:
AMD64_DIGEST: ${{ inputs.amd64-digest }}
ARM64_DIGEST: ${{ inputs.arm64-digest }}
run: |
set -euo pipefail
for digest in "$AMD64_DIGEST" "$ARM64_DIGEST"; do
[[ "$digest" =~ ^sha256:[0-9a-f]{64}$ ]] || {
echo "ERROR: base-image producer output has an invalid digest." >&2
exit 1
}
done
digest_root="$RUNNER_TEMP/digests"
install -d -m 0700 "$digest_root"
touch "$digest_root/amd64-${AMD64_DIGEST#sha256:}"
touch "$digest_root/arm64-${ARM64_DIGEST#sha256:}"

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0
Expand Down Expand Up @@ -65,6 +87,22 @@ runs:
IMAGE: ${{ inputs.registry }}/${{ inputs.image }}
TAGS: ${{ steps.meta.outputs.tags }}
run: bash "$GITHUB_ACTION_PATH/publish.sh"
- name: Export managed base image contract
id: contract-output
shell: bash
run: |
set -euo pipefail
contract="$RUNNER_TEMP/managed-base-contract/contract.json"
if [ ! -f "$contract" ] || [ -L "$contract" ]; then
echo "ERROR: managed base image contract is missing or unsafe." >&2
exit 1
fi
contract_size="$(wc -c < "$contract" | tr -d '[:space:]')"
if [[ ! "$contract_size" =~ ^[1-9][0-9]{0,5}$ ]] || [ "$contract_size" -gt 65536 ]; then
echo "ERROR: managed base image contract is empty or oversized." >&2
exit 1
fi
printf 'contract_base64=%s\n' "$(base64 -w 0 "$contract")" >> "$GITHUB_OUTPUT"
- name: Upload managed base image contract
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
Expand Down
40 changes: 40 additions & 0 deletions .github/workflows/base-image.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,9 @@ jobs:
- reviewed-npm-audit
runs-on: ${{ matrix.runner }}
timeout-minutes: 60
outputs:
amd64-digest: ${{ steps.platform.outputs.amd64-digest }}
arm64-digest: ${{ steps.platform.outputs.arm64-digest }}
strategy:
fail-fast: false
matrix:
Expand All @@ -150,6 +153,7 @@ jobs:
persist-credentials: false

- name: Build and publish platform digest
id: platform
uses: ./.github/actions/build-base-image-platform
with:
agent: ${{ matrix.agent }}
Expand Down Expand Up @@ -177,6 +181,9 @@ jobs:
- reviewed-npm-audit
runs-on: ${{ matrix.runner }}
timeout-minutes: 60
outputs:
amd64-digest: ${{ steps.platform.outputs.amd64-digest }}
arm64-digest: ${{ steps.platform.outputs.arm64-digest }}
strategy:
fail-fast: false
matrix:
Expand All @@ -202,6 +209,7 @@ jobs:
persist-credentials: false

- name: Build and publish platform digest
id: platform
uses: ./.github/actions/build-base-image-platform
with:
agent: ${{ matrix.agent }}
Expand All @@ -221,6 +229,9 @@ jobs:
- reviewed-npm-audit
runs-on: ${{ matrix.runner }}
timeout-minutes: 60
outputs:
amd64-digest: ${{ steps.platform.outputs.amd64-digest }}
arm64-digest: ${{ steps.platform.outputs.arm64-digest }}
strategy:
fail-fast: false
matrix:
Expand All @@ -246,6 +257,7 @@ jobs:
persist-credentials: false

- name: Build and publish platform digest
id: platform
uses: ./.github/actions/build-base-image-platform
with:
agent: ${{ matrix.agent }}
Expand All @@ -268,6 +280,9 @@ jobs:
- reviewed-npm-audit
runs-on: ${{ matrix.runner }}
timeout-minutes: 60
outputs:
amd64-digest: ${{ steps.platform.outputs.amd64-digest }}
arm64-digest: ${{ steps.platform.outputs.arm64-digest }}
strategy:
fail-fast: false
matrix:
Expand All @@ -290,6 +305,7 @@ jobs:
with:
persist-credentials: false
- name: Build and publish platform digest
id: platform
uses: ./.github/actions/build-base-image-platform
with:
agent: ${{ matrix.agent }}
Expand All @@ -308,15 +324,20 @@ jobs:
- reviewed-npm-audit
runs-on: ubuntu-latest
timeout-minutes: 10
outputs:
contract-base64: ${{ steps.publish.outputs.contract-base64 }}
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Publish validated multi-platform manifest
id: publish
uses: ./.github/actions/publish-base-image-manifest
with:
agent: pi
amd64-digest: ${{ needs.build-pi-platforms.outputs.amd64-digest }}
arm64-digest: ${{ needs.build-pi-platforms.outputs.arm64-digest }}
display-name: Pi
image: nvidia/nemoclaw/pi-sandbox-base
registry: ${{ env.REGISTRY }}
Expand All @@ -330,16 +351,21 @@ jobs:
- reviewed-npm-audit
runs-on: ubuntu-latest
timeout-minutes: 10
outputs:
contract-base64: ${{ steps.publish.outputs.contract-base64 }}
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

- name: Publish validated multi-platform manifest
id: publish
uses: ./.github/actions/publish-base-image-manifest
with:
agent: hermes
amd64-digest: ${{ needs.build-hermes-platforms.outputs.amd64-digest }}
arm64-digest: ${{ needs.build-hermes-platforms.outputs.arm64-digest }}
display-name: Hermes
image: nvidia/nemoclaw/hermes-sandbox-base
registry: ${{ env.REGISTRY }}
Expand All @@ -355,16 +381,21 @@ jobs:
- reviewed-npm-audit
runs-on: ubuntu-latest
timeout-minutes: 10
outputs:
contract-base64: ${{ steps.publish.outputs.contract-base64 }}
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

- name: Publish validated multi-platform manifest
id: publish
uses: ./.github/actions/publish-base-image-manifest
with:
agent: langchain-deepagents-code
amd64-digest: ${{ needs.build-dcode-platforms.outputs.amd64-digest }}
arm64-digest: ${{ needs.build-dcode-platforms.outputs.arm64-digest }}
display-name: Deep Agents Code
image: nvidia/nemoclaw/langchain-deepagents-code-sandbox-base
registry: ${{ env.REGISTRY }}
Expand All @@ -382,16 +413,21 @@ jobs:
- reviewed-npm-audit
runs-on: ubuntu-latest
timeout-minutes: 10
outputs:
contract-base64: ${{ steps.publish.outputs.contract-base64 }}
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

- name: Publish validated multi-platform manifest
id: publish
uses: ./.github/actions/publish-base-image-manifest
with:
agent: openclaw
amd64-digest: ${{ needs.build-openclaw-platforms.outputs.amd64-digest }}
arm64-digest: ${{ needs.build-openclaw-platforms.outputs.arm64-digest }}
display-name: OpenClaw
image: nvidia/nemoclaw/sandbox-base
registry: ${{ env.REGISTRY }}
Expand All @@ -417,3 +453,7 @@ jobs:
contents: read
packages: write
uses: ./.github/workflows/managed-images.yaml
with:
dcode-base-contract-base64: ${{ needs.build-and-push-dcode.outputs.contract-base64 }}
hermes-base-contract-base64: ${{ needs.build-and-push-hermes.outputs.contract-base64 }}
openclaw-base-contract-base64: ${{ needs.build-and-push-openclaw.outputs.contract-base64 }}
Loading
Loading