From e494eb541db1e379a5ce8e29a454722e39697a7b Mon Sep 17 00:00:00 2001 From: "fr4nc1sc0.r4m0n" Date: Fri, 3 Jul 2026 12:14:07 +0200 Subject: [PATCH 1/8] Unify branch existence validation in prepare-release action Merge duplicate major/minor branch checks into a single step with release-type-specific error messaging. --- .github/workflows/prepare-release/action.yml | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/.github/workflows/prepare-release/action.yml b/.github/workflows/prepare-release/action.yml index 9eedd90f930..13a4fa423c6 100644 --- a/.github/workflows/prepare-release/action.yml +++ b/.github/workflows/prepare-release/action.yml @@ -73,29 +73,18 @@ runs: echo "::error::${FAILURE_MESSAGE}" ; exit 1 shell: 'bash' - - name: validate if branch already exists (major only) - if: ${{ inputs.type == 'major' }} + - name: validate if branch already exists (major or minor only) + if: ${{ inputs.type == 'major' || inputs.type == 'minor' }} run: |- if git ls-remote --exit-code --heads "https://github.com/${GITHUB_REPOSITORY}.git" "$BRANCH" > /dev/null ; then + FAILURE_MESSAGE="Branch already exists. This is not a ${RELEASE_TYPE} release." echo "FAILURE_MESSAGE=${FAILURE_MESSAGE}" >> "$GITHUB_ENV" echo "::error::${FAILURE_MESSAGE}" ; exit 1 fi shell: 'bash' env: BRANCH: ${{ steps.generate.outputs.release-branch }} - FAILURE_MESSAGE: Branch already exists. This is not a major release. - - - name: validate if branch already exists (minor only) - if: ${{ inputs.type == 'minor' }} - run: |- - if git ls-remote --exit-code --heads https://github.com/${{ github.repository }}.git "$BRANCH" > /dev/null ; then - FAILURE_MESSAGE='Branch already exists. This is not a minor release.' - echo "FAILURE_MESSAGE=${FAILURE_MESSAGE}" >> "$GITHUB_ENV" - echo "::error::${FAILURE_MESSAGE}" ; exit 1 - fi - shell: 'bash' - env: - BRANCH: ${{ steps.generate.outputs.release-branch }} + RELEASE_TYPE: ${{ inputs.type }} - name: validate if tag already exists run: |- From 278cfb95fdb3585df0b12a61a6a0b1217a36df22 Mon Sep 17 00:00:00 2001 From: "fr4nc1sc0.r4m0n" Date: Fri, 3 Jul 2026 12:14:41 +0200 Subject: [PATCH 2/8] Use github.repository in prepare-release branch check Align branch existence validation with the tag check step. --- .github/workflows/prepare-release/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/prepare-release/action.yml b/.github/workflows/prepare-release/action.yml index 13a4fa423c6..5691bd3640a 100644 --- a/.github/workflows/prepare-release/action.yml +++ b/.github/workflows/prepare-release/action.yml @@ -76,7 +76,7 @@ runs: - name: validate if branch already exists (major or minor only) if: ${{ inputs.type == 'major' || inputs.type == 'minor' }} run: |- - if git ls-remote --exit-code --heads "https://github.com/${GITHUB_REPOSITORY}.git" "$BRANCH" > /dev/null ; then + if git ls-remote --exit-code --heads https://github.com/${{ github.repository }}.git "$BRANCH" > /dev/null ; then FAILURE_MESSAGE="Branch already exists. This is not a ${RELEASE_TYPE} release." echo "FAILURE_MESSAGE=${FAILURE_MESSAGE}" >> "$GITHUB_ENV" echo "::error::${FAILURE_MESSAGE}" ; exit 1 From d5ad1cb49dd88107dd77b0d8adc04870e9ac0a9b Mon Sep 17 00:00:00 2001 From: Nina Lee Date: Tue, 21 Jul 2026 10:47:54 -0500 Subject: [PATCH 3/8] add minor and patch checks for idempotency --- .github/workflows/prepare-release/action.yml | 38 +++++++++++++++++--- .github/workflows/run-minor-release.yml | 5 ++- .github/workflows/run-patch-release.yml | 5 ++- 3 files changed, 42 insertions(+), 6 deletions(-) diff --git a/.github/workflows/prepare-release/action.yml b/.github/workflows/prepare-release/action.yml index 5691bd3640a..0c851d4c82d 100644 --- a/.github/workflows/prepare-release/action.yml +++ b/.github/workflows/prepare-release/action.yml @@ -26,6 +26,9 @@ outputs: slack-thread: description: "Slack thread id" value: ${{ steps.slack-thread.outputs.thread-timestamp }} + skip: + description: "Whether release steps should be skipped because they already ran" + value: ${{ steps.check-branch.outputs.skip || steps.check-minor-pr.outputs.skip || steps.check-patch-pr.outputs.skip }} runs: using: "composite" @@ -74,17 +77,44 @@ runs: shell: 'bash' - name: validate if branch already exists (major or minor only) + id: check-branch if: ${{ inputs.type == 'major' || inputs.type == 'minor' }} run: |- if git ls-remote --exit-code --heads https://github.com/${{ github.repository }}.git "$BRANCH" > /dev/null ; then - FAILURE_MESSAGE="Branch already exists. This is not a ${RELEASE_TYPE} release." - echo "FAILURE_MESSAGE=${FAILURE_MESSAGE}" >> "$GITHUB_ENV" - echo "::error::${FAILURE_MESSAGE}" ; exit 1 + echo "Branch $BRANCH already exists, release steps will be skipped." + echo "skip=true" >> "$GITHUB_OUTPUT" fi shell: 'bash' env: BRANCH: ${{ steps.generate.outputs.release-branch }} - RELEASE_TYPE: ${{ inputs.type }} + + - name: check if minor main bump PR already exists + id: check-minor-pr + if: ${{ inputs.type == 'minor' }} + run: |- + BRANCH="update-${{ steps.generate.outputs.release-version }}" + PR_COUNT=$(gh pr list --head "$BRANCH" --base main --label release --state all --json number --jq 'length' --repo "${{ github.repository }}") + if [ "$PR_COUNT" -gt 0 ]; then + echo "Main bump PR for $BRANCH already exists, release steps will be skipped." + echo "skip=true" >> "$GITHUB_OUTPUT" + fi + shell: 'bash' + env: + GH_TOKEN: ${{ github.token }} + + - name: check if patch PR already exists + id: check-patch-pr + if: ${{ inputs.type == 'patch' }} + run: |- + BRANCH="update-${{ steps.generate.outputs.release-version }}" + PR_COUNT=$(gh pr list --head "$BRANCH" --base "${{ steps.generate.outputs.release-branch }}" --label release --state all --json number --jq 'length' --repo "${{ github.repository }}") + if [ "$PR_COUNT" -gt 0 ]; then + echo "Patch PR for $BRANCH already exists, release steps will be skipped." + echo "skip=true" >> "$GITHUB_OUTPUT" + fi + shell: 'bash' + env: + GH_TOKEN: ${{ github.token }} - name: validate if tag already exists run: |- diff --git a/.github/workflows/run-minor-release.yml b/.github/workflows/run-minor-release.yml index 0663715a0ec..96d1bdda6f1 100644 --- a/.github/workflows/run-minor-release.yml +++ b/.github/workflows/run-minor-release.yml @@ -15,6 +15,7 @@ concurrency: permissions: contents: read + pull-requests: read env: JOB_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} @@ -28,6 +29,7 @@ jobs: release-type: ${{ steps.prepare.outputs.release-type }} release-version: ${{ steps.prepare.outputs.release-version }} slack-thread: ${{ steps.prepare.outputs.slack-thread }} + skip: ${{ steps.prepare.outputs.skip }} steps: - uses: actions/checkout@v7 - id: prepare @@ -87,10 +89,11 @@ jobs: git_commit_gpgsign: true - run: make minor-release + if: needs.prepare.outputs.skip != 'true' env: GH_TOKEN: ${{ steps.get_token.outputs.token }} - - if: success() + - if: success() && needs.prepare.outputs.skip != 'true' uses: elastic/oblt-actions/slack/send@v1 with: bot-token: ${{ secrets.SLACK_BOT_TOKEN }} diff --git a/.github/workflows/run-patch-release.yml b/.github/workflows/run-patch-release.yml index 7a39702afeb..5f8f2f61486 100644 --- a/.github/workflows/run-patch-release.yml +++ b/.github/workflows/run-patch-release.yml @@ -15,6 +15,7 @@ concurrency: permissions: contents: read + pull-requests: read env: JOB_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} @@ -28,6 +29,7 @@ jobs: release-type: ${{ steps.prepare.outputs.release-type }} release-version: ${{ steps.prepare.outputs.release-version }} slack-thread: ${{ steps.prepare.outputs.slack-thread }} + skip: ${{ steps.prepare.outputs.skip }} steps: - uses: actions/checkout@v7 @@ -77,11 +79,12 @@ jobs: git_commit_gpgsign: true - run: make patch-release + if: needs.prepare.outputs.skip != 'true' env: GH_TOKEN: ${{ steps.get_token.outputs.token }} BUMP_VERSION: ${{ needs.prepare.outputs.release-version }} - - if: success() + - if: success() && needs.prepare.outputs.skip != 'true' uses: elastic/oblt-actions/slack/send@v1 with: bot-token: ${{ secrets.SLACK_BOT_TOKEN }} From e49921431ead02b8fac4d23baac8c91fa8b4f397 Mon Sep 17 00:00:00 2001 From: Nina Lee Date: Tue, 21 Jul 2026 13:25:04 -0500 Subject: [PATCH 4/8] move branch check one layer lower --- .github/workflows/prepare-release/action.yml | 43 ------------- .github/workflows/run-minor-release.yml | 5 +- .github/workflows/run-patch-release.yml | 5 +- release.mk | 68 +++++++++++--------- 4 files changed, 41 insertions(+), 80 deletions(-) diff --git a/.github/workflows/prepare-release/action.yml b/.github/workflows/prepare-release/action.yml index 0c851d4c82d..7512748ec4d 100644 --- a/.github/workflows/prepare-release/action.yml +++ b/.github/workflows/prepare-release/action.yml @@ -26,9 +26,6 @@ outputs: slack-thread: description: "Slack thread id" value: ${{ steps.slack-thread.outputs.thread-timestamp }} - skip: - description: "Whether release steps should be skipped because they already ran" - value: ${{ steps.check-branch.outputs.skip || steps.check-minor-pr.outputs.skip || steps.check-patch-pr.outputs.skip }} runs: using: "composite" @@ -76,46 +73,6 @@ runs: echo "::error::${FAILURE_MESSAGE}" ; exit 1 shell: 'bash' - - name: validate if branch already exists (major or minor only) - id: check-branch - if: ${{ inputs.type == 'major' || inputs.type == 'minor' }} - run: |- - if git ls-remote --exit-code --heads https://github.com/${{ github.repository }}.git "$BRANCH" > /dev/null ; then - echo "Branch $BRANCH already exists, release steps will be skipped." - echo "skip=true" >> "$GITHUB_OUTPUT" - fi - shell: 'bash' - env: - BRANCH: ${{ steps.generate.outputs.release-branch }} - - - name: check if minor main bump PR already exists - id: check-minor-pr - if: ${{ inputs.type == 'minor' }} - run: |- - BRANCH="update-${{ steps.generate.outputs.release-version }}" - PR_COUNT=$(gh pr list --head "$BRANCH" --base main --label release --state all --json number --jq 'length' --repo "${{ github.repository }}") - if [ "$PR_COUNT" -gt 0 ]; then - echo "Main bump PR for $BRANCH already exists, release steps will be skipped." - echo "skip=true" >> "$GITHUB_OUTPUT" - fi - shell: 'bash' - env: - GH_TOKEN: ${{ github.token }} - - - name: check if patch PR already exists - id: check-patch-pr - if: ${{ inputs.type == 'patch' }} - run: |- - BRANCH="update-${{ steps.generate.outputs.release-version }}" - PR_COUNT=$(gh pr list --head "$BRANCH" --base "${{ steps.generate.outputs.release-branch }}" --label release --state all --json number --jq 'length' --repo "${{ github.repository }}") - if [ "$PR_COUNT" -gt 0 ]; then - echo "Patch PR for $BRANCH already exists, release steps will be skipped." - echo "skip=true" >> "$GITHUB_OUTPUT" - fi - shell: 'bash' - env: - GH_TOKEN: ${{ github.token }} - - name: validate if tag already exists run: |- if git ls-remote --exit-code https://github.com/${{ github.repository }}.git "$TAG" > /dev/null ; then diff --git a/.github/workflows/run-minor-release.yml b/.github/workflows/run-minor-release.yml index 96d1bdda6f1..0663715a0ec 100644 --- a/.github/workflows/run-minor-release.yml +++ b/.github/workflows/run-minor-release.yml @@ -15,7 +15,6 @@ concurrency: permissions: contents: read - pull-requests: read env: JOB_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} @@ -29,7 +28,6 @@ jobs: release-type: ${{ steps.prepare.outputs.release-type }} release-version: ${{ steps.prepare.outputs.release-version }} slack-thread: ${{ steps.prepare.outputs.slack-thread }} - skip: ${{ steps.prepare.outputs.skip }} steps: - uses: actions/checkout@v7 - id: prepare @@ -89,11 +87,10 @@ jobs: git_commit_gpgsign: true - run: make minor-release - if: needs.prepare.outputs.skip != 'true' env: GH_TOKEN: ${{ steps.get_token.outputs.token }} - - if: success() && needs.prepare.outputs.skip != 'true' + - if: success() uses: elastic/oblt-actions/slack/send@v1 with: bot-token: ${{ secrets.SLACK_BOT_TOKEN }} diff --git a/.github/workflows/run-patch-release.yml b/.github/workflows/run-patch-release.yml index 5f8f2f61486..7a39702afeb 100644 --- a/.github/workflows/run-patch-release.yml +++ b/.github/workflows/run-patch-release.yml @@ -15,7 +15,6 @@ concurrency: permissions: contents: read - pull-requests: read env: JOB_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} @@ -29,7 +28,6 @@ jobs: release-type: ${{ steps.prepare.outputs.release-type }} release-version: ${{ steps.prepare.outputs.release-version }} slack-thread: ${{ steps.prepare.outputs.slack-thread }} - skip: ${{ steps.prepare.outputs.skip }} steps: - uses: actions/checkout@v7 @@ -79,12 +77,11 @@ jobs: git_commit_gpgsign: true - run: make patch-release - if: needs.prepare.outputs.skip != 'true' env: GH_TOKEN: ${{ steps.get_token.outputs.token }} BUMP_VERSION: ${{ needs.prepare.outputs.release-version }} - - if: success() && needs.prepare.outputs.skip != 'true' + - if: success() uses: elastic/oblt-actions/slack/send@v1 with: bot-token: ${{ secrets.SLACK_BOT_TOKEN }} diff --git a/release.mk b/release.mk index 3e53fac9f7d..fc7a7d563ca 100644 --- a/release.mk +++ b/release.mk @@ -38,6 +38,7 @@ PROJECT_MINOR_VERSION ?= $(shell echo $(RELEASE_VERSION) | cut -f2 -d.) PROJECT_PATCH_VERSION ?= $(shell echo $(RELEASE_VERSION) | cut -f3 -d.) PROJECT_OWNER ?= elastic RELEASE_TYPE ?= minor +FORCE_PR_CREATION ?= # if gh is installed only ifneq ($(shell command -v gh 2>/dev/null),) @@ -72,26 +73,27 @@ endif # .PHONY: minor-release minor-release: - @echo "INFO: Create GitHub label backport for the version $(RELEASE_VERSION)" - $(MAKE) create-github-label NAME=backport-$(RELEASE_BRANCH) - - @echo "INFO: Create release branch and update new version $(RELEASE_VERSION)" - $(MAKE) create-branch NAME=$(RELEASE_BRANCH) BASE=$(BASE_BRANCH) - $(MAKE) update-version VERSION=$(RELEASE_VERSION) - $(MAKE) update-version-makefile VERSION=$(PROJECT_MAJOR_VERSION)\.$(PROJECT_MINOR_VERSION) - $(MAKE) create-commit COMMIT_MESSAGE="[Release] update version $(RELEASE_VERSION)" - - @echo "INFO: Create feature branch and update the versions. Target branch $(BASE_BRANCH)" - $(MAKE) create-branch NAME=update-$(RELEASE_VERSION) BASE=$(BASE_BRANCH) - $(MAKE) update-mergify VERSION=$(RELEASE_BRANCH) - $(MAKE) update-version VERSION=$(NEXT_PROJECT_MINOR_VERSION) - $(MAKE) create-commit COMMIT_MESSAGE="[Release] update version $(NEXT_PROJECT_MINOR_VERSION)" - $(MAKE) update-changelog VERSION=$(RELEASE_VERSION) - $(MAKE) create-commit COMMIT_MESSAGE="[Release] update changelogs for $(RELEASE_BRANCH) release" - - @echo "INFO: Push changes to $(PROJECT_OWNER)/apm-server and create the relevant Pull Requests" - git push origin $(RELEASE_BRANCH) - $(MAKE) create-pull-request BRANCH=update-$(RELEASE_VERSION) TARGET_BRANCH=$(BASE_BRANCH) TITLE="$(RELEASE_BRANCH): update docs, mergify, versions and changelogs" BODY="Merge as soon as the GitHub checks are green." + @if git ls-remote --exit-code --heads https://github.com/$(PROJECT_OWNER)/apm-server.git "$(RELEASE_BRANCH)" > /dev/null 2>&1; then \ + echo "WARNING: Release branch $(RELEASE_BRANCH) already exists. Skipping." ; \ + else \ + echo "INFO: Create GitHub label backport for the version $(RELEASE_VERSION)" ; \ + $(MAKE) create-github-label NAME=backport-$(RELEASE_BRANCH) ; \ + echo "INFO: Create release branch and update new version $(RELEASE_VERSION)" ; \ + $(MAKE) create-branch NAME=$(RELEASE_BRANCH) BASE=$(BASE_BRANCH) ; \ + $(MAKE) update-version VERSION=$(RELEASE_VERSION) ; \ + $(MAKE) update-version-makefile VERSION=$(PROJECT_MAJOR_VERSION)\.$(PROJECT_MINOR_VERSION) ; \ + $(MAKE) create-commit COMMIT_MESSAGE="[Release] update version $(RELEASE_VERSION)" ; \ + echo "INFO: Create feature branch and update the versions. Target branch $(BASE_BRANCH)" ; \ + $(MAKE) create-branch NAME=update-$(RELEASE_VERSION) BASE=$(BASE_BRANCH) ; \ + $(MAKE) update-mergify VERSION=$(RELEASE_BRANCH) ; \ + $(MAKE) update-version VERSION=$(NEXT_PROJECT_MINOR_VERSION) ; \ + $(MAKE) create-commit COMMIT_MESSAGE="[Release] update version $(NEXT_PROJECT_MINOR_VERSION)" ; \ + $(MAKE) update-changelog VERSION=$(RELEASE_VERSION) ; \ + $(MAKE) create-commit COMMIT_MESSAGE="[Release] update changelogs for $(RELEASE_BRANCH) release" ; \ + echo "INFO: Push changes to $(PROJECT_OWNER)/apm-server and create the relevant Pull Requests" ; \ + git push origin $(RELEASE_BRANCH) ; \ + $(MAKE) create-pull-request BRANCH=update-$(RELEASE_VERSION) TARGET_BRANCH=$(BASE_BRANCH) TITLE="$(RELEASE_BRANCH): update docs, mergify, versions and changelogs" BODY="Merge as soon as the GitHub checks are green." ; \ + fi # This is the contract with the GitHub action .github/workflows/run-major-release.yml. # The GitHub action will provide the below environment variables: @@ -213,15 +215,23 @@ create-pull-request: @echo "::group::create-pull-request $(BRANCH) -> $(TARGET_BRANCH)" git push origin $(BRANCH) echo "--label $(BACKPORT_LABEL)" - gh pr create \ - --title "$(TITLE)" \ - --body "$(BODY)" \ - --base $(TARGET_BRANCH) \ - --head $(BRANCH) \ - --label 'release' \ - --label "$(BACKPORT_LABEL)" \ - --reviewer "$(PROJECT_REVIEWERS)" \ - --repo $(PROJECT_OWNER)/apm-server || echo "There is no changes" + @PR_COUNT=0 ; \ + if [ "$(FORCE_PR_CREATION)" != "true" ]; then \ + PR_COUNT=$$(gh pr list --head "$(BRANCH)" --base "$(TARGET_BRANCH)" --label release --state all --json number --jq 'length' --repo $(PROJECT_OWNER)/apm-server) ; \ + fi ; \ + if [ "$$PR_COUNT" -gt 0 ]; then \ + echo "PR for $(BRANCH) -> $(TARGET_BRANCH) already exists, skipping." ; \ + else \ + gh pr create \ + --title "$(TITLE)" \ + --body "$(BODY)" \ + --base $(TARGET_BRANCH) \ + --head $(BRANCH) \ + --label 'release' \ + --label "$(BACKPORT_LABEL)" \ + --reviewer "$(PROJECT_REVIEWERS)" \ + --repo $(PROJECT_OWNER)/apm-server || echo "There is no changes" ; \ + fi @echo "::endgroup::" ## Diff output From 62833620c5063c9608e4453a1e40bbdea0a0d9b0 Mon Sep 17 00:00:00 2001 From: Nina Lee Date: Tue, 21 Jul 2026 13:30:37 -0500 Subject: [PATCH 5/8] rearranged the logic in the create-pull-request target --- release.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/release.mk b/release.mk index fc7a7d563ca..bb2e519fe70 100644 --- a/release.mk +++ b/release.mk @@ -213,8 +213,6 @@ create-pull-request: BRANCH=$${BRANCH} TITLE=$${TITLE} TARGET_BRANCH=$${TARGET_B create-pull-request: @echo "::group::create-pull-request $(BRANCH) -> $(TARGET_BRANCH)" - git push origin $(BRANCH) - echo "--label $(BACKPORT_LABEL)" @PR_COUNT=0 ; \ if [ "$(FORCE_PR_CREATION)" != "true" ]; then \ PR_COUNT=$$(gh pr list --head "$(BRANCH)" --base "$(TARGET_BRANCH)" --label release --state all --json number --jq 'length' --repo $(PROJECT_OWNER)/apm-server) ; \ @@ -222,6 +220,8 @@ create-pull-request: if [ "$$PR_COUNT" -gt 0 ]; then \ echo "PR for $(BRANCH) -> $(TARGET_BRANCH) already exists, skipping." ; \ else \ + echo "--label $(BACKPORT_LABEL)" ; \ + git push origin $(BRANCH) ; \ gh pr create \ --title "$(TITLE)" \ --body "$(BODY)" \ From 5408240d52cbaf8211e9e3cbc843b4777de10093 Mon Sep 17 00:00:00 2001 From: Nina Lee Date: Wed, 22 Jul 2026 13:37:44 -0500 Subject: [PATCH 6/8] move existing branch guard to create-branch --- release.mk | 52 +++++++++++++++++++++++++++------------------------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/release.mk b/release.mk index bb2e519fe70..d370c4dae07 100644 --- a/release.mk +++ b/release.mk @@ -73,27 +73,23 @@ endif # .PHONY: minor-release minor-release: - @if git ls-remote --exit-code --heads https://github.com/$(PROJECT_OWNER)/apm-server.git "$(RELEASE_BRANCH)" > /dev/null 2>&1; then \ - echo "WARNING: Release branch $(RELEASE_BRANCH) already exists. Skipping." ; \ - else \ - echo "INFO: Create GitHub label backport for the version $(RELEASE_VERSION)" ; \ - $(MAKE) create-github-label NAME=backport-$(RELEASE_BRANCH) ; \ - echo "INFO: Create release branch and update new version $(RELEASE_VERSION)" ; \ - $(MAKE) create-branch NAME=$(RELEASE_BRANCH) BASE=$(BASE_BRANCH) ; \ - $(MAKE) update-version VERSION=$(RELEASE_VERSION) ; \ - $(MAKE) update-version-makefile VERSION=$(PROJECT_MAJOR_VERSION)\.$(PROJECT_MINOR_VERSION) ; \ - $(MAKE) create-commit COMMIT_MESSAGE="[Release] update version $(RELEASE_VERSION)" ; \ - echo "INFO: Create feature branch and update the versions. Target branch $(BASE_BRANCH)" ; \ - $(MAKE) create-branch NAME=update-$(RELEASE_VERSION) BASE=$(BASE_BRANCH) ; \ - $(MAKE) update-mergify VERSION=$(RELEASE_BRANCH) ; \ - $(MAKE) update-version VERSION=$(NEXT_PROJECT_MINOR_VERSION) ; \ - $(MAKE) create-commit COMMIT_MESSAGE="[Release] update version $(NEXT_PROJECT_MINOR_VERSION)" ; \ - $(MAKE) update-changelog VERSION=$(RELEASE_VERSION) ; \ - $(MAKE) create-commit COMMIT_MESSAGE="[Release] update changelogs for $(RELEASE_BRANCH) release" ; \ - echo "INFO: Push changes to $(PROJECT_OWNER)/apm-server and create the relevant Pull Requests" ; \ - git push origin $(RELEASE_BRANCH) ; \ - $(MAKE) create-pull-request BRANCH=update-$(RELEASE_VERSION) TARGET_BRANCH=$(BASE_BRANCH) TITLE="$(RELEASE_BRANCH): update docs, mergify, versions and changelogs" BODY="Merge as soon as the GitHub checks are green." ; \ - fi + @echo "INFO: Create GitHub label backport for the version $(RELEASE_VERSION)" + $(MAKE) create-github-label NAME=backport-$(RELEASE_BRANCH) + @echo "INFO: Create release branch and update new version $(RELEASE_VERSION)" + $(MAKE) create-branch NAME=$(RELEASE_BRANCH) BASE=$(BASE_BRANCH) + $(MAKE) update-version VERSION=$(RELEASE_VERSION) + $(MAKE) update-version-makefile VERSION=$(PROJECT_MAJOR_VERSION)\.$(PROJECT_MINOR_VERSION) + $(MAKE) create-commit COMMIT_MESSAGE="[Release] update version $(RELEASE_VERSION)" + @echo "INFO: Create feature branch and update the versions. Target branch $(BASE_BRANCH)" + $(MAKE) create-branch NAME=update-$(RELEASE_VERSION) BASE=$(BASE_BRANCH) + $(MAKE) update-mergify VERSION=$(RELEASE_BRANCH) + $(MAKE) update-version VERSION=$(NEXT_PROJECT_MINOR_VERSION) + $(MAKE) create-commit COMMIT_MESSAGE="[Release] update version $(NEXT_PROJECT_MINOR_VERSION)" + $(MAKE) update-changelog VERSION=$(RELEASE_VERSION) + $(MAKE) create-commit COMMIT_MESSAGE="[Release] update changelogs for $(RELEASE_BRANCH) release" + @echo "INFO: Push changes to $(PROJECT_OWNER)/apm-server and create the relevant Pull Requests" + git push origin $(RELEASE_BRANCH) + $(MAKE) create-pull-request BRANCH=update-$(RELEASE_VERSION) TARGET_BRANCH=$(BASE_BRANCH) TITLE="$(RELEASE_BRANCH): update docs, mergify, versions and changelogs" BODY="Merge as soon as the GitHub checks are green." # This is the contract with the GitHub action .github/workflows/run-major-release.yml. # The GitHub action will provide the below environment variables: @@ -172,14 +168,20 @@ update-version-makefile: ############################################ ## Create a new branch -## It will delete the branch if it already exists before the creation. +## If the branch already exists on the remote, fetch and check it out instead. .PHONY: create-branch create-branch: NAME=$${NAME} BASE=$${BASE} create-branch: @echo "::group::create-branch $(NAME)" - git checkout $(BASE) - git branch -D $(NAME) &>/dev/null || true - git checkout $(BASE) -b $(NAME) + @if git ls-remote --exit-code --heads origin "$(NAME)" > /dev/null 2>&1; then \ + echo "WARNING: Branch $(NAME) already exists. Fetching and checking out." ; \ + git fetch origin $(NAME):$(NAME) ; \ + git checkout $(NAME) ; \ + else \ + git branch -D $(NAME) &>/dev/null || true ; \ + git checkout $(BASE) ; \ + git checkout $(BASE) -b $(NAME) ; \ + fi @echo "::endgroup::" ## Create a new commit only if there is a diff. From 15c15b629640b2023350155322c647d84ecb68dc Mon Sep 17 00:00:00 2001 From: Nina Lee Date: Wed, 22 Jul 2026 13:40:41 -0500 Subject: [PATCH 7/8] update PR count check in create-pull-request target to filter by branch name --- release.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release.mk b/release.mk index d370c4dae07..b438aa3aeb5 100644 --- a/release.mk +++ b/release.mk @@ -217,7 +217,7 @@ create-pull-request: @echo "::group::create-pull-request $(BRANCH) -> $(TARGET_BRANCH)" @PR_COUNT=0 ; \ if [ "$(FORCE_PR_CREATION)" != "true" ]; then \ - PR_COUNT=$$(gh pr list --head "$(BRANCH)" --base "$(TARGET_BRANCH)" --label release --state all --json number --jq 'length' --repo $(PROJECT_OWNER)/apm-server) ; \ + PR_COUNT=$$(gh pr list --head "$(BRANCH)" --base "$(TARGET_BRANCH)" --label release --state all --json number,headRefName --jq '[.[] | select(.headRefName == "$(BRANCH)")] | length' --repo $(PROJECT_OWNER)/apm-server) ; \ fi ; \ if [ "$$PR_COUNT" -gt 0 ]; then \ echo "PR for $(BRANCH) -> $(TARGET_BRANCH) already exists, skipping." ; \ From 31a92d37f9b8c100b862abce22321663ae240d03 Mon Sep 17 00:00:00 2001 From: Nina Lee Date: Wed, 22 Jul 2026 13:44:30 -0500 Subject: [PATCH 8/8] update comment for create-branch --- release.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/release.mk b/release.mk index b438aa3aeb5..c56f6c7619b 100644 --- a/release.mk +++ b/release.mk @@ -169,6 +169,7 @@ update-version-makefile: ## Create a new branch ## If the branch already exists on the remote, fetch and check it out instead. +## Otherwise, delete the local branch if it exists and recreate it from BASE. .PHONY: create-branch create-branch: NAME=$${NAME} BASE=$${BASE} create-branch: