name: 🚀 Publish Trigger.dev Docker on: workflow_dispatch: workflow_call: inputs: image_tag: description: The image tag to publish required: true type: string secrets: DOCKERHUB_USERNAME: required: false DOCKERHUB_TOKEN: required: false SENTRY_AUTH_TOKEN: required: false CROSS_REPO_PAT: required: false push: branches: - main tags: - "v.docker.*" - "build-*" paths: - ".github/actions/**/*.yml" - ".github/workflows/publish.yml" - ".github/workflows/typecheck.yml" - ".github/workflows/unit-tests.yml" - ".github/workflows/e2e.yml" - ".github/workflows/publish-webapp.yml" - "packages/**" - "!packages/**/*.md" - "!packages/**/*.eslintrc" - "internal-packages/**" - "apps/**" - "!apps/**/*.md" - "!apps/**/*.eslintrc" - "pnpm-lock.yaml" - "pnpm-workspace.yaml" - "turbo.json" - "docker/Dockerfile" - "docker/scripts/**" - "tests/**" permissions: contents: read concurrency: group: ${{ github.workflow }}-${{ github.ref }} env: AWS_REGION: us-east-1 jobs: typecheck: uses: ./.github/workflows/typecheck.yml units: uses: ./.github/workflows/unit-tests.yml secrets: DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} publish-webapp: needs: [typecheck] permissions: contents: read packages: write id-token: write attestations: write uses: ./.github/workflows/publish-webapp.yml secrets: SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} with: image_tag: ${{ inputs.image_tag }} # Target registry namespace. Defaults to ghcr.io/ so a fork publishes # to its own namespace; set the IMAGE_REGISTRY repository variable to override. image_registry: ${{ vars.IMAGE_REGISTRY || format('ghcr.io/{0}', github.repository_owner) }} publish-worker-v4: needs: [typecheck] permissions: contents: read packages: write id-token: write uses: ./.github/workflows/publish-worker-v4.yml with: image_tag: ${{ inputs.image_tag }} image_registry: ${{ vars.IMAGE_REGISTRY || format('ghcr.io/{0}', github.repository_owner) }} # OS-level CVE scan of the image just published above. Report-only (writes to # the run summary); runs alongside the worker publishes and never blocks them. scan-webapp: needs: [publish-webapp] permissions: contents: read packages: read # pull the just-published image from GHCR 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 via repository_dispatch, handing them a digest-pinned ref to build or # deploy from. The repo, ref prefix, and dispatch target all default to the # canonical values and can be overridden by repository variables. # # `push` only: release builds reach publish.yml via workflow_call (from # release.yml) with an explicit image_tag while github.ref_name is still # `main`, so gate on the event to avoid dispatching — and failing on the # absent CROSS_REPO_PAT — during a release. dispatch-main-image: name: 📣 Dispatch main image needs: [publish-webapp] if: github.repository == (vars.MAIN_IMAGE_DISPATCH_REPO || 'triggerdotdev/trigger.dev') && github.event_name == 'push' && startsWith(github.ref_name, vars.MAIN_IMAGE_DISPATCH_REF_PREFIX || 'main') runs-on: warp-ubuntu-latest-x64-2x 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: ${{ vars.MAIN_IMAGE_DISPATCH_TARGET || 'triggerdotdev/cloud' }} event-type: main-image-published client-payload: ${{ steps.payload.outputs.client_payload }}