Skip to content

Commit 50a35d7

Browse files
committed
fix: handle race conditions on pr auto-merge
Signed-off-by: Frédéric BIDON <fredbi@yahoo.com>
1 parent 08a1777 commit 50a35d7

9 files changed

Lines changed: 142 additions & 95 deletions

.github/workflows/auto-merge.yml

Lines changed: 85 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ on:
99
1010
type: string
1111
required: false
12-
default: 'true'
12+
default: "true"
1313
organization-bot:
1414
description: |
1515
The bot name for your organization,
@@ -19,7 +19,7 @@ on:
1919
2020
type: string
2121
required: false
22-
default: 'bot-go-openapi[bot]'
22+
default: "bot-go-openapi[bot]"
2323

2424
permissions:
2525
contents: read
@@ -39,25 +39,72 @@ jobs:
3939
PR_URL: ${{ github.event.pull_request.html_url }}
4040
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
4141
steps:
42-
-
43-
name: Dependabot metadata
42+
- name: Dependabot metadata
4443
id: metadata
4544
uses: dependabot/fetch-metadata@21025c705c08248db411dc16f3619e6b5f9ea21a # v2.5.0
46-
-
47-
name: Auto-approve all dependabot PRs
45+
- name: Auto-approve all dependabot PRs
4846
run: gh pr review --approve "$PR_URL"
49-
-
50-
name: Auto-merge dependabot PRs for development dependencies
47+
- name: Auto-merge dependabot PRs for development dependencies
5148
if: ${{ contains(steps.metadata.outputs.dependency-group, 'development-dependencies') }}
52-
run: gh pr merge --auto --rebase "$PR_URL"
53-
-
54-
name: Auto-merge dependabot PRs for go-openapi patches
49+
run: |
50+
set +e # Don't exit on error
51+
OUTPUT=$(gh pr merge --auto --rebase "$PR_URL" 2>&1)
52+
EXIT_CODE=$?
53+
set -e # Re-enable exit on error
54+
# Check if error is due to race condition (merge already in progress)
55+
# GitHub GraphQL API returns: "GraphQL: Merge already in progress (mergePullRequest)"
56+
if echo "$OUTPUT" | grep -q "Merge already in progress"; then
57+
echo "::warning title=auto-merge::Auto-merge already handled by another workflow (race condition)"
58+
exit 0
59+
fi
60+
if echo "$OUTPUT" | grep -q "Pull request is already merged"; then
61+
echo "::warning title=auto-merge::Auto-merge already handled by another workflow (race condition)"
62+
exit 0
63+
fi
64+
# Unexpected error - fail the workflow
65+
echo "::error title=auto-merge::Failed to enable auto-merge"
66+
echo "$OUTPUT"
67+
exit $EXIT_CODE
68+
- name: Auto-merge dependabot PRs for go-openapi patches
5569
if: ${{ contains(steps.metadata.outputs.dependency-group, 'go-openapi-dependencies') && (steps.metadata.outputs.update-type == 'version-update:semver-minor' || steps.metadata.outputs.update-type == 'version-update:semver-patch') }}
56-
run: gh pr merge --auto --rebase "$PR_URL"
57-
-
58-
name: Auto-merge dependabot PRs for golang.org updates
70+
run: |
71+
set +e # Don't exit on error
72+
gh pr merge --auto --rebase "$PR_URL"
73+
# Check if error is due to race condition (merge already in progress)
74+
# GitHub GraphQL API returns: "GraphQL: Merge already in progress (mergePullRequest)"
75+
if echo "$OUTPUT" | grep -q "Merge already in progress"; then
76+
echo "::warning title=auto-merge::Auto-merge already handled by another workflow (race condition)"
77+
exit 0
78+
fi
79+
if echo "$OUTPUT" | grep -q "Pull request is already merged"; then
80+
echo "::warning title=auto-merge::Auto-merge already handled by another workflow (race condition)"
81+
exit 0
82+
fi
83+
# Unexpected error - fail the workflow
84+
echo "::error title=auto-merge::Failed to enable auto-merge"
85+
echo "$OUTPUT"
86+
exit $EXIT_CODE
87+
- name: Auto-merge dependabot PRs for golang.org updates
5988
if: ${{ contains(steps.metadata.outputs.dependency-group, 'golang-org-dependencies') }}
60-
run: gh pr merge --auto --rebase "$PR_URL"
89+
run: |
90+
set +e # Don't exit on error
91+
OUTPUT=$(gh pr merge --auto --rebase "$PR_URL" 2>&1)
92+
EXIT_CODE=$?
93+
set -e # Re-enable exit on error
94+
# Check if error is due to race condition (merge already in progress)
95+
# GitHub GraphQL API returns: "GraphQL: Merge already in progress (mergePullRequest)"
96+
if echo "$OUTPUT" | grep -q "Merge already in progress"; then
97+
echo "::warning title=auto-merge::Auto-merge already handled by another workflow (race condition)"
98+
exit 0
99+
fi
100+
if echo "$OUTPUT" | grep -q "Pull request is already merged"; then
101+
echo "::warning title=auto-merge::Auto-merge already handled by another workflow (race condition)"
102+
exit 0
103+
fi
104+
# Unexpected error - fail the workflow
105+
echo "::error title=auto-merge::Failed to enable auto-merge"
106+
echo "$OUTPUT"
107+
exit $EXIT_CODE
61108
62109
actions-bot:
63110
# description: |
@@ -73,18 +120,31 @@ jobs:
73120
PR_URL: ${{ github.event.pull_request.html_url }}
74121
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
75122
steps:
76-
-
77-
name: Checkout repository
123+
- name: Checkout repository
78124
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
79-
-
80-
name: Auto-approve all bot-go-openapi PRs
125+
- name: Auto-approve all bot-go-openapi PRs
81126
run: gh pr review --approve "$PR_URL"
82-
-
83-
name: Wait for all workflow runs to complete
84-
uses: go-openapi/gh-actions/ci-jobs/wait-pending-jobs@8340d5403ad368f2ddaa0bc3b10ce38a10099e2c # v1.4.3
127+
- name: Wait for all workflow runs to complete
128+
uses: go-openapi/gh-actions/ci-jobs/wait-pending-jobs@f7ed44020a2682556ac42fa9c210142495270354 # v1.4.5
85129
with:
86130
pr-url: ${{ env.PR_URL }}
87131
github-token: ${{ secrets.GITHUB_TOKEN }}
88-
-
89-
name: Auto-merge bot-go-openapi PRs
90-
run: gh pr merge --auto --rebase "$PR_URL"
132+
- name: Auto-merge bot-go-openapi PRs
133+
run: |
134+
set +e # Don't exit on error
135+
OUTPUT=$(gh pr merge --auto --rebase "$PR_URL" 2>&1)
136+
EXIT_CODE=$?
137+
# Check if error is due to race condition (merge already in progress)
138+
# GitHub GraphQL API returns: "GraphQL: Merge already in progress (mergePullRequest)"
139+
if echo "$OUTPUT" | grep -q "Merge already in progress"; then
140+
echo "::warning title=auto-merge::Auto-merge already handled by another workflow (race condition)"
141+
exit 0
142+
fi
143+
if echo "$OUTPUT" | grep -q "Pull request is already merged"; then
144+
echo "::warning title=auto-merge::Auto-merge already handled by another workflow (race condition)"
145+
exit 0
146+
fi
147+
# Unexpected error - fail the workflow
148+
echo "::error title=auto-merge::Failed to enable auto-merge"
149+
echo "$OUTPUT"
150+
exit $EXIT_CODE

.github/workflows/bump-release-monorepo.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ jobs:
112112
-
113113
name: Detect go mono-repo
114114
id: detect-monorepo
115-
uses: go-openapi/gh-actions/ci-jobs/detect-go-monorepo@8340d5403ad368f2ddaa0bc3b10ce38a10099e2c # v1.4.3
115+
uses: go-openapi/gh-actions/ci-jobs/detect-go-monorepo@f7ed44020a2682556ac42fa9c210142495270354 # v1.4.5
116116

117117
bump-release-single:
118118
name: Bump release (single module)
@@ -168,7 +168,7 @@ jobs:
168168
-
169169
name: Determine next tag
170170
id: bump-release
171-
uses: go-openapi/gh-actions/ci-jobs/next-tag@8340d5403ad368f2ddaa0bc3b10ce38a10099e2c # v1.4.3
171+
uses: go-openapi/gh-actions/ci-jobs/next-tag@f7ed44020a2682556ac42fa9c210142495270354 # v1.4.5
172172
with:
173173
bump-patch: ${{ steps.bump-check.outputs.bump-patch }}
174174
bump-minor: ${{ steps.bump-check.outputs.bump-minor }}
@@ -268,7 +268,7 @@ jobs:
268268
-
269269
name: Configure bot credentials
270270
if: ${{ inputs.enable-tag-signing == 'true' }}
271-
uses: go-openapi/gh-actions/ci-jobs/bot-credentials@8340d5403ad368f2ddaa0bc3b10ce38a10099e2c # v1.4.3
271+
uses: go-openapi/gh-actions/ci-jobs/bot-credentials@f7ed44020a2682556ac42fa9c210142495270354 # v1.4.5
272272
# This is using the GPG signature of bot-go-openapi.
273273
#
274274
# For go-openapi repos (using secrets: inherit):

.github/workflows/bump-release.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,15 +114,15 @@ jobs:
114114
-
115115
name: Determine next tag
116116
id: bump-release
117-
uses: go-openapi/gh-actions/ci-jobs/next-tag@8340d5403ad368f2ddaa0bc3b10ce38a10099e2c # v1.4.3
117+
uses: go-openapi/gh-actions/ci-jobs/next-tag@f7ed44020a2682556ac42fa9c210142495270354 # v1.4.5
118118
with:
119119
bump-patch: ${{ steps.bump-check.outputs.bump-patch }}
120120
bump-minor: ${{ steps.bump-check.outputs.bump-minor }}
121121
bump-major: ${{ steps.bump-check.outputs.bump-major }}
122122
-
123123
name: Configure bot credentials
124124
if: ${{ inputs.enable-tag-signing == 'true' }}
125-
uses: go-openapi/gh-actions/ci-jobs/bot-credentials@8340d5403ad368f2ddaa0bc3b10ce38a10099e2c # v1.4.3
125+
uses: go-openapi/gh-actions/ci-jobs/bot-credentials@f7ed44020a2682556ac42fa9c210142495270354 # v1.4.5
126126
# This is using the GPG signature of bot-go-openapi.
127127
#
128128
# For go-openapi repos (using secrets: inherit):

.github/workflows/collect-reports.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ jobs:
3232
path: reports/
3333
-
3434
name: Install go-junit-report
35-
uses: go-openapi/gh-actions/install/go-junit-report@8340d5403ad368f2ddaa0bc3b10ce38a10099e2c # v1.4.3
35+
uses: go-openapi/gh-actions/install/go-junit-report@f7ed44020a2682556ac42fa9c210142495270354 # v1.4.5
3636
-
3737
name: Convert test reports to a merged JUnit XML
3838
# NOTE: codecov test reports only support JUnit format at this moment. See https://docs.codecov.com/docs/test-analytics.
@@ -57,7 +57,7 @@ jobs:
5757
verbose: true
5858
-
5959
name: Install go-ctrf-json-reporter
60-
uses: go-openapi/gh-actions/install/go-ctrf-json-reporter@8340d5403ad368f2ddaa0bc3b10ce38a10099e2c # v1.4.3
60+
uses: go-openapi/gh-actions/install/go-ctrf-json-reporter@f7ed44020a2682556ac42fa9c210142495270354 # v1.4.5
6161
-
6262
name: Convert test reports to CTRF JSON
6363
# description: |

.github/workflows/contributors.yml

Lines changed: 22 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ on:
1313
When enabled, commits in the pull request will be signed with the bot's GPG key.
1414
required: false
1515
type: string
16-
default: 'true'
16+
default: "true"
1717
secrets:
1818
github-app-id:
1919
description: |
@@ -67,41 +67,36 @@ jobs:
6767
pull-request-url: ${{ steps.create-pull-request.outputs.pull-request-url }}
6868
pull-request-operation: ${{ steps.create-pull-request.outputs.pull-request-operation }}
6969
steps:
70-
-
71-
name: Checkout repository
70+
- name: Checkout repository
7271
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
73-
-
74-
name: Identify all-time contributors to this repository
72+
- name: Identify all-time contributors to this repository
7573
uses: github/contributors@0d5adc3833e89ee1f4145744f5d69313cf5ea238 # v1.7.8
7674
env:
7775
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
78-
REPOSITORY: ${{ github.repository }}
79-
LINK_TO_PROFILE: 'True'
80-
-
81-
name: Rename contributor file
76+
REPOSITORY: ${{ github.repository }}
77+
LINK_TO_PROFILE: "True"
78+
- name: Rename contributor file
8279
run: |
8380
rm -rf contributors.json
8481
mv contributors.md CONTRIBUTORS.md
85-
-
86-
name: Configure bot credentials
87-
uses: go-openapi/gh-actions/ci-jobs/bot-credentials@8340d5403ad368f2ddaa0bc3b10ce38a10099e2c # v1.4.3
82+
- name: Configure bot credentials
83+
uses: go-openapi/gh-actions/ci-jobs/bot-credentials@f7ed44020a2682556ac42fa9c210142495270354 # v1.4.5
8884
id: bot-credentials
8985
# For go-openapi repos (using secrets: inherit):
9086
# Falls back to: CI_BOT_APP_ID, CI_BOT_APP_PRIVATE_KEY, CI_BOT_GPG_PRIVATE_KEY, etc.
9187
#
9288
# For other orgs: explicitly pass secrets with your custom names
9389
with:
94-
enable-github-app: 'true'
90+
enable-github-app: "true"
9591
github-app-id: ${{ secrets.github-app-id || secrets.CI_BOT_APP_ID }}
9692
github-app-private-key: ${{ secrets.github-app-private-key || secrets.CI_BOT_APP_PRIVATE_KEY }}
9793
enable-gpg-signing: ${{ inputs.enable-commit-signing }}
9894
gpg-private-key: ${{ secrets.gpg-private-key || secrets.CI_BOT_GPG_PRIVATE_KEY }}
9995
gpg-passphrase: ${{ secrets.gpg-passphrase || secrets.CI_BOT_GPG_PASSPHRASE }}
10096
gpg-fingerprint: ${{ secrets.gpg-fingerprint || secrets.CI_BOT_SIGNING_KEY }}
101-
enable-commit-signing: 'true'
102-
enable-tag-signing: 'false'
103-
-
104-
name: Create a PR
97+
enable-commit-signing: "true"
98+
enable-tag-signing: "false"
99+
- name: Create a PR
105100
id: create-pull-request
106101
uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8.1.0
107102
with:
@@ -122,8 +117,7 @@ jobs:
122117
runs-on: ubuntu-latest
123118
if: ${{ needs.update-contributors.outputs.pull-request-operation == 'none' }}
124119
steps:
125-
-
126-
name: Report no change needed
120+
- name: Report no change needed
127121
run: |
128122
echo "::notice title=no-change::No change needed to the contributors file"
129123
exit 0
@@ -146,20 +140,16 @@ jobs:
146140
PR_URL: ${{ needs.update-contributors.outputs.pull-request-url }}
147141
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
148142
steps:
149-
-
150-
name: Checkout repository
143+
- name: Checkout repository
151144
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
152-
-
153-
name: Auto-approve PR
145+
- name: Auto-approve PR
154146
run: gh pr review --approve "$PR_URL"
155-
-
156-
name: Wait for all workflow runs to complete
157-
uses: go-openapi/gh-actions/ci-jobs/wait-pending-jobs@8340d5403ad368f2ddaa0bc3b10ce38a10099e2c # v1.4.3
147+
- name: Wait for all workflow runs to complete
148+
uses: go-openapi/gh-actions/ci-jobs/wait-pending-jobs@f7ed44020a2682556ac42fa9c210142495270354 # v1.4.5
158149
with:
159150
pr-url: ${{ env.PR_URL }}
160151
github-token: ${{ secrets.GITHUB_TOKEN }}
161-
-
162-
name: Enable auto-merge
152+
- name: Enable auto-merge
163153
run: |
164154
# Attempt to enable auto-merge, handling race condition gracefully
165155
set +e # Don't exit on error
@@ -178,6 +168,10 @@ jobs:
178168
echo "::warning title=auto-merge::Auto-merge already handled by another workflow (race condition)"
179169
exit 0
180170
fi
171+
if echo "$OUTPUT" | grep -q "Pull request is already merged"; then
172+
echo "::warning title=auto-merge::Auto-merge already handled by another workflow (race condition)"
173+
exit 0
174+
fi
181175
182176
# Unexpected error - fail the workflow
183177
echo "::error title=auto-merge::Failed to enable auto-merge"

.github/workflows/go-test-monorepo.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ jobs:
3535
-
3636
name: Detect go mono-repo
3737
id: detect-monorepo
38-
uses: go-openapi/gh-actions/ci-jobs/detect-go-monorepo@8340d5403ad368f2ddaa0bc3b10ce38a10099e2c # v1.4.3
38+
uses: go-openapi/gh-actions/ci-jobs/detect-go-monorepo@f7ed44020a2682556ac42fa9c210142495270354 # v1.4.5
3939
-
4040
name: golangci-lint [monorepo]
4141
# golangci-action v9.1+ has an experimental built-in mono repo detection setup.
@@ -92,10 +92,10 @@ jobs:
9292
-
9393
name: Detect go version capabilities
9494
id: detect-go-version
95-
uses: go-openapi/gh-actions/ci-jobs/detect-go-version@8340d5403ad368f2ddaa0bc3b10ce38a10099e2c # v1.4.3
95+
uses: go-openapi/gh-actions/ci-jobs/detect-go-version@f7ed44020a2682556ac42fa9c210142495270354 # v1.4.5
9696
-
9797
name: Install gotestsum
98-
uses: go-openapi/gh-actions/install/gotestsum@8340d5403ad368f2ddaa0bc3b10ce38a10099e2c # v1.4.3
98+
uses: go-openapi/gh-actions/install/gotestsum@f7ed44020a2682556ac42fa9c210142495270354 # v1.4.5
9999
-
100100
name: Ensure TMP is created on windows runners
101101
# On windows, some tests require testing.TempDir to reside on the same drive as the code.

.github/workflows/go-test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ jobs:
5353
cache: true
5454
-
5555
name: Install gotestsum
56-
uses: go-openapi/gh-actions/install/gotestsum@8340d5403ad368f2ddaa0bc3b10ce38a10099e2c # v1.4.3
56+
uses: go-openapi/gh-actions/install/gotestsum@f7ed44020a2682556ac42fa9c210142495270354 # v1.4.5
5757
-
5858
name: Ensure TMP is created on windows runners
5959
# On windows, some tests require testing.TempDir to reside on the same drive as the code.

0 commit comments

Comments
 (0)