Skip to content

Commit a589a20

Browse files
ci(kiloclaw): push prod image to dev registry on every deploy (#2197)
* ci(kiloclaw): push prod image to dev registry on every deploy After building (or reusing) the prod Docker image, re-tag and push it to the dev Fly registry (kiloclaw-registry-dev) with a dev-<unix-timestamp> tag. This keeps the dev environment in sync with production images without needing a separate manual workflow run. Also writes a GitHub Step Summary with .dev.vars entries so developers can copy the values for local wrangler dev usage. * fix(ci): isolate dev image push from prod deploy Move the dev registry push into a separate job to fix two issues: 1. Registry credential conflict: the dev login overwrote prod credentials at registry.fly.io before the prod image could be pulled. The new job logs in with prod creds first to pull, then switches to dev creds to push. 2. Dev push blocking prod deploys: the dev push steps were inline in the deploy job, so a failure would block the worker deploy and Slack notification. The new push-dev-image job runs after deploy completes with continue-on-error: true, so failures are non-blocking. * ci(kiloclaw): also tag and push dev image as latest --------- Co-authored-by: kiloconnect[bot] <240665456+kiloconnect[bot]@users.noreply.github.com>
1 parent 80b1e7a commit a589a20

File tree

1 file changed

+94
-0
lines changed

1 file changed

+94
-0
lines changed

.github/workflows/deploy-kiloclaw.yml

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ jobs:
1212
runs-on: ${{ vars.RUNNER_DEFAULT_LABEL || 'ubuntu-latest' }}
1313
timeout-minutes: 30
1414
name: Deploy KiloClaw
15+
outputs:
16+
image-tag: ${{ steps.image-hash.outputs.tag }}
17+
image-hash: ${{ steps.image-hash.outputs.hash }}
18+
image-digest: ${{ steps.image-digest.outputs.digest }}
19+
openclaw-version: ${{ steps.openclaw-version.outputs.version }}
1520

1621
steps:
1722
- name: Checkout code
@@ -226,3 +231,92 @@ jobs:
226231
}
227232
]
228233
}
234+
235+
# ── Push prod image to dev registry ───────────────────────────
236+
# Runs after the production deploy completes. Copies the prod image
237+
# to the dev Fly registry so dev stays in sync automatically.
238+
# continue-on-error ensures a dev push failure never blocks prod.
239+
push-dev-image:
240+
needs: [deploy]
241+
runs-on: ${{ vars.RUNNER_DEFAULT_LABEL || 'ubuntu-latest' }}
242+
timeout-minutes: 10
243+
name: Push Dev Image
244+
continue-on-error: true
245+
246+
steps:
247+
- name: Setup Docker Buildx
248+
uses: useblacksmith/setup-docker-builder@5241b2e9423e8b1fa37ed6050ecb62d0fb9a4e38 # v1.6.0
249+
250+
# Login with prod credentials FIRST to pull the prod image
251+
- name: Login to prod Fly Registry
252+
uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0
253+
with:
254+
registry: registry.fly.io
255+
username: x
256+
password: ${{ secrets.FLY_API_TOKEN }}
257+
258+
- name: Pull prod image
259+
run: |
260+
PROD_IMAGE="registry.fly.io/kiloclaw-machines:${{ needs.deploy.outputs.image-tag }}"
261+
echo "Pulling prod image: ${PROD_IMAGE}"
262+
docker pull "${PROD_IMAGE}"
263+
264+
# Now switch to dev credentials for pushing
265+
- name: Login to dev Fly Registry
266+
uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0
267+
with:
268+
registry: registry.fly.io
269+
username: x
270+
password: ${{ secrets.FLY_DEV_API_TOKEN }}
271+
272+
- name: Generate dev image tag
273+
id: dev-tag
274+
run: |
275+
TIMESTAMP=$(date +%s)
276+
echo "tag=dev-${TIMESTAMP}" >> "$GITHUB_OUTPUT"
277+
echo "Dev tag: dev-${TIMESTAMP}"
278+
279+
- name: Tag and push to dev registry
280+
run: |
281+
PROD_IMAGE="registry.fly.io/kiloclaw-machines:${{ needs.deploy.outputs.image-tag }}"
282+
DEV_IMAGE="registry.fly.io/kiloclaw-registry-dev:${{ steps.dev-tag.outputs.tag }}"
283+
DEV_LATEST="registry.fly.io/kiloclaw-registry-dev:latest"
284+
285+
echo "Tagging as: ${DEV_IMAGE}"
286+
docker tag "${PROD_IMAGE}" "${DEV_IMAGE}"
287+
288+
echo "Tagging as: ${DEV_LATEST}"
289+
docker tag "${PROD_IMAGE}" "${DEV_LATEST}"
290+
291+
echo "Pushing to dev registry..."
292+
docker push "${DEV_IMAGE}"
293+
docker push "${DEV_LATEST}"
294+
295+
echo "✅ Pushed dev image: ${DEV_IMAGE}"
296+
echo "✅ Pushed dev latest: ${DEV_LATEST}"
297+
298+
- name: Write dev .dev.vars summary
299+
run: |
300+
TAG="${{ steps.dev-tag.outputs.tag }}"
301+
DIGEST="${{ needs.deploy.outputs.image-digest }}"
302+
OPENCLAW="${{ needs.deploy.outputs.openclaw-version }}"
303+
CONTENT="${{ needs.deploy.outputs.image-hash }}"
304+
305+
{
306+
echo ""
307+
echo "## .dev.vars entries for KiloClaw worker"
308+
echo ""
309+
echo "Add or update these in \`services/kiloclaw/.dev.vars\`, then restart wrangler dev:"
310+
echo ""
311+
echo '```'
312+
echo "FLY_IMAGE_TAG=${TAG}"
313+
if [ -n "$DIGEST" ]; then
314+
echo "FLY_IMAGE_DIGEST=${DIGEST}"
315+
fi
316+
echo "OPENCLAW_VERSION=${OPENCLAW}"
317+
echo "FLY_IMAGE_CONTENT_HASH=${CONTENT}"
318+
echo '```'
319+
echo ""
320+
echo "**Image pushed to:** \`registry.fly.io/kiloclaw-registry-dev:${TAG}\`"
321+
echo ""
322+
} >> "$GITHUB_STEP_SUMMARY"

0 commit comments

Comments
 (0)