-
Notifications
You must be signed in to change notification settings - Fork 4
190 lines (177 loc) · 8.38 KB
/
Copy pathbuild-images.yml
File metadata and controls
190 lines (177 loc) · 8.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# Build the four ComputerAgent images in parallel and push to AWS ECR:
# - harness-server (deploy/fullstack-base/harness-server.Dockerfile)
# - computeragent-server (examples/Dockerfile.harness)
# - agentos-server (packages/agentos-server/Dockerfile)
# - agentos-spa (agentos/Dockerfile, uses VITE_AGENTOS_DEFAULT_*)
#
# Required repo secrets (Settings → Secrets and variables → Actions → Secrets):
# AWS_ACCOUNT_ID 12-digit AWS account id
# AWS_ACCESS_KEY_ID IAM user / role key with ECR push on agentos/*
# AWS_SECRET_ACCESS_KEY paired secret
#
# Optional repo variables (Settings → Secrets and variables → Actions → Variables):
# AWS_REGION default: us-east-1
# VITE_AGENTOS_DEFAULT_HARNESS, VITE_AGENTOS_DEFAULT_SOURCE,
# VITE_AGENTOS_DEFAULT_MODEL — baked into the SPA bundle at build time
#
# Triggers:
# - push to deploy → build + push (tag: <sha>)
# - tag v* → build + push (tags: <sha>, <semver>)
# - workflow_dispatch → manual
# - pull_request to deploy → build only (no push)
#
# `deploy` is the long-lived release branch — merge feature branches into it
# when you're ready to ship to EKS. Main can move independently.
#
# ── Tag policy ──────────────────────────────────────────────────────────────
# ECR repos are IMMUTABLE, so we only ever push SHA-based tags + semver tags.
# Floating `deploy` / `main` tags would conflict with IMMUTABLE on every
# subsequent push. To roll forward: bump kustomize image tag to the new SHA.
#
# If the SHA already exists in ECR (re-run of the same commit), the workflow
# detects it and skips the build entirely → no-op success, no error.
name: build-images
on:
push:
branches: [deploy]
tags: ['v*']
pull_request:
branches: [deploy]
workflow_dispatch:
env:
AWS_REGION: ${{ vars.AWS_REGION || 'us-east-1' }}
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
strategy:
fail-fast: false
matrix:
include:
# The two harness images share examples/Dockerfile.harness — only
# the entry script differs (ENTRY build arg).
- name: harness-server
dockerfile: examples/Dockerfile.harness
entry: examples/harness-server.ts
build_args: harness
- name: computeragent-server
dockerfile: examples/Dockerfile.harness
entry: examples/computeragent-server.ts
build_args: harness
- name: agentos-server
dockerfile: packages/agentos-server/Dockerfile
build_args: ""
- name: agentos-spa
dockerfile: agentos/Dockerfile
# Build args are evaluated by docker/build-push-action's `build-args:`
# field below — we set them via vars at the step level instead.
build_args: spa
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set image tag
id: tag
run: |
SHA=$(echo "${{ github.sha }}" | cut -c1-7)
echo "sha=${SHA}" >> "$GITHUB_OUTPUT"
if [[ "${{ github.ref }}" == refs/tags/v* ]]; then
echo "semver=${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT"
fi
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Configure AWS credentials
if: github.event_name != 'pull_request'
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}
- name: Log in to Amazon ECR
if: github.event_name != 'pull_request'
uses: aws-actions/amazon-ecr-login@v2
- name: Compose image tags
id: tags
run: |
REGISTRY="${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.${{ env.AWS_REGION }}.amazonaws.com"
REPO="agentos/${{ matrix.name }}"
# ECR is IMMUTABLE → SHA-only by default, plus semver on tag pushes.
TAGS="${REGISTRY}/${REPO}:${{ steps.tag.outputs.sha }}"
if [[ -n "${{ steps.tag.outputs.semver }}" ]]; then
TAGS="${TAGS},${REGISTRY}/${REPO}:${{ steps.tag.outputs.semver }}"
fi
echo "tags=${TAGS}" >> "$GITHUB_OUTPUT"
echo "registry=${REGISTRY}" >> "$GITHUB_OUTPUT"
echo "repo=${REPO}" >> "$GITHUB_OUTPUT"
- name: Check if image already exists at this SHA
id: exists
if: github.event_name != 'pull_request'
run: |
# ECR is IMMUTABLE — if the SHA tag exists, ANY push (even the
# identical bytes) is rejected. Make re-runs idempotent by exiting
# the build cleanly when the image is already there.
if aws ecr describe-images \
--repository-name "${{ steps.tags.outputs.repo }}" \
--image-ids "imageTag=${{ steps.tag.outputs.sha }}" \
--region "${{ env.AWS_REGION }}" >/dev/null 2>&1; then
echo "skip=true" >> "$GITHUB_OUTPUT"
echo "::notice title=Skipping build::Image ${{ steps.tags.outputs.repo }}:${{ steps.tag.outputs.sha }} already exists in ECR — no rebuild needed."
else
echo "skip=false" >> "$GITHUB_OUTPUT"
fi
- name: Build and push ${{ matrix.name }} (agentos-server)
if: matrix.build_args == '' && steps.exists.outputs.skip != 'true'
uses: docker/build-push-action@v5
with:
context: .
file: ${{ matrix.dockerfile }}
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.tags.outputs.tags }}
cache-from: type=gha,scope=${{ matrix.name }}
cache-to: type=gha,mode=max,scope=${{ matrix.name }}
- name: Build and push ${{ matrix.name }} (harness variant)
if: matrix.build_args == 'harness' && steps.exists.outputs.skip != 'true'
uses: docker/build-push-action@v5
with:
context: .
file: ${{ matrix.dockerfile }}
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.tags.outputs.tags }}
build-args: |
ENTRY=${{ matrix.entry }}
cache-from: type=gha,scope=${{ matrix.name }}
cache-to: type=gha,mode=max,scope=${{ matrix.name }}
- name: Build and push agentos-spa (with VITE_ build args)
if: matrix.build_args == 'spa' && steps.exists.outputs.skip != 'true'
uses: docker/build-push-action@v5
with:
context: .
file: ${{ matrix.dockerfile }}
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.tags.outputs.tags }}
build-args: |
VITE_AGENTOS_DEFAULT_HARNESS=${{ vars.VITE_AGENTOS_DEFAULT_HARNESS || 'claude-agent-sdk' }}
VITE_AGENTOS_DEFAULT_SOURCE=${{ vars.VITE_AGENTOS_DEFAULT_SOURCE || 'github.com/shreyas-lyzr/general-agent' }}
VITE_AGENTOS_DEFAULT_MODEL=${{ vars.VITE_AGENTOS_DEFAULT_MODEL || 'claude-sonnet-4-6' }}
cache-from: type=gha,scope=${{ matrix.name }}
cache-to: type=gha,mode=max,scope=${{ matrix.name }}
- name: Summary
if: github.event_name != 'pull_request'
run: |
if [[ "${{ steps.exists.outputs.skip }}" == "true" ]]; then
echo "### ${{ matrix.name }} — skipped" >> "$GITHUB_STEP_SUMMARY"
echo "" >> "$GITHUB_STEP_SUMMARY"
echo "Image already exists at \`${{ steps.tags.outputs.repo }}:${{ steps.tag.outputs.sha }}\` — no rebuild." >> "$GITHUB_STEP_SUMMARY"
else
echo "### Pushed ${{ matrix.name }}" >> "$GITHUB_STEP_SUMMARY"
echo "" >> "$GITHUB_STEP_SUMMARY"
echo "Tags:" >> "$GITHUB_STEP_SUMMARY"
for t in $(echo "${{ steps.tags.outputs.tags }}" | tr ',' '\n'); do
echo "- \`$t\`" >> "$GITHUB_STEP_SUMMARY"
done
fi
echo "" >> "$GITHUB_STEP_SUMMARY"
echo "Bump kustomize:" >> "$GITHUB_STEP_SUMMARY"
echo '```bash' >> "$GITHUB_STEP_SUMMARY"
echo "kustomize edit set image agentos/${{ matrix.name }}=${{ steps.tags.outputs.registry }}/agentos/${{ matrix.name }}:${{ steps.tag.outputs.sha }}" >> "$GITHUB_STEP_SUMMARY"
echo '```' >> "$GITHUB_STEP_SUMMARY"