From 819da36d01356b4ff597db1aa0b1f35531f48b4e Mon Sep 17 00:00:00 2001 From: Matt Aitken Date: Tue, 9 Jun 2026 13:57:11 +0100 Subject: [PATCH] feat(ci): dispatch a repository event when the main webapp image is published After the webapp image is pushed on a main build, emit a repository_dispatch (main-image-published) carrying a digest-pinned image ref so other repositories in the org can build or deploy from the exact artifact rather than chasing the moving main tag. Fires only for the mutable main tag, never semver releases or other tag builds, and only from the canonical repo. --- .github/workflows/publish-webapp.yml | 4 +++ .github/workflows/publish.yml | 44 ++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/.github/workflows/publish-webapp.yml b/.github/workflows/publish-webapp.yml index 07f6486519..5a604e2608 100644 --- a/.github/workflows/publish-webapp.yml +++ b/.github/workflows/publish-webapp.yml @@ -29,6 +29,9 @@ on: image_repo: description: The image repository the build was published to (without tag) value: ${{ jobs.publish.outputs.image_repo }} + digest: + description: Multi-arch index digest (sha256:...) of the published image + value: ${{ jobs.publish.outputs.digest }} secrets: SENTRY_AUTH_TOKEN: required: false @@ -42,6 +45,7 @@ jobs: version: ${{ steps.get_tag.outputs.tag }} short_sha: ${{ steps.get_commit.outputs.sha_short }} image_repo: ${{ steps.set_tags.outputs.image_repo }} + digest: ${{ steps.build_push.outputs.digest }} steps: - name: 🏭 Setup Depot CLI uses: depot/setup-action@15c09a5f77a0840ad4bce955686522a257853461 # v1.7.1 diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 8b5677a923..3426690fc5 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -15,6 +15,8 @@ on: required: false SENTRY_AUTH_TOKEN: required: false + CROSS_REPO_PAT: + required: false push: branches: - main @@ -112,3 +114,45 @@ jobs: uses: ./.github/workflows/trivy-image-webapp.yml with: image-ref: ${{ needs.publish-webapp.outputs.image_repo }}:${{ needs.publish-webapp.outputs.version }} + + # Announce the freshly published mutable `main` webapp image to subscriber + # repos in the org via repository_dispatch, handing them a digest-pinned ref to + # build or deploy from. Fires only for the `main` tag — never semver releases or + # other tag builds — and only from the canonical repo (forks have no PAT). + dispatch-main-image: + name: 📣 Dispatch main image + needs: [publish-webapp] + if: github.repository == 'triggerdotdev/trigger.dev' && needs.publish-webapp.outputs.version == 'main' + runs-on: ubuntu-latest + permissions: {} + steps: + - name: Build dispatch payload + id: payload + env: + IMAGE_REPO: ${{ needs.publish-webapp.outputs.image_repo }} + DIGEST: ${{ needs.publish-webapp.outputs.digest }} + COMMIT: ${{ github.sha }} + run: | + set -euo pipefail + # Pin to the exact multi-arch index just pushed so subscribers resolve a + # single immutable artifact rather than chasing the moving `main` tag. + if [[ -z "${DIGEST}" ]]; then + echo "::error::publish-webapp produced no image digest; refusing to dispatch" + exit 1 + fi + image="${IMAGE_REPO}@${DIGEST}" + # jq --arg JSON-escapes every value, so the ref/commit can't break out of + # or inject into the client payload. + payload=$(jq -nc \ + --arg img "$image" \ + --arg c "$COMMIT" \ + '{image: $img, commit: $c}') + echo "client_payload=$payload" >> "$GITHUB_OUTPUT" + + - name: Send repository_dispatch + uses: peter-evans/repository-dispatch@28959ce8df70de7be546dd1250a005dd32156697 # v4.0.1 + with: + token: ${{ secrets.CROSS_REPO_PAT }} + repository: triggerdotdev/cloud + event-type: main-image-published + client-payload: ${{ steps.payload.outputs.client_payload }}