From 4997c936c0b547a0bad8817f658296abb11b0ab5 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Sun, 9 Nov 2025 09:53:35 +0000 Subject: [PATCH 1/7] feat: add /prerelease slash command to trigger publish workflow Co-Authored-By: AJ Steers --- .github/workflows/prerelease-command.yml | 90 ++++++++++++++++++++ .github/workflows/slash_command_dispatch.yml | 2 + 2 files changed, 92 insertions(+) create mode 100644 .github/workflows/prerelease-command.yml diff --git a/.github/workflows/prerelease-command.yml b/.github/workflows/prerelease-command.yml new file mode 100644 index 000000000..eaeca2985 --- /dev/null +++ b/.github/workflows/prerelease-command.yml @@ -0,0 +1,90 @@ +name: On-Demand Prerelease + +on: + workflow_dispatch: + inputs: + pr: + description: "PR Number" + type: string + required: false + comment-id: + description: "Comment ID (Optional)" + type: string + required: false + +jobs: + prerelease-on-demand: + name: Trigger Prerelease Publish + runs-on: ubuntu-24.04 + steps: + - name: Authenticate as GitHub App + uses: actions/create-github-app-token@v2 + id: get-app-token + with: + owner: "airbytehq" + repositories: "airbyte-python-cdk" + app-id: ${{ secrets.OCTAVIA_BOT_APP_ID }} + private-key: ${{ secrets.OCTAVIA_BOT_PRIVATE_KEY }} + + - name: Create URL to the run output + id: vars + run: echo "run-url=https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID" >> $GITHUB_OUTPUT + + - name: Append comment with job run link + if: github.event.inputs.comment-id + id: first-comment-action + uses: peter-evans/create-or-update-comment@v4 + with: + comment-id: ${{ github.event.inputs.comment-id }} + issue-number: ${{ github.event.inputs.pr }} + body: | + > **Prerelease Job Info** + > + > This job triggers the publish workflow with default arguments to create a prerelease. + > + > Prerelease job started... [Check job output.][1] + + [1]: ${{ steps.vars.outputs.run-url }} + + - name: Trigger publish workflow + run: | + gh workflow run publish.yml \ + --ref ${{ github.ref }} \ + -f version="" \ + -f publish_to_pypi=true \ + -f publish_to_dockerhub=true \ + -f publish_manifest_server=true \ + -f update_connector_builder=false + env: + GH_TOKEN: ${{ steps.get-app-token.outputs.token }} + + - name: Get workflow run URL + id: workflow-url + run: | + # Wait a moment for the workflow to be created + sleep 5 + # Get the most recent workflow run for publish.yml + WORKFLOW_RUN_URL=$(gh run list --workflow=publish.yml --limit=1 --json url --jq '.[0].url') + echo "workflow-run-url=${WORKFLOW_RUN_URL}" >> $GITHUB_OUTPUT + env: + GH_TOKEN: ${{ steps.get-app-token.outputs.token }} + + - name: Append success comment + if: github.event.inputs.comment-id + uses: peter-evans/create-or-update-comment@v4 + with: + comment-id: ${{ steps.first-comment-action.outputs.comment-id }} + reactions: hooray + body: | + > ✅ Prerelease workflow triggered successfully. + > + > View the publish workflow run: ${{ steps.workflow-url.outputs.workflow-run-url }} + + - name: Append failure comment + if: failure() && github.event.inputs.comment-id + uses: peter-evans/create-or-update-comment@v4 + with: + comment-id: ${{ steps.first-comment-action.outputs.comment-id }} + reactions: confused + body: | + > ❌ Failed to trigger prerelease workflow. diff --git a/.github/workflows/slash_command_dispatch.yml b/.github/workflows/slash_command_dispatch.yml index b42d61e64..1af77a5a8 100644 --- a/.github/workflows/slash_command_dispatch.yml +++ b/.github/workflows/slash_command_dispatch.yml @@ -35,6 +35,7 @@ jobs: test poetry-lock poe + prerelease # Notes regarding static-args: # - Slash commands can be invoked from both issues and comments. @@ -63,6 +64,7 @@ jobs: - \`/autofix\` - Corrects any linting or formatting issues - \`/test\` - Runs the test suite - \`/poetry-lock\` - Re-locks dependencies and updates the poetry.lock file + - \`/prerelease\` - Triggers a prerelease publish with default arguments - \`/help\` - Shows this help message" if [[ "${{ github.event.comment.body }}" == "/help" ]]; then From 563b6e8cbdf030858a575d26b80861a268d74271 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Sun, 9 Nov 2025 09:54:59 +0000 Subject: [PATCH 2/7] docs: update guidance and PR welcome messages to advertise /prerelease slash command Co-Authored-By: AJ Steers --- .github/pr-welcome-community.md | 1 + .github/pr-welcome-internal.md | 1 + .github/workflows/publish.yml | 6 ++++-- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/pr-welcome-community.md b/.github/pr-welcome-community.md index 1591a0e41..951fd90da 100644 --- a/.github/pr-welcome-community.md +++ b/.github/pr-welcome-community.md @@ -27,5 +27,6 @@ As needed or by request, Airbyte Maintainers can execute the following slash com - `/autofix` - Fixes most formatting and linting issues - `/poetry-lock` - Updates poetry.lock file - `/test` - Runs connector tests with the updated CDK +- `/prerelease` - Triggers a prerelease publish with default arguments If you have any questions, feel free to ask in the PR comments or join our [Slack community](https://airbytehq.slack.com/). diff --git a/.github/pr-welcome-internal.md b/.github/pr-welcome-internal.md index 0f4aa6e2c..27d1adeeb 100644 --- a/.github/pr-welcome-internal.md +++ b/.github/pr-welcome-internal.md @@ -26,6 +26,7 @@ Airbyte Maintainers can execute the following slash commands on your PR: - `/autofix` - Fixes most formatting and linting issues - `/poetry-lock` - Updates poetry.lock file - `/test` - Runs connector tests with the updated CDK +- `/prerelease` - Triggers a prerelease publish with default arguments - `/poe build` - Regenerate git-committed build artifacts, such as the pydantic models which are generated from the manifest JSON schema in YAML. - `/poe ` - Runs any poe command in the CDK environment diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 81f67efb5..31e22c6c7 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -20,8 +20,10 @@ on: Note that this workflow is intended for prereleases. For public-facing stable releases, please use the GitHub Releases workflow instead: https://github.com/airbytehq/airbyte-python-cdk/blob/main/docs/RELEASES.md. - For prereleases, please leave the version blank to use the detected version. Alternatively, - you can override the dynamic versioning for special use cases. + For prereleases, you can use the /prerelease slash command in a PR comment to trigger + this workflow with default arguments. Alternatively, you can manually trigger this workflow + and leave the version blank to use the detected version, or override the dynamic versioning + for special use cases. required: false publish_to_pypi: description: "Publish to PyPI. If true, the workflow will publish to PyPI." From cdd2eec41ee2c36db0b0f25b81fc446e4105937a Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Sun, 9 Nov 2025 10:00:54 +0000 Subject: [PATCH 3/7] fix: address bot feedback on prerelease workflow - Add explicit permissions block (contents: read, pull-requests: write, issues: write) - Fix --ref to use PR head branch instead of github.ref (main) - Add PR info fetching step to get head branch and repo - Add guard to prevent usage on forks (only works for branches in this repo) - Add guard to prevent usage on issues (PR-only) - Improve race condition handling by filtering workflow runs by branch - Add fallback URL if workflow run not found - Document that hardcoded defaults mirror publish.yml defaults Co-Authored-By: AJ Steers --- .github/workflows/prerelease-command.yml | 54 ++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 3 deletions(-) diff --git a/.github/workflows/prerelease-command.yml b/.github/workflows/prerelease-command.yml index eaeca2985..52f7c8ba3 100644 --- a/.github/workflows/prerelease-command.yml +++ b/.github/workflows/prerelease-command.yml @@ -1,5 +1,11 @@ name: On-Demand Prerelease +# Minimal permissions for security (addresses GitHub Advanced Security feedback) +permissions: + contents: read + pull-requests: write + issues: write + on: workflow_dispatch: inputs: @@ -30,6 +36,32 @@ jobs: id: vars run: echo "run-url=https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID" >> $GITHUB_OUTPUT + - name: Check that PR number is provided + if: github.event.inputs.pr == '' + run: | + echo "Error: /prerelease command must be invoked on a pull request, not an issue." + exit 1 + + - name: Get PR info + id: pr-info + run: | + PR_JSON=$(gh api repos/${{ github.repository }}/pulls/${{ github.event.inputs.pr }}) + HEAD_REF=$(echo "$PR_JSON" | jq -r .head.ref) + HEAD_REPO=$(echo "$PR_JSON" | jq -r .head.repo.full_name) + echo "head-ref=${HEAD_REF}" >> $GITHUB_OUTPUT + echo "head-repo=${HEAD_REPO}" >> $GITHUB_OUTPUT + echo "PR branch: ${HEAD_REF} from ${HEAD_REPO}" + env: + GH_TOKEN: ${{ steps.get-app-token.outputs.token }} + + - name: Check that PR is from this repository (not a fork) + if: steps.pr-info.outputs.head-repo != github.repository + run: | + echo "Error: /prerelease only works for branches in this repository, not forks." + echo "PR is from: ${{ steps.pr-info.outputs.head-repo }}" + echo "Expected: ${{ github.repository }}" + exit 1 + - name: Append comment with job run link if: github.event.inputs.comment-id id: first-comment-action @@ -47,9 +79,13 @@ jobs: [1]: ${{ steps.vars.outputs.run-url }} - name: Trigger publish workflow + id: trigger-publish run: | + # Trigger the publish workflow on the PR's head branch + # Note: These defaults mirror the defaults in publish.yml and can be extended + # to accept optional overrides via slash command arguments if needed in the future. gh workflow run publish.yml \ - --ref ${{ github.ref }} \ + --ref "${{ steps.pr-info.outputs.head-ref }}" \ -f version="" \ -f publish_to_pypi=true \ -f publish_to_dockerhub=true \ @@ -63,8 +99,20 @@ jobs: run: | # Wait a moment for the workflow to be created sleep 5 - # Get the most recent workflow run for publish.yml - WORKFLOW_RUN_URL=$(gh run list --workflow=publish.yml --limit=1 --json url --jq '.[0].url') + # Query for the most recent publish workflow run on the PR branch + # Filter by branch to avoid race conditions with concurrent runs + WORKFLOW_RUN_URL=$(gh run list \ + --workflow=publish.yml \ + --branch "${{ steps.pr-info.outputs.head-ref }}" \ + --limit=1 \ + --json url \ + --jq '.[0].url') + + if [ -z "$WORKFLOW_RUN_URL" ] || [ "$WORKFLOW_RUN_URL" = "null" ]; then + echo "Warning: Could not find workflow run URL. Using fallback." + WORKFLOW_RUN_URL="https://github.com/${{ github.repository }}/actions/workflows/publish.yml" + fi + echo "workflow-run-url=${WORKFLOW_RUN_URL}" >> $GITHUB_OUTPUT env: GH_TOKEN: ${{ steps.get-app-token.outputs.token }} From 60b00158f6201b44a319afc84af6b7a6a66bcebb Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Sun, 9 Nov 2025 10:03:06 +0000 Subject: [PATCH 4/7] refactor: use marketplace action for workflow dispatch Replace gh workflow run with the-actions-org/workflow-dispatch@v4 marketplace action. This provides cleaner workflow URL output and eliminates the need for sleep + query logic. Benefits: - Direct workflow-url output from the action - No race conditions from querying recent runs - Cleaner, more maintainable code - Purpose-built for workflow_dispatch events Co-Authored-By: AJ Steers --- .github/workflows/prerelease-command.yml | 53 +++++++----------------- 1 file changed, 16 insertions(+), 37 deletions(-) diff --git a/.github/workflows/prerelease-command.yml b/.github/workflows/prerelease-command.yml index 52f7c8ba3..7e8ede535 100644 --- a/.github/workflows/prerelease-command.yml +++ b/.github/workflows/prerelease-command.yml @@ -80,42 +80,21 @@ jobs: - name: Trigger publish workflow id: trigger-publish - run: | - # Trigger the publish workflow on the PR's head branch - # Note: These defaults mirror the defaults in publish.yml and can be extended - # to accept optional overrides via slash command arguments if needed in the future. - gh workflow run publish.yml \ - --ref "${{ steps.pr-info.outputs.head-ref }}" \ - -f version="" \ - -f publish_to_pypi=true \ - -f publish_to_dockerhub=true \ - -f publish_manifest_server=true \ - -f update_connector_builder=false - env: - GH_TOKEN: ${{ steps.get-app-token.outputs.token }} - - - name: Get workflow run URL - id: workflow-url - run: | - # Wait a moment for the workflow to be created - sleep 5 - # Query for the most recent publish workflow run on the PR branch - # Filter by branch to avoid race conditions with concurrent runs - WORKFLOW_RUN_URL=$(gh run list \ - --workflow=publish.yml \ - --branch "${{ steps.pr-info.outputs.head-ref }}" \ - --limit=1 \ - --json url \ - --jq '.[0].url') - - if [ -z "$WORKFLOW_RUN_URL" ] || [ "$WORKFLOW_RUN_URL" = "null" ]; then - echo "Warning: Could not find workflow run URL. Using fallback." - WORKFLOW_RUN_URL="https://github.com/${{ github.repository }}/actions/workflows/publish.yml" - fi - - echo "workflow-run-url=${WORKFLOW_RUN_URL}" >> $GITHUB_OUTPUT - env: - GH_TOKEN: ${{ steps.get-app-token.outputs.token }} + uses: the-actions-org/workflow-dispatch@v4 + with: + workflow: publish.yml + token: ${{ steps.get-app-token.outputs.token }} + ref: ${{ steps.pr-info.outputs.head-ref }} + wait-for-completion: false + display-workflow-run-url: false + inputs: >- + { + "version": "", + "publish_to_pypi": "true", + "publish_to_dockerhub": "true", + "publish_manifest_server": "true", + "update_connector_builder": "false" + } - name: Append success comment if: github.event.inputs.comment-id @@ -126,7 +105,7 @@ jobs: body: | > ✅ Prerelease workflow triggered successfully. > - > View the publish workflow run: ${{ steps.workflow-url.outputs.workflow-run-url }} + > View the publish workflow run: ${{ steps.trigger-publish.outputs.workflow-url }} - name: Append failure comment if: failure() && github.event.inputs.comment-id From 44118d6788113e4cdfb5b5b6d390538255166fd0 Mon Sep 17 00:00:00 2001 From: "Aaron (\"AJ\") Steers" Date: Sun, 9 Nov 2025 02:04:17 -0800 Subject: [PATCH 5/7] Apply suggestion from @aaronsteers --- .github/workflows/prerelease-command.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/prerelease-command.yml b/.github/workflows/prerelease-command.yml index 7e8ede535..6ffc011ba 100644 --- a/.github/workflows/prerelease-command.yml +++ b/.github/workflows/prerelease-command.yml @@ -92,7 +92,7 @@ jobs: "version": "", "publish_to_pypi": "true", "publish_to_dockerhub": "true", - "publish_manifest_server": "true", + "publish_manifest_server": "false", "update_connector_builder": "false" } From b92a8992a7126522f8d448a9eb32c58fac6b1027 Mon Sep 17 00:00:00 2001 From: "Aaron (\"AJ\") Steers" Date: Sun, 9 Nov 2025 02:05:16 -0800 Subject: [PATCH 6/7] Apply suggestion from @aaronsteers --- .github/workflows/prerelease-command.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/prerelease-command.yml b/.github/workflows/prerelease-command.yml index 6ffc011ba..85cd7fbc7 100644 --- a/.github/workflows/prerelease-command.yml +++ b/.github/workflows/prerelease-command.yml @@ -85,7 +85,7 @@ jobs: workflow: publish.yml token: ${{ steps.get-app-token.outputs.token }} ref: ${{ steps.pr-info.outputs.head-ref }} - wait-for-completion: false + wait-for-completion: true display-workflow-run-url: false inputs: >- { From 1ae85626bf374f2420989275d1b8555a73810ae6 Mon Sep 17 00:00:00 2001 From: "Aaron (\"AJ\") Steers" Date: Sun, 9 Nov 2025 02:09:05 -0800 Subject: [PATCH 7/7] Apply suggestion from @aaronsteers --- .github/workflows/prerelease-command.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/prerelease-command.yml b/.github/workflows/prerelease-command.yml index 85cd7fbc7..e6048cb71 100644 --- a/.github/workflows/prerelease-command.yml +++ b/.github/workflows/prerelease-command.yml @@ -89,7 +89,6 @@ jobs: display-workflow-run-url: false inputs: >- { - "version": "", "publish_to_pypi": "true", "publish_to_dockerhub": "true", "publish_manifest_server": "false",