diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 9601165fa4..fe7dc1e6c3 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -17,9 +17,9 @@ on: required: false type: string default: "" - # Daily staging build from the staging branch + # Staging build from the staging branch every hour schedule: - - cron: '0 6 * * *' + - cron: '0 * * * *' env: IMAGE_NAME: nearaidev/ironclaw @@ -40,6 +40,13 @@ jobs: ref: ${{ github.event_name == 'schedule' && 'staging' || '' }} persist-credentials: false + - name: Resolve source git commit + id: source_sha + run: | + SOURCE_SHA="$(git rev-parse HEAD)" + echo "sha=${SOURCE_SHA}" >> "$GITHUB_OUTPUT" + echo "Source commit: ${SOURCE_SHA}" + - name: Extract version from Cargo.toml id: version run: | @@ -53,8 +60,9 @@ jobs: VERSION: ${{ steps.version.outputs.version }} EVENT_NAME: ${{ github.event_name }} INPUT_TAG: ${{ inputs.tag }} + SOURCE_SHA: ${{ steps.source_sha.outputs.sha }} run: | - SHA="sha-${GITHUB_SHA::7}" + SHA="sha-${SOURCE_SHA::7}" echo "sha_tag=${SHA}" >> "$GITHUB_OUTPUT" if [[ "${EVENT_NAME}" == "workflow_call" ]]; then @@ -92,39 +100,75 @@ jobs: echo "target=runtime" >> "$GITHUB_OUTPUT" fi - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3 - - name: Log in to Docker Hub uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3 with: username: ${{ vars.DOCKER_REGISTRY_USER }} password: ${{ secrets.DOCKER_REGISTRY_TOKEN }} + - name: Check if current staging commit is already built + id: check + if: steps.tags.outputs.target == 'runtime-staging' + env: + SOURCE_SHA: ${{ steps.source_sha.outputs.sha }} + run: | + CURRENT_BUILT_SHA="" + WORKER_BUILT_SHA="" + + if docker pull "${IMAGE_NAME}:staging" > /dev/null 2>&1; then + CURRENT_BUILT_SHA=$(docker inspect --format='{{index .Config.Labels "ironclaw.git.sha"}}' "${IMAGE_NAME}:staging" 2>/dev/null || echo "") + fi + if docker pull "${WORKER_IMAGE_NAME}:staging" > /dev/null 2>&1; then + WORKER_BUILT_SHA=$(docker inspect --format='{{index .Config.Labels "ironclaw.git.sha"}}' "${WORKER_IMAGE_NAME}:staging" 2>/dev/null || echo "") + fi + + echo "Current built commit (ironclaw): ${CURRENT_BUILT_SHA:-}" + echo "Current built commit (ironclaw-worker): ${WORKER_BUILT_SHA:-}" + echo "Current source commit: ${SOURCE_SHA}" + + if [[ -n "${CURRENT_BUILT_SHA}" && "${CURRENT_BUILT_SHA}" == "${SOURCE_SHA}" && -n "${WORKER_BUILT_SHA}" && "${WORKER_BUILT_SHA}" == "${SOURCE_SHA}" ]]; then + echo "skip=true" >> "$GITHUB_OUTPUT" + echo "Current commit already built for both images — skipping." + else + echo "skip=false" >> "$GITHUB_OUTPUT" + echo "At least one image is missing or out of date — proceeding." + fi + + - name: Set up Docker Buildx + if: steps.check.outputs.skip != 'true' + uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3 + - name: Build and push (ironclaw) + if: steps.check.outputs.skip != 'true' uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6 with: context: . push: true tags: ${{ steps.tags.outputs.tags }} target: ${{ steps.tags.outputs.target }} + labels: | + ironclaw.git.sha=${{ steps.source_sha.outputs.sha }} platforms: linux/amd64 cache-from: type=gha cache-to: type=gha,mode=max - name: Build and push (ironclaw-worker) + if: steps.check.outputs.skip != 'true' uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6 with: context: . file: Dockerfile.worker push: true tags: ${{ steps.tags.outputs.worker_tags }} + labels: | + ironclaw.git.sha=${{ steps.source_sha.outputs.sha }} platforms: linux/amd64 cache-from: type=gha,scope=worker cache-to: type=gha,mode=max,scope=worker - name: Create releases-manager app token id: app-token + if: steps.check.outputs.skip != 'true' continue-on-error: true uses: actions/create-github-app-token@fee1f7d63c2ff003460e3d139729b119787bc349 # v2 with: @@ -134,7 +178,7 @@ jobs: repositories: ironclaw-dind - name: Trigger ironclaw-dind Build & Push - if: steps.app-token.outcome == 'success' + if: steps.app-token.outcome == 'success' && steps.check.outputs.skip != 'true' continue-on-error: true env: GH_TOKEN: ${{ steps.app-token.outputs.token }} @@ -154,6 +198,7 @@ jobs: fi - name: Summary + if: steps.check.outputs.skip != 'true' run: | { echo "## Docker Images" @@ -169,5 +214,15 @@ jobs: echo '```' echo "" echo "- version: \`${{ steps.version.outputs.version }}\`" - echo "- sha: \`${GITHUB_SHA::7}\`" + echo "- sha: \`${{ steps.source_sha.outputs.sha }}\`" + } >> "$GITHUB_STEP_SUMMARY" + + - name: Summary (skipped) + if: steps.check.outputs.skip == 'true' + run: | + { + echo "## Docker Images — skipped" + echo "" + echo "Current commit already built for \`${IMAGE_NAME}:staging\`." + echo "- sha: \`${{ steps.source_sha.outputs.sha }}\`" } >> "$GITHUB_STEP_SUMMARY"