Skip to content
Open
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
101 changes: 71 additions & 30 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,70 +10,111 @@ concurrency:
cancel-in-progress: false

jobs:
release:
determine-version:
runs-on: ubuntu-latest
outputs:
version: ${{ steps.version.outputs.version }}
steps:
- name: Determine version
id: version
run: |
if [[ "${GITHUB_REF}" == refs/tags/v* ]]; then
echo "version=${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT"
else
echo "version=main" >> "$GITHUB_OUTPUT"
fi

build-images:
needs: determine-version
strategy:
matrix:
arch: [amd64, arm64]
runs-on: ${{ matrix.arch == 'arm64' && 'ubuntu-24.04-arm' || 'ubuntu-latest' }}
permissions:
contents: write
contents: read
packages: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- uses: actions/setup-go@v5
with:
go-version-file: go.mod

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

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

- name: Determine version
id: version
run: |
if [[ "${GITHUB_REF}" == refs/tags/v* ]]; then
echo "version=${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT"
else
echo "version=main" >> "$GITHUB_OUTPUT"
fi

- name: Build images
- name: Build and push image
env:
VERSION: ${{ steps.version.outputs.version }}
run: make image VERSION="$VERSION"
VERSION: ${{ needs.determine-version.outputs.version }}
run: make image IMAGE_PLATFORMS=linux/${{ matrix.arch }} PUSH=true VERSION="$VERSION-${{ matrix.arch }}"

- name: Push images
merge-manifests:
needs: [determine-version, build-images]
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

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

- name: Create and push multi-arch manifests
env:
VERSION: ${{ steps.version.outputs.version }}
run: make push VERSION="$VERSION"
VERSION: ${{ needs.determine-version.outputs.version }}
run: make manifest IMAGE_PLATFORMS=linux/amd64,linux/arm64 VERSION="$VERSION"

- name: Push latest tags for releases
- name: Create and push latest manifests
if: startsWith(github.ref, 'refs/tags/v')
run: |
make image VERSION=latest
make push VERSION=latest
env:
VERSION: ${{ needs.determine-version.outputs.version }}
run: make manifest IMAGE_PLATFORMS=linux/amd64,linux/arm64 VERSION=latest

release-artifacts:
needs: [determine-version, merge-manifests]
if: startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- uses: actions/setup-go@v5
with:
go-version-file: go.mod

- name: Build CLI binaries
if: startsWith(github.ref, 'refs/tags/v')
env:
VERSION: ${{ steps.version.outputs.version }}
VERSION: ${{ needs.determine-version.outputs.version }}
run: make release-binaries VERSION="$VERSION"

- name: Generate release notes
if: startsWith(github.ref, 'refs/tags/v')
env:
GH_TOKEN: ${{ github.token }}
VERSION: ${{ steps.version.outputs.version }}
VERSION: ${{ needs.determine-version.outputs.version }}
run: go run ./hack/release-notes "$VERSION" > /tmp/release-notes.md

- name: Upload CLI binaries to GitHub release
if: startsWith(github.ref, 'refs/tags/v')
env:
GH_TOKEN: ${{ github.token }}
VERSION: ${{ steps.version.outputs.version }}
VERSION: ${{ needs.determine-version.outputs.version }}
run: |
gh release create "$VERSION" --verify-tag --draft --title "$VERSION" --notes-file /tmp/release-notes.md || true
gh release upload "$VERSION" --clobber \
Expand All @@ -83,7 +124,7 @@ jobs:
publish-helm-chart:
if: startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-latest
needs: release
needs: release-artifacts
permissions:
contents: read
packages: write
Expand Down
32 changes: 28 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
REGISTRY ?= ghcr.io/kelos-dev
VERSION ?= latest
IMAGE_DIRS ?= cmd/kelos-controller cmd/kelos-spawner cmd/kelos-token-refresher claude-code codex gemini opencode cursor
LOCAL_ARCH ?= $(shell go env GOARCH)

# Version injection for the kelos CLI – only set ldflags when an explicit
# version is given so that dev builds fall through to runtime/debug info.
Expand Down Expand Up @@ -79,14 +80,37 @@ build: ## Build binaries (use WHAT=cmd/kelos to build specific binary).
run: ## Run a controller from your host.
go run ./cmd/kelos-controller

IMAGE_PLATFORMS ?= linux/$(LOCAL_ARCH)
IMAGE_ARCHES = $(shell echo "$(IMAGE_PLATFORMS)" | tr ',' '\n' | cut -d'/' -f2 | tr '\n' ' ')
PUSH ?= false

.PHONY: image
image: ## Build docker images (use WHAT to build specific image).
image: ## Build docker images (use WHAT, IMAGE_PLATFORMS, PUSH=true to customize).
@for dir in $(filter cmd/%,$(or $(WHAT),$(IMAGE_DIRS))); do \
GOOS=linux GOARCH=amd64 $(MAKE) build WHAT=$$dir; \
name=$$(basename $$dir); \
for arch in $(IMAGE_ARCHES); do \
GOOS=linux GOARCH=$$arch $(MAKE) build WHAT=$$dir; \
mv bin/$$name bin/$${name}-linux-$$arch; \
done; \
done
@for arch in $(IMAGE_ARCHES); do \
GOOS=linux GOARCH=$$arch $(MAKE) build WHAT=cmd/kelos-capture; \
mv bin/kelos-capture bin/kelos-capture-linux-$$arch; \
done
@GOOS=linux GOARCH=amd64 $(MAKE) build WHAT=cmd/kelos-capture
@for dir in $(or $(WHAT),$(IMAGE_DIRS)); do \
docker build -t $(REGISTRY)/$$(basename $$dir):$(VERSION) -f $$dir/Dockerfile .; \
docker buildx build --platform $(IMAGE_PLATFORMS) \
$(if $(filter true,$(PUSH)),--push,--load) \
-t $(REGISTRY)/$$(basename $$dir):$(VERSION) \
-f $$dir/Dockerfile .; \
done

.PHONY: manifest
manifest: ## Create and push multi-arch manifest from per-arch images (use WHAT, IMAGE_PLATFORMS).
@for dir in $(or $(WHAT),$(IMAGE_DIRS)); do \
name=$$(basename $$dir); \
docker buildx imagetools create \
-t $(REGISTRY)/$$name:$(VERSION) \
$(foreach arch,$(IMAGE_ARCHES),$(REGISTRY)/$$name:$(VERSION)-$(arch) ); \
done

.PHONY: push
Expand Down
3 changes: 2 additions & 1 deletion claude-code/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ RUN npm install -g @anthropic-ai/claude-code@${CLAUDE_CODE_VERSION}
COPY claude-code/kelos_entrypoint.sh /kelos_entrypoint.sh
RUN chmod +x /kelos_entrypoint.sh

COPY bin/kelos-capture /kelos/kelos-capture
ARG TARGETARCH
COPY bin/kelos-capture-linux-${TARGETARCH} /kelos/kelos-capture

RUN useradd -u 61100 -m -s /bin/bash claude
RUN mkdir -p /home/claude/.claude && chown -R claude:claude /home/claude
Expand Down
3 changes: 2 additions & 1 deletion cmd/kelos-controller/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
FROM gcr.io/distroless/static:nonroot
ARG TARGETARCH
WORKDIR /
COPY bin/kelos-controller .
COPY bin/kelos-controller-linux-${TARGETARCH} kelos-controller
USER 65532:65532
ENTRYPOINT ["/kelos-controller"]
3 changes: 2 additions & 1 deletion cmd/kelos-spawner/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
FROM gcr.io/distroless/static:nonroot
ARG TARGETARCH
WORKDIR /
COPY bin/kelos-spawner .
COPY bin/kelos-spawner-linux-${TARGETARCH} kelos-spawner
USER 65532:65532
ENTRYPOINT ["/kelos-spawner"]
3 changes: 2 additions & 1 deletion codex/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ RUN npm install -g @openai/codex@${CODEX_VERSION}
COPY codex/kelos_entrypoint.sh /kelos_entrypoint.sh
RUN chmod +x /kelos_entrypoint.sh

COPY bin/kelos-capture /kelos/kelos-capture
ARG TARGETARCH
COPY bin/kelos-capture-linux-${TARGETARCH} /kelos/kelos-capture

RUN useradd -u 61100 -m -s /bin/bash agent
RUN mkdir -p /home/agent/.codex && chown -R agent:agent /home/agent
Expand Down
3 changes: 2 additions & 1 deletion cursor/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ ENV PATH="/usr/local/go/bin:${PATH}"
COPY cursor/kelos_entrypoint.sh /kelos_entrypoint.sh
RUN chmod +x /kelos_entrypoint.sh

COPY bin/kelos-capture /kelos/kelos-capture
ARG TARGETARCH
COPY bin/kelos-capture-linux-${TARGETARCH} /kelos/kelos-capture

RUN useradd -u 61100 -m -s /bin/bash agent
RUN mkdir -p /home/agent/.cursor && chown -R agent:agent /home/agent
Expand Down
3 changes: 2 additions & 1 deletion gemini/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ RUN npm install -g @google/gemini-cli@${GEMINI_CLI_VERSION}
COPY gemini/kelos_entrypoint.sh /kelos_entrypoint.sh
RUN chmod +x /kelos_entrypoint.sh

COPY bin/kelos-capture /kelos/kelos-capture
ARG TARGETARCH
COPY bin/kelos-capture-linux-${TARGETARCH} /kelos/kelos-capture

RUN useradd -u 61100 -m -s /bin/bash agent
RUN mkdir -p /home/agent/.gemini && chown -R agent:agent /home/agent
Expand Down
3 changes: 2 additions & 1 deletion opencode/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ RUN npm install -g opencode-ai@${OPENCODE_VERSION}
COPY opencode/kelos_entrypoint.sh /kelos_entrypoint.sh
RUN chmod +x /kelos_entrypoint.sh

COPY bin/kelos-capture /kelos/kelos-capture
ARG TARGETARCH
COPY bin/kelos-capture-linux-${TARGETARCH} /kelos/kelos-capture

RUN useradd -u 61100 -m -s /bin/bash agent
RUN mkdir -p /home/agent/.opencode && chown -R agent:agent /home/agent
Expand Down
Loading