Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
e513642
feat(sandbox): k8s deployment manifests for agent-sandbox runner
pedrofrxncx Apr 28, 2026
49f16e0
chore: update helm chart and workflows for agent-sandbox
pedrofrxncx Apr 28, 2026
ae3a0dd
feat(agent-sandbox): introduce Helm chart for agent-sandbox operator
pedrofrxncx Apr 28, 2026
f0b7693
docs(agent-sandbox): enhance README.md for Helm chart usage and struc…
pedrofrxncx Apr 28, 2026
555c83c
chore: update Helm chart values and documentation
pedrofrxncx Apr 28, 2026
16b93e6
feat(agent-sandbox): consolidate controller Deployments in Helm chart
pedrofrxncx Apr 28, 2026
0befc09
chore(sandbox): drop deploy/k8s-sandbox/ local dev tooling and monito…
pedrofrxncx Apr 28, 2026
61fffec
chore: remove outdated agent-sandbox runner documentation and streaml…
pedrofrxncx Apr 28, 2026
55e182e
chore: clean up README.md by removing unnecessary whitespace
pedrofrxncx Apr 28, 2026
808e37f
chore(sandbox): drop stale k8s-sandbox/ comments and rename MESH_SAND…
pedrofrxncx Apr 29, 2026
30b0bb9
chore: add Helm chart validation and CI workflow for agent-sandbox
pedrofrxncx Apr 29, 2026
0b45176
chore: migrate agent-sandbox to sandbox-operator and sandbox-env Helm…
pedrofrxncx Apr 29, 2026
803c339
fix(sandbox-operator): re-apply PodSecurity labels in vendor.sh
pedrofrxncx Apr 29, 2026
4df1ce6
feat(sandbox): add shared build cache PVC to sandbox-env chart
pedrofrxncx Apr 29, 2026
5ddd3f5
feat(sandbox): enhance shared build cache functionality in sandbox-env
pedrofrxncx Apr 29, 2026
4b54ab0
refactor(sandbox): improve shallow clone handling in git mirror setup
pedrofrxncx Apr 29, 2026
dd07d10
fix(sandbox): improve error handling for cache and clone operations
pedrofrxncx Apr 29, 2026
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
8 changes: 8 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Vendored upstream YAML for kubernetes-sigs/agent-sandbox (operator + CRDs).
# Refreshed via deploy/helm/sandbox-operator/vendor.sh — do not hand-edit.
# Marking as generated so GitHub collapses the diff in PRs and excludes it
# from language stats; bumps are still reviewable by reading vendor.sh's
# version arg. The sandbox-env chart's templates are first-party and stay
# reviewable.
deploy/helm/sandbox-operator/crds/** linguist-generated=true
deploy/helm/sandbox-operator/templates/agent-sandbox-manifest.yaml linguist-generated=true
139 changes: 139 additions & 0 deletions .github/workflows/helm-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
name: Helm chart checks

# PR-scoped lint + render + vendor-drift checks for the Helm charts. The
# release workflows (release-sandbox-charts.yaml, publish-chart.yml) are
# publish-only — without this gate, a helpers typo or a hand-edit to
# vendored CRDs ships straight to consumers. Runs on every PR that touches
# deploy/helm/** so reviewers see render failures inline.

on:
pull_request:
paths:
- 'deploy/helm/**'
- '.github/workflows/helm-test.yml'
workflow_dispatch:

jobs:
sandbox-operator:
name: sandbox-operator chart
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Set up Helm
uses: azure/setup-helm@v4
with:
version: v3.16.4

- name: Lint
# The chart's namespace validation (templates/validations.yaml)
# requires `agent-sandbox-system`. Pass it here so render-time
# checks during lint don't see the wrong namespace.
run: helm lint deploy/helm/sandbox-operator --namespace agent-sandbox-system

- name: Render
run: |
helm template sandbox-operator deploy/helm/sandbox-operator \
--namespace agent-sandbox-system \
> /dev/null

# Catches hand-edits to crds/ or templates/agent-sandbox-manifest.yaml
# that bypass vendor.sh. The .gitattributes linguist-generated marker
# collapses those files in PR review, so without this gate a manual
# tweak would slip through unnoticed.
- name: Vendor drift check
run: |
set -euo pipefail
bash deploy/helm/sandbox-operator/vendor.sh
if ! git diff --exit-code -- \
deploy/helm/sandbox-operator/crds \
deploy/helm/sandbox-operator/templates/agent-sandbox-manifest.yaml; then
echo "::error::Vendored files differ from vendor.sh output. Re-run deploy/helm/sandbox-operator/vendor.sh and commit the result."
exit 1
fi

sandbox-env:
name: sandbox-env chart
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Set up Helm
uses: azure/setup-helm@v4
with:
version: v3.16.4

- name: Lint
# envName is required, so lint must pass it. Use a representative
# value rather than `Release.Name` because helm lint doesn't drive
# render with a release name.
run: |
helm lint deploy/helm/sandbox-env \
--namespace agent-sandbox-system \
--set envName=ci

- name: Render (default values)
run: |
helm template sandbox-env deploy/helm/sandbox-env \
--namespace agent-sandbox-system \
--set envName=ci \
> /dev/null

- name: Render (preview gateway enabled)
run: |
helm template sandbox-env deploy/helm/sandbox-env \
--namespace agent-sandbox-system \
--set envName=ci \
--set previewGateway.enabled=true \
--set previewGateway.domain=preview.example.com \
--set previewGateway.clusterIssuer=letsencrypt-prod \
--api-versions gateway.networking.k8s.io/v1 \
--api-versions cert-manager.io/v1 \
> /dev/null

- name: Render (warm pool enabled)
run: |
helm template sandbox-env deploy/helm/sandbox-env \
--namespace agent-sandbox-system \
--set envName=ci \
--set warmPool.enabled=true \
--set warmPool.size=2 \
> /dev/null

- name: Render (envName missing must fail)
run: |
set +e
helm template sandbox-env deploy/helm/sandbox-env \
--namespace agent-sandbox-system \
> /tmp/render.out 2>&1
rc=$?
set -e
if [ "${rc}" -eq 0 ]; then
echo "::error::sandbox-env rendered without envName — required-value check is missing."
cat /tmp/render.out
exit 1
fi
if ! grep -q "envName is required" /tmp/render.out; then
echo "::error::sandbox-env failed for the wrong reason — expected envName-required error."
cat /tmp/render.out
exit 1
fi

studio:
name: studio chart
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Set up Helm
uses: azure/setup-helm@v4
with:
version: v3.16.4

- name: Lint
run: helm lint deploy/helm/studio

# Subchart .tgz files are vendored under deploy/helm/studio/charts/
# (see .gitignore comment) — no `helm dependency build` needed.
- name: Render
run: helm template deco-studio deploy/helm/studio > /dev/null
6 changes: 3 additions & 3 deletions .github/workflows/publish-chart.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ on:
branches:
- main
paths:
- 'deploy/helm/Chart.yaml'
- 'deploy/helm/studio/Chart.yaml'

jobs:
publish:
Expand All @@ -22,13 +22,13 @@ jobs:

- name: Get chart version
id: chart
run: echo "version=$(grep '^version:' deploy/helm/Chart.yaml | awk '{print $2}')" >> $GITHUB_OUTPUT
run: echo "version=$(grep '^version:' deploy/helm/studio/Chart.yaml | awk '{print $2}')" >> $GITHUB_OUTPUT

- name: Login to GHCR
run: helm registry login ghcr.io -u ${{ github.actor }} -p ${{ secrets.GITHUB_TOKEN }}

- name: Package chart
run: helm package deploy/helm/ --dependency-update
run: helm package deploy/helm/studio/ --dependency-update

- name: Push chart to GHCR
run: helm push chart-deco-studio-${{ steps.chart.outputs.version }}.tgz oci://ghcr.io/decocms
Expand Down
165 changes: 165 additions & 0 deletions .github/workflows/release-sandbox-charts.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
name: Release sandbox Helm charts

on:
push:
branches: [main]
paths:
- "deploy/helm/sandbox-operator/**"
- "deploy/helm/sandbox-env/**"
workflow_dispatch:

env:
REGISTRY: ghcr.io
# OCI charts in ghcr.io live at <registry>/<owner>/<name>:<tag>. Helm
# treats the parent path as the "repo" (here ghcr.io/decocms/studio/charts)
# and the chart name+version as ref. Argo CD's helm source supports this
# natively via repoURL=<registry>/<owner>/<name> + chart=<chart-name>.
OCI_REPO: oci://ghcr.io/${{ github.repository }}/charts

jobs:
release:
name: Package & push ${{ matrix.chart }}
runs-on: ubuntu-latest
# Run sandbox-operator and sandbox-env in parallel — independent OCI
# tags, no shared mutable state.
strategy:
fail-fast: false
matrix:
chart: [sandbox-operator, sandbox-env]
# `[release]:` commits come from the auto-bump bot and don't actually
# change chart contents — skip them so we don't republish the same
# version.
if: ${{ !startsWith(github.event.head_commit.message, '[release]:') }}
permissions:
contents: read
packages: write
# OIDC token for keyless cosign signing (Sigstore Fulcio).
id-token: write
# Required to attach SLSA provenance attestations.
attestations: write

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Helm
uses: azure/setup-helm@v4
with:
version: v3.16.4

- name: Read chart version
id: version
env:
CHART_PATH: deploy/helm/${{ matrix.chart }}
run: |
set -euo pipefail
VERSION=$(awk '/^version:/{print $2; exit}' "${CHART_PATH}/Chart.yaml")
NAME=$(awk '/^name:/{print $2; exit}' "${CHART_PATH}/Chart.yaml")
echo "version=${VERSION}" >> "${GITHUB_OUTPUT}"
echo "name=${NAME}" >> "${GITHUB_OUTPUT}"
echo "path=${CHART_PATH}" >> "${GITHUB_OUTPUT}"
echo "::notice::Chart ${NAME} version ${VERSION}"

- name: Log in to GitHub Container Registry
run: |
echo "${{ secrets.GITHUB_TOKEN }}" | \
helm registry login "${REGISTRY}" \
--username "${{ github.actor }}" \
--password-stdin

# Skip republishing if the version tag already exists. Without this
# guard, every push to main that touches the chart silently mutates
# the chart under a tag consumers may already be pinning.
- name: Check if chart version already exists
id: tag-check
run: |
set -euo pipefail
# `helm show chart` against an OCI ref hits the registry; success
# means the tag is published.
if helm show chart "${OCI_REPO}/${{ steps.version.outputs.name }}" \
--version "${{ steps.version.outputs.version }}" \
>/dev/null 2>&1; then
echo "exists=true" >> "${GITHUB_OUTPUT}"
echo "::notice::Chart ${{ steps.version.outputs.name }}-${{ steps.version.outputs.version }} already published — skipping. Bump ${{ steps.version.outputs.path }}/Chart.yaml version to publish."
else
echo "exists=false" >> "${GITHUB_OUTPUT}"
fi

- name: Package chart
if: steps.tag-check.outputs.exists != 'true'
id: package
run: |
set -euo pipefail
helm package "${{ steps.version.outputs.path }}" --destination dist
PACKAGE="dist/${{ steps.version.outputs.name }}-${{ steps.version.outputs.version }}.tgz"
echo "package=${PACKAGE}" >> "${GITHUB_OUTPUT}"

- name: Push chart to OCI registry
if: steps.tag-check.outputs.exists != 'true'
id: push
run: |
set -euo pipefail
PUSH_OUT=$(helm push "${{ steps.package.outputs.package }}" "${OCI_REPO}" 2>&1)
echo "${PUSH_OUT}"
DIGEST=$(echo "${PUSH_OUT}" | awk '/Digest:/{print $2}')
if [ -z "${DIGEST}" ]; then
echo "::error::Could not extract digest from helm push output"
exit 1
fi
echo "digest=${DIGEST}" >> "${GITHUB_OUTPUT}"

# Keyless cosign signing for parity with the image release workflow.
# Verifies provenance via Sigstore's public transparency log without
# long-lived keys. Verify downstream with:
# cosign verify ghcr.io/decocms/studio/charts/<chart>:<tag> \
# --certificate-identity-regexp 'https://github.com/decocms/studio/.*' \
# --certificate-oidc-issuer https://token.actions.githubusercontent.com
- name: Install cosign
if: steps.tag-check.outputs.exists != 'true'
uses: sigstore/cosign-installer@v3

- name: Sign chart with cosign
if: steps.tag-check.outputs.exists != 'true'
env:
DIGEST: ${{ steps.push.outputs.digest }}
NAME: ${{ steps.version.outputs.name }}
VERSION: ${{ steps.version.outputs.version }}
run: |
set -euo pipefail
REF="${{ env.REGISTRY }}/${{ github.repository }}/charts/${NAME}@${DIGEST}"
cosign sign --yes "${REF}"

- name: Generate SLSA build provenance
if: steps.tag-check.outputs.exists != 'true'
uses: actions/attest-build-provenance@v2
with:
subject-name: ${{ env.REGISTRY }}/${{ github.repository }}/charts/${{ steps.version.outputs.name }}
subject-digest: ${{ steps.push.outputs.digest }}
push-to-registry: true

- name: Release summary
if: steps.tag-check.outputs.exists != 'true'
run: |
{
echo "## Helm chart published"
echo ""
echo "**${{ steps.version.outputs.name }} ${{ steps.version.outputs.version }}**"
echo ""
echo "### Install"
echo '```bash'
if [ "${{ matrix.chart }}" = "sandbox-operator" ]; then
echo "helm install sandbox-operator ${OCI_REPO}/${{ steps.version.outputs.name }} \\"
echo " --version ${{ steps.version.outputs.version }} \\"
echo " --namespace agent-sandbox-system --create-namespace"
else
echo "helm install sandbox-env-<envName> ${OCI_REPO}/${{ steps.version.outputs.name }} \\"
echo " --version ${{ steps.version.outputs.version }} \\"
echo " --namespace agent-sandbox-system \\"
echo " --set envName=<envName> \\"
echo " --set mesh.namespace=<studio-namespace> \\"
echo " --set mesh.serviceAccountName=<studio-release-name> \\"
echo " --set mesh.serviceName=<studio-release-name> \\"
echo " --set mesh.servicePort=80"
fi
echo '```'
} >> "${GITHUB_STEP_SUMMARY}"
Loading
Loading