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
132 changes: 21 additions & 111 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ on:
version:
description: 'Version number'

env:
VERSION: ${{ github.event.inputs.version || github.ref_name }}
DOCKER_REGISTRY: ghcr.io

jobs:
docker:
strategy:
Expand Down Expand Up @@ -37,7 +41,7 @@ jobs:
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
registry: ${{ env.DOCKER_REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

Expand All @@ -53,22 +57,16 @@ jobs:
env:
DOCKER_BUILD_ARGS: "--push --platform linux/amd64,linux/arm64"
DOCKER_BUILDER: "docker buildx"
DOCKER_REGISTRY: "ghcr.io" # prod for releases, local for dev
run: |
# if workflow_dispatch is used, use the version input
if [ -n "${{ github.event.inputs.version }}" ]; then
export VERSION=${{ github.event.inputs.version }}
else
export VERSION=$(echo "$GITHUB_REF" | cut -c12-)
fi
make docker-${{ matrix.image }}
run: make docker-${{ matrix.image }}

release:
needs:
- docker
runs-on: ubuntu-latest
env:
HELM_PLUGIN_UNITTEST_VERSION: v1.0.3
HELM_REGISTRY: ${{ secrets.HELM_REGISTRY || 'ghcr.io' }}
HELM_REPO: ${{ secrets.HELM_REPO || 'agentregistry-dev/agentregistry' }}
permissions:
contents: write
packages: write
Expand All @@ -82,122 +80,30 @@ jobs:
with:
go-version-file: "go.mod"

- name: Resolve chart version
id: version
run: |
set -euo pipefail
CHART_VER=$(grep -E '^version:' charts/agentregistry/Chart.yaml | awk '{print $2}' | tr -d '"')
echo "chart_version=${CHART_VER}" >> "$GITHUB_OUTPUT"

if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
TARGET_VER="${{ github.event.inputs.version }}"
else
TARGET_VER="${GITHUB_REF#refs/tags/}"
TARGET_VER="${TARGET_VER#v}"
fi
echo "target_version=${TARGET_VER}" >> "$GITHUB_OUTPUT"
echo "Chart.yaml version : ${CHART_VER}"
echo "Target publish version: ${TARGET_VER}"

- name: Verify Chart.yaml version matches release version
run: |
set -euo pipefail
CHART_VER="${{ steps.version.outputs.chart_version }}"
TARGET_VER="${{ steps.version.outputs.target_version }}"
if [ "$CHART_VER" != "$TARGET_VER" ]; then
echo "::error::Chart.yaml version (${CHART_VER}) does not match release version (${TARGET_VER})."
echo "Update charts/agentregistry/Chart.yaml to version: ${TARGET_VER} before releasing."
exit 1
fi
echo "Version check passed: ${CHART_VER}"

- name: Cache Helm plugins
uses: actions/cache@v4
with:
path: ~/.local/share/helm/plugins
# Cache the helm-unittest plugin by plugin version so it's stable across chart changes
key: ${{ runner.os }}-helm-plugins-unittest-${{ env.HELM_PLUGIN_UNITTEST_VERSION }}
restore-keys: |
${{ runner.os }}-helm-plugins-unittest-

- name: Ensure helm-unittest plugin (Makefile)
run: |
set -euo pipefail
make helm-unittest-install

- name: Lint chart (Makefile)
run: make charts-lint HELM_CHART_DIR=charts/agentregistry

- name: Run chart tests (Makefile)
run: make charts-test HELM_CHART_DIR=charts/agentregistry

- name: Build Release Artifacts
- name: Log in to Helm registry
env:
DOCKER_REGISTRY: "ghcr.io" # prod for releases
run: |
# if workflow_dispatch is used, use the version input
if [ -n "${{ github.event.inputs.version }}" ]; then
export VERSION=${{ github.event.inputs.version }}
else
export VERSION=$(echo "$GITHUB_REF" | cut -c12-)
fi
make release-cli

- name: Package chart
HELM_REGISTRY_USERNAME: ${{ secrets.HELM_REGISTRY_USERNAME || github.actor }}
HELM_REGISTRY_PASSWORD: ${{ secrets.HELM_REGISTRY_PASSWORD || secrets.GITHUB_TOKEN }}
run: |
set -euo pipefail
mkdir -p build/charts
helm package charts/agentregistry -d build/charts
echo "--- packaged files ---"
ls -lh build/charts/

- name: Generate checksum
run: |
set -euo pipefail
cd build/charts
sha256sum ./*.tgz > checksums.txt
cat checksums.txt

- name: Resolve registry credentials
id: creds
run: |
# Use explicit secret if provided; fall back to built-in GITHUB_TOKEN.
if [ -n "${{ secrets.HELM_REGISTRY_PASSWORD }}" ]; then
echo "password_source=secret" >> "$GITHUB_OUTPUT"
else
echo "password_source=github_token" >> "$GITHUB_OUTPUT"
fi

- name: Log in to GHCR (OCI registry)
run: |
set -euo pipefail
REGISTRY="${{ secrets.HELM_REGISTRY || 'ghcr.io' }}"
USERNAME="${{ secrets.HELM_REGISTRY_USERNAME || github.actor }}"

if [ "${{ steps.creds.outputs.password_source }}" = "secret" ]; then
PASSWORD="${{ secrets.HELM_REGISTRY_PASSWORD }}"
else
PASSWORD="${{ secrets.GITHUB_TOKEN }}"
fi

printf "%s" "${PASSWORD}" | helm registry login "${REGISTRY}" \
--username "${USERNAME}" \
printf "%s" "${HELM_REGISTRY_PASSWORD}" | helm registry login "${HELM_REGISTRY}" \
--username "${HELM_REGISTRY_USERNAME}" \
--password-stdin
echo "Logged in to ${REGISTRY} as ${USERNAME}"

- name: Push chart to GHCR
run: |
set -euo pipefail
REGISTRY="${{ secrets.HELM_REGISTRY || 'ghcr.io' }}"
REPO="${{ secrets.HELM_REPO || 'agentregistry-dev/agentregistry' }}"
CHART_VER="${{ steps.version.outputs.chart_version }}"

for pkg in build/charts/*.tgz; do
[ -f "$pkg" ] || continue
echo "Pushing ${pkg} → oci://${REGISTRY}/${REPO}/charts/agentregistry:${CHART_VER}"
helm push "${pkg}" "oci://${REGISTRY}/${REPO}/charts"
done
- name: Build Release Artifacts
run: make release-cli

Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The release workflow now runs make charts-release, which requires envsubst (gettext) to generate Chart.yaml. There’s no step ensuring envsubst is installed on the runner, so this job can fail depending on the base image. Add an explicit install step (e.g. install gettext/gettext-base) or adjust chart generation to avoid this external dependency in CI.

Suggested change
- name: Install envsubst
run: |
sudo apt-get update
sudo apt-get install -y gettext-base

Copilot uses AI. Check for mistakes.
- name: Release Helm chart
run: make charts-release

- name: Create GitHub Release
uses: softprops/action-gh-release@v2
Expand All @@ -208,3 +114,7 @@ jobs:
bin/arctl-*
build/charts/*.tgz
build/charts/checksums.txt

- name: Log out of Helm registry
if: always()
run: helm registry logout "${HELM_REGISTRY}" || true
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,6 @@ Thumbs.db
.env.staging
.env.production

# Generated Helm chart manifest
charts/agentregistry/Chart.yaml

38 changes: 38 additions & 0 deletions DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ The fastest way to run the full stack locally is with [Kind](https://kind.sigs.k
- [Docker](https://docs.docker.com/get-docker/)
- [kubectl](https://kubernetes.io/docs/tasks/tools/)
- [Helm](https://helm.sh/docs/intro/install/)
- [envsubst](https://www.gnu.org/software/gettext/manual/html_node/envsubst-Invocation.html) (used to generate `Chart.yaml`)

> `kind` is installed automatically into `./bin/kind` by `make install-tools` — no manual installation needed.

Expand Down Expand Up @@ -36,6 +37,8 @@ make install-agentregistry
make install-agentregistry BUILD=false
```

`install-agentregistry` automatically runs `charts-generate` first (see [Helm Chart Generation](#helm-chart-generation) below), so `Chart.yaml` is always up to date before deploying.

On subsequent runs, `install-agentregistry` reuses the `jwtPrivateKey` already stored in the cluster secret so tokens remain valid across redeploys.

### Accessing the services
Expand All @@ -60,6 +63,41 @@ See [`scripts/kind/README.md`](scripts/kind/README.md) for more detail on config

---

## Helm Chart Generation

`charts/agentregistry/Chart.yaml` is **generated** from `charts/agentregistry/Chart-template.yaml` using `envsubst` and is not committed to the repository. Any `helm` command run directly against the chart directory will fail unless `Chart.yaml` exists.

### Generating Chart.yaml locally

```bash
# Generate with version derived from the latest git tag (e.g. 0.3.0)
make charts-generate

# Generate with an explicit version
make charts-generate CHART_VERSION=0.4.0
```

`CHART_VERSION` defaults to the output of `git describe --tags --abbrev=0` with the leading `v` stripped. If there are no tags, set it explicitly.

Any Makefile target that needs `Chart.yaml` (e.g. `charts-lint`, `charts-test`, `charts-package`, `install-agentregistry`) declares `charts-generate` as a prerequisite and will generate it automatically. You only need to run `make charts-generate` directly if you're invoking `helm` commands by hand.
Comment on lines +72 to +82
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default CHART_VERSION derivation described here doesn’t match the Makefile. The Makefile sets VERSION via git describe --tags --always (or a fallback) and then strips a leading v to get CHART_VERSION. This can include additional -<n>-g<sha> suffixes, and it does not use git describe --abbrev=0 as written. Please update this section to reflect the actual derivation (or change the Makefile to match the documented behavior).

Copilot uses AI. Check for mistakes.

### Adding Chart.yaml to your editor's ignore hints

Because `charts/agentregistry/Chart.yaml` is gitignored, some editors may flag it as untracked. This is expected — treat `Chart-template.yaml` as the source of truth and do not commit the generated `Chart.yaml`.

### Helm release pipeline

The full release pipeline is encapsulated in a single target:

```bash
# Requires HELM_REGISTRY_PASSWORD to be set; optionally HELM_REGISTRY_USERNAME
make charts-release CHART_VERSION=0.4.0
```

This runs in order: `charts-test` → `charts-push` (lint → package → push) → `charts-checksum`.

---

## Local Docker Compose Environment

```bash
Expand Down
67 changes: 32 additions & 35 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,12 @@ LOCALARCH ?= $(shell uname -m | sed 's/x86_64/amd64/' | sed 's/aarch64/arm64/')
## Helm / Chart settings
# Override HELM if your helm binary lives elsewhere (e.g. HELM=/usr/local/bin/helm).
HELM ?= helm
# CHART_VERSION strips the leading 'v' from VERSION for use in Chart.yaml (Helm requires semver without the prefix).
CHART_VERSION ?= $(shell echo $(VERSION) | sed 's/^v//')
HELM_CHART_DIR ?= ./charts/agentregistry
HELM_PACKAGE_DIR ?= build/charts
HELM_REGISTRY ?= ghcr.io
HELM_REPO ?= agentregistry-dev/agentregistry
# HELM_PUSH_MODE: oci (default, recommended) | repo (legacy chart repo / ChartMuseum)
HELM_PUSH_MODE ?= oci
HELM_PLUGIN_UNITTEST_URL ?= https://github.com/helm-unittest/helm-unittest
# Pin the helm-unittest plugin version for reproducibility and allow install flags
HELM_PLUGIN_UNITTEST_VERSION ?= v1.0.3
Expand Down Expand Up @@ -309,7 +309,7 @@ install-postgresql: ## Deploy standalone PostgreSQL/pgvector into the Kind clust
BUILD ?= true

.PHONY: install-agentregistry
install-agentregistry: ## Build images and Helm install AgentRegistry into the Kind cluster (BUILD=false to skip image builds)
install-agentregistry: charts-generate ## Build images and Helm install AgentRegistry into the Kind cluster (BUILD=false to skip image builds)
ifeq ($(BUILD),true)
install-agentregistry: docker-server docker-agentgateway
endif
Expand Down Expand Up @@ -412,15 +412,23 @@ _helm-check:
exit 1; \
fi

# Generate Chart.yaml from Chart-template.yaml using envsubst.
.PHONY: charts-generate
charts-generate: ## Generate Chart.yaml from Chart-template.yaml (uses CHART_VERSION, default derived from git tags)
@echo "Generating $(HELM_CHART_DIR)/Chart.yaml (version=$(CHART_VERSION))..."
CHART_VERSION=$(CHART_VERSION) envsubst '$$CHART_VERSION' \
< $(HELM_CHART_DIR)/Chart-template.yaml \
> $(HELM_CHART_DIR)/Chart.yaml
Comment on lines +415 to +421
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

charts-generate invokes envsubst but the Makefile never checks that envsubst is installed. This will currently fail with a generic "command not found" error on machines/CI images without gettext. Consider adding a preflight check (similar to _helm-check) that verifies envsubst is available and prints a clear install hint, or make ENV_SUBST ?= envsubst configurable and check that executable.

Copilot uses AI. Check for mistakes.

# Build chart dependencies (resolves Chart.yaml dependencies → charts/ subdir).
.PHONY: charts-deps
charts-deps: _helm-check ## Build Helm chart dependencies
charts-deps: charts-generate _helm-check ## Build Helm chart dependencies
@echo "Building Helm chart dependencies for $(HELM_CHART_DIR)..."
$(HELM) dependency build $(HELM_CHART_DIR)

# Lint chart with --strict so warnings are treated as errors.
.PHONY: charts-lint
charts-lint: charts-deps ## Lint the Helm chart with --strict
charts-lint: charts-generate charts-deps ## Lint the Helm chart with --strict
@echo "Linting Helm chart $(HELM_CHART_DIR)..."
$(HELM) lint $(HELM_CHART_DIR) --strict

Expand All @@ -437,47 +445,40 @@ charts-render-test: charts-deps ## Render chart templates as a smoke test

# Package the chart into $(HELM_PACKAGE_DIR)/.
.PHONY: charts-package
charts-package: charts-lint ## Package the Helm chart into $(HELM_PACKAGE_DIR)
charts-package: charts-generate charts-lint ## Package the Helm chart into $(HELM_PACKAGE_DIR)
@mkdir -p $(HELM_PACKAGE_DIR)
@echo "Packaging chart $(HELM_CHART_DIR) → $(HELM_PACKAGE_DIR)/"
$(HELM) package $(HELM_CHART_DIR) -d $(HELM_PACKAGE_DIR)
@echo "Packaged chart(s):"
@ls -1 $(HELM_PACKAGE_DIR)/*.tgz

# Push packaged chart(s) to an OCI registry.
# Credentials are read from the environment at runtime (never stored in the Makefile):
# HELM_REGISTRY_USERNAME – registry username (default: your shell $USER)
# HELM_REGISTRY_PASSWORD – registry password / token (required)
# Package the chart and push to an OCI registry. Caller must be logged in.
# Override registry/repo: make charts-push HELM_REGISTRY=ghcr.io HELM_REPO=org/repo
.PHONY: charts-push
charts-push: charts-package ## Push packaged charts to the configured registry
@echo "Pushing chart(s) to $(HELM_REGISTRY)/$(HELM_REPO)/charts (mode: $(HELM_PUSH_MODE))"
ifeq ($(HELM_PUSH_MODE),oci)
@if [ -z "$$HELM_REGISTRY_PASSWORD" ]; then \
echo "ERROR: HELM_REGISTRY_PASSWORD is not set. Export it before running this target."; \
exit 1; \
fi
@printf "%s" "$$HELM_REGISTRY_PASSWORD" | $(HELM) registry login $(HELM_REGISTRY) \
--username "$${HELM_REGISTRY_USERNAME:-$$USER}" \
--password-stdin
@for pkg in $(HELM_PACKAGE_DIR)/*.tgz; do \
[ -f "$$pkg" ] || continue; \
echo " Pushing $$pkg → oci://$(HELM_REGISTRY)/$(HELM_REPO)/charts"; \
$(HELM) push "$$pkg" "oci://$(HELM_REGISTRY)/$(HELM_REPO)/charts"; \
done
@$(HELM) registry logout $(HELM_REGISTRY) || true
else
@echo "Non-OCI push (mode=$(HELM_PUSH_MODE)) — implement repo-specific push logic or use chart-releaser."
@exit 1
endif
charts-push: charts-package _helm-check ## Package and push chart to the configured OCI registry
@echo "Pushing $(HELM_PACKAGE_DIR)/agentregistry-$(CHART_VERSION).tgz → oci://$(HELM_REGISTRY)/$(HELM_REPO)/charts"
$(HELM) push "$(HELM_PACKAGE_DIR)/agentregistry-$(CHART_VERSION).tgz" "oci://$(HELM_REGISTRY)/$(HELM_REPO)/charts"

# Generate SHA-256 checksums for all packaged chart files.
.PHONY: charts-checksum
charts-checksum: ## Generate SHA-256 checksum for the packaged chart in $(HELM_PACKAGE_DIR)
sha256sum "$(HELM_PACKAGE_DIR)/agentregistry-$(CHART_VERSION).tgz" > "$(HELM_PACKAGE_DIR)/checksums.txt"
@echo "--- checksum ---"
@cat $(HELM_PACKAGE_DIR)/checksums.txt

# Full Helm release pipeline: test → push (→ lint → package → generate + deps) → checksum.
# Required env vars for the push step: HELM_REGISTRY_PASSWORD (and optionally HELM_REGISTRY_USERNAME).
# Override version: make charts-release CHART_VERSION=1.2.3
Comment on lines +470 to +471
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comments for charts-release mention required env vars for the push step (e.g. HELM_REGISTRY_PASSWORD), but charts-push no longer performs a helm registry login and doesn't read these env vars. Either restore an explicit login/logout in charts-push (using those env vars) or update the comments/docs to state that the caller must be logged in before running charts-push/charts-release to avoid confusion.

Suggested change
# Required env vars for the push step: HELM_REGISTRY_PASSWORD (and optionally HELM_REGISTRY_USERNAME).
# Override version: make charts-release CHART_VERSION=1.2.3
# Caller must be logged in to the Helm OCI registry before running charts-push/charts-release.
# For example: HELM_REGISTRY_USERNAME=... HELM_REGISTRY_PASSWORD=... helm registry login $(HELM_REGISTRY)

Copilot uses AI. Check for mistakes.
.PHONY: charts-release
charts-release: charts-test charts-push charts-checksum ## Full Helm release: lint, test, package, checksum, and push
Comment on lines +469 to +473
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

charts-release: charts-test charts-push charts-checksum is described as an ordered pipeline, but Make does not guarantee prerequisite execution order under parallel builds (make -j), and charts-checksum does not depend on charts-package/charts-push to ensure the .tgz exists. To make this robust, enforce sequencing in the charts-release recipe (invoke sub-targets in order) or add explicit dependencies (e.g. charts-checksum: charts-package) and/or mark the target(s) .NOTPARALLEL.

Copilot uses AI. Check for mistakes.

# Run helm-unittest against charts/agentregistry/tests/*.
# This target:
# 1. checks that 'helm' is present (fails with a clear message if not)
# 2. checks for the helm-unittest plugin and installs it if missing
# 3. runs the full test suite
.PHONY: charts-test
charts-test: _helm-check charts-deps helm-unittest-install ## Run helm-unittest chart tests
charts-test: charts-generate _helm-check charts-deps helm-unittest-install ## Run helm-unittest chart tests
@echo "Running helm-unittest on $(HELM_CHART_DIR)..."
$(HELM) unittest $(HELM_CHART_DIR) --file "tests/*_test.yaml"

Expand All @@ -500,7 +501,3 @@ helm-unittest-install: _helm-check ## Install the helm-unittest plugin if needed
echo "helm-unittest plugin already installed"; \
fi

# Convenience: package → push → test.
.PHONY: charts-all
charts-all: charts-push charts-test ## Package, push, and test the Helm chart
@echo "charts-all complete: packaged, pushed, and tested."
Loading
Loading