From ded85cd21719b84ad08089145d9785add6129790 Mon Sep 17 00:00:00 2001 From: aivong-openhands Date: Fri, 5 Jun 2026 13:06:43 -0500 Subject: [PATCH] PLTF-2875: Add promote-to-development sender (#14635) --- .github/workflows/promote-to-development.yml | 86 ++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 .github/workflows/promote-to-development.yml diff --git a/.github/workflows/promote-to-development.yml b/.github/workflows/promote-to-development.yml new file mode 100644 index 0000000000..404f31a51c --- /dev/null +++ b/.github/workflows/promote-to-development.yml @@ -0,0 +1,86 @@ +# Promotes each successful main build's enterprise-server image to the +# development environment by dispatching to OpenHands/saas-deploy, which runs +# the bump. Runs after the Docker workflow succeeds on main; can also be run +# manually (from main) to re-promote a known-good image tag. + +name: Promote to development + +on: + workflow_dispatch: + inputs: + image-tag: + description: "Image tag to promote (defaults to sha- for the selected ref)" + required: false + type: string + workflow_run: + workflows: ["Docker"] + types: [completed] + branches: [main] + +# Queue promotions so an earlier main commit deploys before a later one. +concurrency: + group: promote-to-development + cancel-in-progress: false + +jobs: + promote: + # Only promote when the Docker build actually succeeded, or when run manually. + # The Docker workflow also runs on pull_request, and the workflow_run branches + # filter matches the *head* branch — a fork PR from a branch named "main" + # would slip through — so additionally require a push event. + if: ${{ github.event_name == 'workflow_dispatch' || (github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event == 'push') }} + runs-on: ubuntu-24.04 + timeout-minutes: 10 + environment: dev-deploy + permissions: + contents: read + steps: + - name: Compute image tag + id: tag + # Matches docker/metadata-action type=sha (7-char short SHA) emitted by + # the docker-image-tags action used in _build-image.yml. + env: + DISPATCH_IMAGE_TAG: ${{ github.event.inputs['image-tag'] }} + SHA: ${{ github.event.workflow_run.head_sha || github.sha }} + run: | + if [ -n "$DISPATCH_IMAGE_TAG" ]; then + echo "tag=$DISPATCH_IMAGE_TAG" >> "$GITHUB_OUTPUT" + else + echo "tag=sha-${SHA::7}" >> "$GITHUB_OUTPUT" + fi + + - name: Mint token + id: app-token + uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0 + with: + app-id: ${{ secrets.SAAS_DEPLOY_DISPATCHER_APP_ID }} + private-key: ${{ secrets.SAAS_DEPLOY_DISPATCHER_APP_PRIVATE_KEY }} + owner: OpenHands + repositories: saas-deploy + permission-contents: write + + - name: Dispatch promotion to saas-deploy + env: + GH_TOKEN: ${{ steps.app-token.outputs.token }} + IMAGE_TAG: ${{ steps.tag.outputs.tag }} + SOURCE_SHA: ${{ github.event.workflow_run.head_sha || github.sha }} + run: | + gh api /repos/OpenHands/saas-deploy/dispatches \ + -f event_type=promote-to-development \ + -F client_payload[release]=openhands \ + -F client_payload[tag-path]=.openhands.image.tag \ + -F client_payload[image-tag]="$IMAGE_TAG" \ + -F client_payload[source-repo]="$GITHUB_REPOSITORY" \ + -F client_payload[source-sha]="$SOURCE_SHA" + echo "Dispatched promote-to-development for openhands ${IMAGE_TAG} (${SOURCE_SHA})." + + - name: Annotate dispatch failure + if: ${{ failure() }} + env: + IMAGE_TAG: ${{ steps.tag.outputs.tag }} + HEAD_SHA: ${{ github.event.workflow_run.head_sha || github.sha }} + SOURCE_RUN_URL: ${{ github.event.workflow_run.html_url }} + run: | + image_tag="${IMAGE_TAG:-sha-${HEAD_SHA::7}}" + source="${SOURCE_RUN_URL:-manual workflow_dispatch run}" + echo "::error title=Promote to development failed::Failed to dispatch promotion of enterprise-server ${image_tag} (${HEAD_SHA}) to development. Source: ${source}"