Skip to content
Draft
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
135 changes: 135 additions & 0 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

name: release

on:
workflow_dispatch:
inputs:
tag:
description: 'Image tag (e.g. v1.2.3-rc1). Leave blank to auto-generate from branch+SHA.'
required: false
create_release:
description: 'Create a GitHub release'
type: boolean
default: false

permissions:
contents: write
packages: write

jobs:
release:
runs-on: ubuntu-latest

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

- name: Validate and resolve tag
id: tag
run: |
TAG="${{ inputs.tag }}"
if [[ -z "${TAG}" ]]; then
BRANCH="${GITHUB_REF_NAME//\//-}"
SHA="$(git rev-parse --short HEAD)"
TAG="${BRANCH}-${SHA}"
fi
if [[ "${{ inputs.create_release }}" == "true" ]]; then
if [[ ! "${TAG}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9._-]+)?$ ]]; then
echo "::error::Tag '${TAG}' must match vMAJOR.MINOR.PATCH[-prerelease] when creating a release (e.g. v1.2.3 or v1.2.3-rc1)"
exit 1
fi
fi
echo "value=${TAG}" >> "$GITHUB_OUTPUT"
if [[ "${{ inputs.create_release }}" == "true" ]]; then
echo "tags=${TAG},latest" >> "$GITHUB_OUTPUT"
else
echo "tags=${TAG}" >> "$GITHUB_OUTPUT"
fi

- name: Setup Go
uses: actions/setup-go@v5
with:
go-version-file: 'go.mod'

- name: Install ko
uses: ko-build/setup-ko@v0.7

- name: Install Helm
uses: azure/setup-helm@v4

- name: Log in to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Set up QEMU (multi-arch)
uses: docker/setup-qemu-action@v3

- name: Build and push images
env:
# ghcr.io/<owner>/<repo> — resolves correctly in forks
IMAGE_REPOSITORY: ghcr.io/${{ github.repository }}
IMAGE_TAGS: ${{ steps.tag.outputs.tags }}
run: |
set -o errexit -o nounset -o pipefail

for component in ateapi atecontroller atelet ateom-gvisor podcertcontroller atenet; do
KO_DOCKER_REPO="${IMAGE_REPOSITORY}/${component}" \
./hack/run-tool.sh ko build \
--tags "${IMAGE_TAGS}" \
--platform linux/amd64,linux/arm64 \
--bare \
"./cmd/${component}"
done

- name: Package and push Helm charts
if: inputs.create_release
env:
HELM_EXPERIMENTAL_OCI: "1"
CHART_REPOSITORY: oci://ghcr.io/kagent-dev/substrate/helm
run: |
set -o errexit -o nounset -o pipefail

tag="${{ steps.tag.outputs.value }}"
chart_version="${tag#v}"
package_dir="${RUNNER_TEMP}/helm-packages"
mkdir -p "${package_dir}"

echo "${{ secrets.GITHUB_TOKEN }}" \
| helm registry login ghcr.io \
--username "${{ github.actor }}" \
--password-stdin

helm package charts/substrate-crds \
--destination "${package_dir}" \
--version "${chart_version}" \
--app-version "${tag}"
helm package charts/substrate \
--destination "${package_dir}" \
--version "${chart_version}" \
--app-version "${tag}"

helm push "${package_dir}/substrate-crds-${chart_version}.tgz" "${CHART_REPOSITORY}"
helm push "${package_dir}/substrate-${chart_version}.tgz" "${CHART_REPOSITORY}"

- name: Create GitHub Release
if: inputs.create_release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ steps.tag.outputs.value }}
generate_release_notes: true
3 changes: 3 additions & 0 deletions .ko.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,6 @@ defaultPlatforms:
baseImageOverrides:
github.com/agent-substrate/substrate/demos/sandbox: alpine
github.com/agent-substrate/substrate/demos/agent-secret: alpine

x-agentgatewayEgressBaseImageOverrides:
github.com/agent-substrate/substrate/cmd/ateom-gvisor: cr.agentgateway.dev/agentgateway:latest-dev
25 changes: 21 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,11 @@ build: build-images build-atectl

.PHONY: build-images
build-images:
$(KO) build --ldflags "$(LDFLAGS)" ./cmd/ateapi
$(KO) build --ldflags "$(LDFLAGS)" ./cmd/atelet
$(KO) build --ldflags "$(LDFLAGS)" ./cmd/podcertcontroller
$(KO) build --ldflags "$(LDFLAGS)" ./cmd/atenet
$(KO) build --base-import-paths --ldflags "$(LDFLAGS)" ./cmd/ateapi
$(KO) build --base-import-paths --ldflags "$(LDFLAGS)" ./cmd/atecontroller
$(KO) build --base-import-paths --ldflags "$(LDFLAGS)" ./cmd/atelet
$(KO) build --base-import-paths --ldflags "$(LDFLAGS)" ./cmd/podcertcontroller
$(KO) build --base-import-paths --ldflags "$(LDFLAGS)" ./cmd/atenet

.PHONY: build-atectl
build-atectl:
Expand Down Expand Up @@ -92,3 +93,19 @@ verify: test
.PHONY: clean
clean:
rm -rf $(BINDIR)

# Render the substrate Helm chart into manifests/ate-install/ (mTLS mode,
# the historical default install). Run this whenever charts/substrate/ changes.
.PHONY: helm-template
helm-template:
@./hack/render-manifests.sh

# Verify that manifests/ate-install/ matches the chart output. Used in CI.
.PHONY: verify-helm-template
verify-helm-template:
@./hack/render-manifests.sh --check

# Verify that the CRD chart mirrors the generated CRDs.
.PHONY: verify-crd-chart
verify-crd-chart:
@./hack/verify/crd-chart.sh
21 changes: 18 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,10 @@ To quickly set up the complete environment:
2. Run the following steps:
```shell
# create cluster and local registry
hack/create-kind-cluster.sh
KIND_ENABLE_PODCERT=false hack/create-kind-cluster.sh

# install ate, valkey, rustfs
hack/install-ate-kind.sh --deploy-ate-system
# install ate, valkey, rustfs using Helm in JWT mode
hack/install-ate-kind-jwt.sh

# install counter demo
hack/install-ate-kind.sh --deploy-demo-counter
Expand All @@ -126,6 +126,21 @@ kubectl port-forward -n ate-system svc/atenet-router 8000:80
curl -X POST -H "Host: my-counter-1.actors.resources.substrate.ate.dev" -i http://localhost:8000/
```

#### mTLS mode

JWT mode is the default install path and does not require pod certificate
feature gates. To test the older mTLS path, create kind with the
`ClusterTrustBundle` / `PodCertificateRequest` feature gates enabled and use the
mTLS install helper.

```shell
# create cluster WITH podcert feature gates
hack/create-kind-cluster.sh

# install ate using the mTLS manifests path
hack/install-ate-kind.sh --deploy-ate-system
```

### GKE Quickstart (Development)

1. Create and configure your environment file:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,17 @@
# See the License for the specific language governing permissions and
# limitations under the License.

apiVersion: v1
kind: Namespace
metadata:
name: ate-system
apiVersion: v2
name: substrate-crds
description: Agent Substrate CustomResourceDefinitions.
type: application
version: 0.1.0
appVersion: "0.1.0"
home: https://github.com/agent-substrate/substrate
sources:
- https://github.com/agent-substrate/substrate
keywords:
- agent
- actor
- substrate
- crds
13 changes: 13 additions & 0 deletions charts/substrate-crds/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# substrate-crds

Helm chart for installing the Agent Substrate CRDs.

Install this chart before installing the main `substrate` chart:

```bash
helm upgrade --install substrate-crds ./charts/substrate-crds
helm upgrade --install substrate ./charts/substrate --namespace ate-system --create-namespace
```

The CRD YAMLs in `templates/` mirror `manifests/ate-install/generated/`.
Run `hack/verify/crd-chart.sh` to verify they are in sync.
Loading