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
39 changes: 36 additions & 3 deletions .github/workflows/build-thailand.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,15 @@ jobs:
permissions:
contents: read
packages: write
# Required for keyless Cosign signing (only used on the build path): the
# job exchanges its OIDC token with Sigstore's public-good Fulcio for a
# short-lived signing cert, recorded in the Rekor transparency log. No
# long-lived signing keys are stored anywhere.
id-token: write

steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Check out
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
# Build from the same commit the base image was built from on the
# workflow_run path; otherwise the pushed / dispatched ref.
Expand Down Expand Up @@ -131,17 +137,27 @@ jobs:
echo "moving=${moving}"
} >> "$GITHUB_OUTPUT"

- uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0
- name: Set up Buildx
if: ${{ steps.resolve.outputs.proceed == 'true' }}
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0

- uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
- name: Install Cosign
if: ${{ steps.resolve.outputs.proceed == 'true' }}
uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # v4.1.2
with:
# v3.x is keyless-by-default (Sigstore public-good Fulcio + Rekor).
cosign-release: 'v3.1.1'

- name: Log in to GHCR
if: ${{ steps.resolve.outputs.proceed == 'true' }}
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build and push (overlay)
id: build
if: ${{ steps.resolve.outputs.proceed == 'true' }}
uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0
with:
Expand All @@ -158,3 +174,20 @@ jobs:
sbom: false
cache-from: type=gha
cache-to: type=gha,mode=max

# Sign the overlay manifest by digest. Both pushed tags (sha-<short> and
# the moving tag) resolve to it, so one signing call covers them — and a
# later release that PROMOTES this digest inherits the signature.
# Verify with:
# cosign verify ghcr.io/eternisai/agent-sandbox-thailand@<digest> \
# --certificate-identity-regexp \
# '^https://github.com/EternisAI/agent-sandbox/.github/workflows/build-thailand.yml@.*$' \
# --certificate-oidc-issuer https://token.actions.githubusercontent.com
- name: Sign image with Cosign
if: ${{ steps.resolve.outputs.proceed == 'true' }}
env:
DIGEST: ${{ steps.build.outputs.digest }}
IMAGE: ${{ steps.resolve.outputs.thai }}
run: |
set -euo pipefail
cosign sign --yes "${IMAGE}@${DIGEST}"
40 changes: 36 additions & 4 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,31 @@ jobs:
permissions:
contents: read
packages: write
# Required for keyless Cosign signing: the job exchanges its OIDC token
# with Sigstore's public-good Fulcio for a short-lived signing cert, and
# the signature is recorded in the Rekor transparency log. No long-lived
# signing keys are stored anywhere.
id-token: write

steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Check out
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
# Only docker push (via login-action) follows — never git; keep
# GITHUB_TOKEN out of .git/config.
persist-credentials: false

- uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0
- name: Set up Buildx
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0

- uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
- name: Install Cosign
uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # v4.1.2
with:
# v3.x is keyless-by-default (Sigstore public-good Fulcio + Rekor).
cosign-release: 'v3.1.1'

- name: Log in to GHCR
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
Expand Down Expand Up @@ -107,6 +121,23 @@ jobs:
cache-from: type=gha
cache-to: type=gha,mode=max

# Sign the manifest by digest. Cosign attaches the signature to the
# digest, so every tag that resolves to it (sha-<short> and the moving
# tag) is covered by this single signing call — and a later release that
# PROMOTES this digest (oras tag) inherits the signature for free.
# Verify with:
# cosign verify ghcr.io/eternisai/agent-sandbox@<digest> \
# --certificate-identity-regexp \
# '^https://github.com/EternisAI/agent-sandbox/.github/workflows/build.yml@.*$' \
# --certificate-oidc-issuer https://token.actions.githubusercontent.com
- name: Sign image with Cosign
env:
DIGEST: ${{ steps.build.outputs.digest }}
IMAGE: ${{ steps.meta.outputs.image }}
run: |
set -euo pipefail
cosign sign --yes "${IMAGE}@${DIGEST}"

- name: Write deploy-info
run: |
set -euo pipefail
Expand All @@ -128,7 +159,8 @@ jobs:
}
EOF

- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
- name: Upload deploy-info
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: deploy-info
path: deploy-info/deploy-info.json
Expand Down
6 changes: 4 additions & 2 deletions .github/workflows/deploy-thailand.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,13 @@ jobs:
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ secrets.GITHUB_TOKEN }}

- uses: oras-project/setup-oras@38de303aac69abb66f3e6255b7198bff35f323e3 # v2.0.0
- name: Set up ORAS
uses: oras-project/setup-oras@38de303aac69abb66f3e6255b7198bff35f323e3 # v2.0.0

# oras reads ~/.docker/config.json, which docker/login-action writes — so
# the manifest fetch below is authenticated against GHCR with no extra login.
- uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
- name: Log in to GHCR
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
Expand Down
57 changes: 51 additions & 6 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,21 +39,37 @@ jobs:
permissions:
contents: read
packages: write
# Required for keyless Cosign signing of the fallback build paths: the job
# exchanges its OIDC token with Sigstore's public-good Fulcio for a
# short-lived signing cert, recorded in the Rekor transparency log. No
# long-lived signing keys are stored anywhere. (A PROMOTED image needs no
# re-signing — see the promote steps below.)
id-token: write

steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Check out
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
# Only docker/oras push (via login-action) follows — never git; keep
# GITHUB_TOKEN out of .git/config.
persist-credentials: false

- uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0
- name: Set up Buildx
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0

- uses: oras-project/setup-oras@38de303aac69abb66f3e6255b7198bff35f323e3 # v2.0.0
- name: Set up ORAS
uses: oras-project/setup-oras@38de303aac69abb66f3e6255b7198bff35f323e3 # v2.0.0

- name: Install Cosign
uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # v4.1.2
with:
# v3.x is keyless-by-default (Sigstore public-good Fulcio + Rekor).
cosign-release: 'v3.1.1'

# docker/login-action writes ~/.docker/config.json, which oras reads by
# default — so oras is authenticated against GHCR without a separate login.
- uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
- name: Log in to GHCR
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
Expand All @@ -72,6 +88,10 @@ jobs:
} >> "$GITHUB_OUTPUT"

# ---- Regular image: promote the existing sha- image, else fall back to build.
# A promote (oras tag) only adds the <ver> tag to the SAME manifest digest
# that build.yml already signed with Cosign, so the signature carries
# forward and the promoted image needs no re-signing. Only the fallback
# build (a brand-new, never-signed manifest) is signed below.
- name: Promote regular image
id: regular
env:
Expand Down Expand Up @@ -113,6 +133,18 @@ jobs:
cache-from: type=gha
cache-to: type=gha,mode=max

# Sign only on the fallback build (a fresh manifest); a promoted image is
# already signed via build.yml (see the promote note above). Signing by
# digest covers both pushed tags (sha-<short> and <ver>).
- name: Sign regular image with Cosign
if: ${{ steps.regular.outputs.mode == 'build' }}
env:
DIGEST: ${{ steps.regular_build.outputs.digest }}
IMAGE: ${{ steps.meta.outputs.image }}
run: |
set -euo pipefail
cosign sign --yes "${IMAGE}@${DIGEST}"

- name: Resolve regular digest
id: regular_digest
env:
Expand Down Expand Up @@ -168,6 +200,17 @@ jobs:
cache-from: type=gha
cache-to: type=gha,mode=max

# Sign only on the fallback build; a promoted thai image is already signed
# via build-thailand.yml. Signing by digest covers both pushed tags.
- name: Sign thai image with Cosign
if: ${{ steps.thai.outputs.mode == 'build' }}
env:
DIGEST: ${{ steps.thai_build.outputs.digest }}
IMAGE: ${{ steps.meta.outputs.thai }}
run: |
set -euo pipefail
cosign sign --yes "${IMAGE}@${DIGEST}"

- name: Resolve thai digest
id: thai_digest
env:
Expand Down Expand Up @@ -196,13 +239,15 @@ jobs:
{ "image": "${THAI}", "tag": "${VER}", "digest": "${THAI_DIGEST}", "git_sha": "${GITHUB_SHA}", "ref": "${GITHUB_REF}", "environment": "siam-ai" }
EOF

- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
- name: Upload deploy-info (production)
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: deploy-info-production
path: deploy-info/production.json
retention-days: 7

- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
- name: Upload deploy-info (siam-ai)
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: deploy-info-siam-ai
path: deploy-info/siam-ai.json
Expand Down
15 changes: 10 additions & 5 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@ jobs:
plugin-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Check out
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
# Test jobs never push via git; keep GITHUB_TOKEN out of .git/config.
persist-credentials: false

- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
- name: Set up Node.js
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
# Keep in sync with the Node major+minor pinned in Dockerfile.
# Bumping here without bumping the Dockerfile (or vice-versa)
Expand All @@ -27,7 +29,8 @@ jobs:
# so disable setup-node's v5+ automatic package-manager caching.
package-manager-cache: false

- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
- name: Set up Python
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: '3.12'

Expand All @@ -44,12 +47,14 @@ jobs:
docker-build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Check out
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
# Test jobs never push via git; keep GITHUB_TOKEN out of .git/config.
persist-credentials: false

- uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0
- name: Set up Buildx
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0

# Build-only check: catches Dockerfile syntax errors, broken apt/npm/pip
# pins, and missing files referenced by COPY before they land on main.
Expand Down