From dc0667a4d5a4dbbe4df714369891c52d5741ef29 Mon Sep 17 00:00:00 2001 From: Jonathan Desrosiers Date: Fri, 18 Jul 2025 12:32:07 -0400 Subject: [PATCH] First pass at a reusable PR creation workflow. --- .../reusable-create-pull-request.yml | 114 ++++++++++++++++++ .../reusable-plugin-prep-release.yml | 55 +++++---- 2 files changed, 141 insertions(+), 28 deletions(-) create mode 100644 .github/workflows/reusable-create-pull-request.yml diff --git a/.github/workflows/reusable-create-pull-request.yml b/.github/workflows/reusable-create-pull-request.yml new file mode 100644 index 00000000..896e7417 --- /dev/null +++ b/.github/workflows/reusable-create-pull-request.yml @@ -0,0 +1,114 @@ +# A reusable workflow for creating a pull request in a repository. +name: Reusable Create Pull Request + +on: + workflow_call: + base-branch: + description: 'The name of the BASE branch to create the pull request against.' + type: string + default: main + head-branch: + description: 'The name of the HEAD branch to create the pull request from.' + required: true + type: string + workflow-id: + description: 'The ID of the workflow that produced the required artifacts.' + required: true + type: string + pr-title: + description: 'The title of the pull request.' + required: true + type: string + pr-labels: + description: 'A comma-separated list of labels to apply to the pull request.' + type: string + default: '' + +# Disable permissions for all available scopes by default. +# Any needed permissions should be configured individually for each job. +permissions: {} + +jobs: + + create-pull-request: + name: Create Pull Request + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + + steps: + - name: Retrieve patch artifact + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 + with: + name: 'pr-artifacts-${{ inputs.workflow-id }}-patch' + path: ${{ runner.temp }}/artifacts + + - name: Retrieve commit message artifact + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 + with: + name: 'pr-artifacts-${{ inputs.workflow-id }}-commit-message' + path: ${{ runner.temp }}/artifacts + + - name: Retrieve pull request body artifact + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 + with: + name: 'pr-artifacts-${{ inputs.workflow-id }}-pr-body' + path: ${{ runner.temp }}/artifacts + + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: true + + # When the specified HEAD branch already exists, the workflow should fail and require manual inspection. + - name: Check if branch already exists remotely + env: + PR_HEAD_BRANCH: ${{ inputs.head-branch }} + run: | + if git ls-remote --exit-code --heads origin "$PR_HEAD_BRANCH"; then + echo "::error::Branch '$PR_HEAD_BRANCH' already exists. Please inspect, delete, and try again." + exit 1 + fi + + - name: Create the HEAD branch + env: + PR_HEAD_BRANCH: ${{ inputs.head-branch }} + PR_BASE_BRANCH: ${{ inputs.base-branch }} + run: git checkout -b "$PR_HEAD_BRANCH" "origin/$PR_BASE_BRANCH" + + - name: Configure the Git user + run: | + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + + - name: Apply the patch + run: git apply "$RUNNER_TEMP/artifacts/patch.diff" + + - name: Stage changes + run: git add -A + + - name: Commit changes + run: git commit -F "$RUNNER_TEMP/artifacts/commit-message.md" + + - name: Push changes + run: git push origin "$PR_BRANCH_NAME" + + - name: Create Pull Request + if: false + env: + PR_BASE_BRANCH: ${{ inputs.base-branch }} + PR_HEAD_BRANCH: ${{ inputs.head-branch }} + PR_TITLE: ${{ inputs.pr-title }} + run: | + gh pr create \ + --base "$PR_BASE_BRANCH" \ + --head "$PR_HEAD_BRANCH" \ + --title "$PR_TITLE" \ + --body-file ${RUNNER_TEMP}/artifacts/pr-body.md + + - name: Add labels to the pull request + if: ${{ inputs.pr-labels != '' }} + env: + PR_LABELS: ${{ inputs.pr-labels }} + run: gh pr edit --add-label "$PR_LABELS" \ No newline at end of file diff --git a/.github/workflows/reusable-plugin-prep-release.yml b/.github/workflows/reusable-plugin-prep-release.yml index 96e34927..be858dfc 100644 --- a/.github/workflows/reusable-plugin-prep-release.yml +++ b/.github/workflows/reusable-plugin-prep-release.yml @@ -187,6 +187,18 @@ jobs: echo "message=⚠️ Warning: i18n script not defined." >> "$GITHUB_OUTPUT" fi + - name: Stage all changes + run: git add -A + + - name: Generated a diff file + run: git diff --cached > "${GITHUB_WORKSPACE}/release-diff.patch" + + - name: Save patch file as an artifact + uses: actions/upload-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 + with: + name: pr-artifacts-${{ github.run_id }}-patch + path: release-diff.patch + - name: Get merged PRs since last tag/release id: merged-prs env: @@ -228,38 +240,28 @@ jobs: echo "EOF" } >> "$GITHUB_OUTPUT" - # create the release branch, commit the changes with the github-actions[bot] - - name: Create and commit to release branch - id: push-changes + - name: Generate commit message env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} OLD_VERSION: ${{ steps.old.outputs.version }} NEW_VERSION: ${{ steps.new.outputs.version }} - run: | - git config user.name "github-actions[bot]" - git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + run: echo "🤖 prep for release - ${OLD_VERSION} → ${NEW_VERSION}" > commit-message.md - RELEASE_BRANCH="release/${NEW_VERSION}" - git checkout -b "$RELEASE_BRANCH" - git add . - git commit -m "🤖 prep for release - ${OLD_VERSION} → ${NEW_VERSION}" - git push origin "$RELEASE_BRANCH" + - name: Save commit message as an artifact + uses: actions/upload-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 + with: + name: pr-artifacts-${{ github.run_id }}-commit-message + path: commit-message.md - - name: Create Pull Request to target branch - id: create_pr + - name: Generate the pull request body env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} OLD_VERSION: ${{ steps.old.outputs.version }} NEW_VERSION: ${{ steps.new.outputs.version }} POST_SET_VERSION_MESSAGE: ${{ steps.run-post-set-version.outputs.message }} BUILD_OUTPUT_MESSAGE: ${{ steps.run-build.outputs.message }} I18N_OUTPUT_MESSAGE: ${{ steps.run-i18n.outputs.message }} MERGED_PRS: ${{ steps.merged-prs.outputs.prs }} - RELEASE_LEVEL: ${{ inputs.level }} - PLUGIN_TARGET_BRANCH: ${{ inputs.plugin-target-branch }} run: | - RELEASE_BRANCH="release/${NEW_VERSION}" - PR_BODY="$({ + { echo "## Changes in this pull request" echo "- Bumped version from \`${OLD_VERSION}\` to \`${NEW_VERSION}\`" echo "- ${POST_SET_VERSION_MESSAGE}" @@ -270,15 +272,13 @@ jobs: echo "${MERGED_PRS}" echo "" echo "_Generated automatically by CI workflow (see prep-release workflow)._" - })" + } > pr-body.md - PR_URL=$(gh pr create \ - --title "Automated ${RELEASE_LEVEL} release: ${NEW_VERSION}" \ - --body "$PR_BODY" \ - --base "${PLUGIN_TARGET_BRANCH}" \ - --head "$RELEASE_BRANCH" ) - - echo "pr_url=$PR_URL" >> "$GITHUB_OUTPUT" + - name: Save pull request body as an artifact + uses: actions/upload-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 + with: + name: pr-artifacts-${{ github.run_id }}-pr-body + path: pr-body.md - name: Write release summary to workflow summary env: @@ -288,7 +288,6 @@ jobs: BUILD_OUTPUT_MESSAGE: ${{ steps.run-build.outputs.message }} I18N_OUTPUT_MESSAGE: ${{ steps.run-i18n.outputs.message }} MERGED_PRS: ${{ steps.merged-prs.outputs.prs }} - PR_URL: ${{ steps.create_pr.outputs.pr_url }} run: | { echo "## 🚀 Release Prep Summary"