Skip to content

Commit 0ef544c

Browse files
authored
Merge pull request #5668 from sysown/v3.0-fix-init-release-race
ci: drop concurrency group on init_release, use race-tolerant find-or-create
2 parents 4beb6a8 + ac64389 commit 0ef544c

156 files changed

Lines changed: 4836 additions & 2340 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/CI-package-amd64-almalinux10-clang.yml

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@ concurrency:
1515
jobs:
1616
init_release:
1717
runs-on: ubuntu-latest
18-
concurrency:
19-
group: release-init-${{ github.sha }}
20-
cancel-in-progress: false
18+
# No concurrency group: GitHub's "1 running + 1 pending" rule causes
19+
# mass cancellations when many workflows share a group. Instead we
20+
# run all init jobs in parallel and converge via a race-tolerant
21+
# find-or-create loop; all workers deterministically pick the
22+
# lowest-id draft matching this SHA+tag.
2123
outputs:
2224
release_id: ${{ steps.release.outputs.release_id }}
2325
release_name: ${{ steps.release.outputs.release_name }}
@@ -38,22 +40,36 @@ jobs:
3840
GIT_DESC=$(git describe --long --abbrev=7 --tags)
3941
TAG_NAME="${{ github.ref_name }}-head"
4042
RELEASE_NAME="${TAG_NAME} - ${GIT_DESC}"
41-
echo "Target: $RELEASE_NAME (sha ${{ github.sha }})"
43+
REPO="${{ github.repository }}"
44+
SHA="${{ github.sha }}"
45+
echo "Target: $RELEASE_NAME (sha $SHA)"
4246
43-
RELEASE_ID=$(gh api "repos/${{ github.repository }}/releases" --paginate \
44-
--jq ".[] | select(.draft==true and .name==\"${RELEASE_NAME}\") | .id" | head -1)
47+
# Stagger start to reduce the thundering-herd on first create
48+
sleep $(( RANDOM % 10 ))
4549
46-
if [ -z "$RELEASE_ID" ]; then
47-
echo "No matching draft; creating."
48-
RELEASE_ID=$(gh api -X POST "repos/${{ github.repository }}/releases" \
50+
RELEASE_ID=""
51+
for attempt in 1 2 3 4 5 6; do
52+
IDS=$(gh api "repos/${REPO}/releases" --paginate \
53+
--jq ".[] | select(.draft==true and .target_commitish==\"${SHA}\" and .tag_name==\"${TAG_NAME}\") | .id" \
54+
| sort -n)
55+
if [ -n "$IDS" ]; then
56+
RELEASE_ID=$(echo "$IDS" | head -1)
57+
NDUPES=$(echo "$IDS" | wc -l)
58+
echo "attempt ${attempt}: found ${NDUPES} draft(s); using lowest id=${RELEASE_ID}"
59+
break
60+
fi
61+
echo "attempt ${attempt}: no matching draft; creating"
62+
gh api -X POST "repos/${REPO}/releases" \
4963
-f tag_name="${TAG_NAME}" \
5064
-f name="${RELEASE_NAME}" \
51-
-f target_commitish="${{ github.sha }}" \
52-
-F draft=true -F prerelease=true \
53-
--jq '.id')
54-
echo "Created release id=${RELEASE_ID}"
55-
else
56-
echo "Reusing existing draft id=${RELEASE_ID}"
65+
-f target_commitish="${SHA}" \
66+
-F draft=true -F prerelease=true >/dev/null 2>&1 || true
67+
sleep $(( (RANDOM % 4) + 2 ))
68+
done
69+
70+
if [ -z "$RELEASE_ID" ]; then
71+
echo "ERROR: could not find or create draft release after retries" >&2
72+
exit 1
5773
fi
5874
5975
echo "release_id=${RELEASE_ID}" >> "$GITHUB_OUTPUT"

.github/workflows/CI-package-amd64-almalinux10-dbg.yml

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@ concurrency:
1515
jobs:
1616
init_release:
1717
runs-on: ubuntu-latest
18-
concurrency:
19-
group: release-init-${{ github.sha }}
20-
cancel-in-progress: false
18+
# No concurrency group: GitHub's "1 running + 1 pending" rule causes
19+
# mass cancellations when many workflows share a group. Instead we
20+
# run all init jobs in parallel and converge via a race-tolerant
21+
# find-or-create loop; all workers deterministically pick the
22+
# lowest-id draft matching this SHA+tag.
2123
outputs:
2224
release_id: ${{ steps.release.outputs.release_id }}
2325
release_name: ${{ steps.release.outputs.release_name }}
@@ -38,22 +40,36 @@ jobs:
3840
GIT_DESC=$(git describe --long --abbrev=7 --tags)
3941
TAG_NAME="${{ github.ref_name }}-head"
4042
RELEASE_NAME="${TAG_NAME} - ${GIT_DESC}"
41-
echo "Target: $RELEASE_NAME (sha ${{ github.sha }})"
43+
REPO="${{ github.repository }}"
44+
SHA="${{ github.sha }}"
45+
echo "Target: $RELEASE_NAME (sha $SHA)"
4246
43-
RELEASE_ID=$(gh api "repos/${{ github.repository }}/releases" --paginate \
44-
--jq ".[] | select(.draft==true and .name==\"${RELEASE_NAME}\") | .id" | head -1)
47+
# Stagger start to reduce the thundering-herd on first create
48+
sleep $(( RANDOM % 10 ))
4549
46-
if [ -z "$RELEASE_ID" ]; then
47-
echo "No matching draft; creating."
48-
RELEASE_ID=$(gh api -X POST "repos/${{ github.repository }}/releases" \
50+
RELEASE_ID=""
51+
for attempt in 1 2 3 4 5 6; do
52+
IDS=$(gh api "repos/${REPO}/releases" --paginate \
53+
--jq ".[] | select(.draft==true and .target_commitish==\"${SHA}\" and .tag_name==\"${TAG_NAME}\") | .id" \
54+
| sort -n)
55+
if [ -n "$IDS" ]; then
56+
RELEASE_ID=$(echo "$IDS" | head -1)
57+
NDUPES=$(echo "$IDS" | wc -l)
58+
echo "attempt ${attempt}: found ${NDUPES} draft(s); using lowest id=${RELEASE_ID}"
59+
break
60+
fi
61+
echo "attempt ${attempt}: no matching draft; creating"
62+
gh api -X POST "repos/${REPO}/releases" \
4963
-f tag_name="${TAG_NAME}" \
5064
-f name="${RELEASE_NAME}" \
51-
-f target_commitish="${{ github.sha }}" \
52-
-F draft=true -F prerelease=true \
53-
--jq '.id')
54-
echo "Created release id=${RELEASE_ID}"
55-
else
56-
echo "Reusing existing draft id=${RELEASE_ID}"
65+
-f target_commitish="${SHA}" \
66+
-F draft=true -F prerelease=true >/dev/null 2>&1 || true
67+
sleep $(( (RANDOM % 4) + 2 ))
68+
done
69+
70+
if [ -z "$RELEASE_ID" ]; then
71+
echo "ERROR: could not find or create draft release after retries" >&2
72+
exit 1
5773
fi
5874
5975
echo "release_id=${RELEASE_ID}" >> "$GITHUB_OUTPUT"

.github/workflows/CI-package-amd64-almalinux10-genai-clang.yml

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@ concurrency:
1515
jobs:
1616
init_release:
1717
runs-on: ubuntu-latest
18-
concurrency:
19-
group: release-init-${{ github.sha }}
20-
cancel-in-progress: false
18+
# No concurrency group: GitHub's "1 running + 1 pending" rule causes
19+
# mass cancellations when many workflows share a group. Instead we
20+
# run all init jobs in parallel and converge via a race-tolerant
21+
# find-or-create loop; all workers deterministically pick the
22+
# lowest-id draft matching this SHA+tag.
2123
outputs:
2224
release_id: ${{ steps.release.outputs.release_id }}
2325
release_name: ${{ steps.release.outputs.release_name }}
@@ -38,22 +40,36 @@ jobs:
3840
GIT_DESC=$(git describe --long --abbrev=7 --tags)
3941
TAG_NAME="${{ github.ref_name }}-head"
4042
RELEASE_NAME="${TAG_NAME} - ${GIT_DESC}"
41-
echo "Target: $RELEASE_NAME (sha ${{ github.sha }})"
43+
REPO="${{ github.repository }}"
44+
SHA="${{ github.sha }}"
45+
echo "Target: $RELEASE_NAME (sha $SHA)"
4246
43-
RELEASE_ID=$(gh api "repos/${{ github.repository }}/releases" --paginate \
44-
--jq ".[] | select(.draft==true and .name==\"${RELEASE_NAME}\") | .id" | head -1)
47+
# Stagger start to reduce the thundering-herd on first create
48+
sleep $(( RANDOM % 10 ))
4549
46-
if [ -z "$RELEASE_ID" ]; then
47-
echo "No matching draft; creating."
48-
RELEASE_ID=$(gh api -X POST "repos/${{ github.repository }}/releases" \
50+
RELEASE_ID=""
51+
for attempt in 1 2 3 4 5 6; do
52+
IDS=$(gh api "repos/${REPO}/releases" --paginate \
53+
--jq ".[] | select(.draft==true and .target_commitish==\"${SHA}\" and .tag_name==\"${TAG_NAME}\") | .id" \
54+
| sort -n)
55+
if [ -n "$IDS" ]; then
56+
RELEASE_ID=$(echo "$IDS" | head -1)
57+
NDUPES=$(echo "$IDS" | wc -l)
58+
echo "attempt ${attempt}: found ${NDUPES} draft(s); using lowest id=${RELEASE_ID}"
59+
break
60+
fi
61+
echo "attempt ${attempt}: no matching draft; creating"
62+
gh api -X POST "repos/${REPO}/releases" \
4963
-f tag_name="${TAG_NAME}" \
5064
-f name="${RELEASE_NAME}" \
51-
-f target_commitish="${{ github.sha }}" \
52-
-F draft=true -F prerelease=true \
53-
--jq '.id')
54-
echo "Created release id=${RELEASE_ID}"
55-
else
56-
echo "Reusing existing draft id=${RELEASE_ID}"
65+
-f target_commitish="${SHA}" \
66+
-F draft=true -F prerelease=true >/dev/null 2>&1 || true
67+
sleep $(( (RANDOM % 4) + 2 ))
68+
done
69+
70+
if [ -z "$RELEASE_ID" ]; then
71+
echo "ERROR: could not find or create draft release after retries" >&2
72+
exit 1
5773
fi
5874
5975
echo "release_id=${RELEASE_ID}" >> "$GITHUB_OUTPUT"

.github/workflows/CI-package-amd64-almalinux10-genai-dbg.yml

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@ concurrency:
1515
jobs:
1616
init_release:
1717
runs-on: ubuntu-latest
18-
concurrency:
19-
group: release-init-${{ github.sha }}
20-
cancel-in-progress: false
18+
# No concurrency group: GitHub's "1 running + 1 pending" rule causes
19+
# mass cancellations when many workflows share a group. Instead we
20+
# run all init jobs in parallel and converge via a race-tolerant
21+
# find-or-create loop; all workers deterministically pick the
22+
# lowest-id draft matching this SHA+tag.
2123
outputs:
2224
release_id: ${{ steps.release.outputs.release_id }}
2325
release_name: ${{ steps.release.outputs.release_name }}
@@ -38,22 +40,36 @@ jobs:
3840
GIT_DESC=$(git describe --long --abbrev=7 --tags)
3941
TAG_NAME="${{ github.ref_name }}-head"
4042
RELEASE_NAME="${TAG_NAME} - ${GIT_DESC}"
41-
echo "Target: $RELEASE_NAME (sha ${{ github.sha }})"
43+
REPO="${{ github.repository }}"
44+
SHA="${{ github.sha }}"
45+
echo "Target: $RELEASE_NAME (sha $SHA)"
4246
43-
RELEASE_ID=$(gh api "repos/${{ github.repository }}/releases" --paginate \
44-
--jq ".[] | select(.draft==true and .name==\"${RELEASE_NAME}\") | .id" | head -1)
47+
# Stagger start to reduce the thundering-herd on first create
48+
sleep $(( RANDOM % 10 ))
4549
46-
if [ -z "$RELEASE_ID" ]; then
47-
echo "No matching draft; creating."
48-
RELEASE_ID=$(gh api -X POST "repos/${{ github.repository }}/releases" \
50+
RELEASE_ID=""
51+
for attempt in 1 2 3 4 5 6; do
52+
IDS=$(gh api "repos/${REPO}/releases" --paginate \
53+
--jq ".[] | select(.draft==true and .target_commitish==\"${SHA}\" and .tag_name==\"${TAG_NAME}\") | .id" \
54+
| sort -n)
55+
if [ -n "$IDS" ]; then
56+
RELEASE_ID=$(echo "$IDS" | head -1)
57+
NDUPES=$(echo "$IDS" | wc -l)
58+
echo "attempt ${attempt}: found ${NDUPES} draft(s); using lowest id=${RELEASE_ID}"
59+
break
60+
fi
61+
echo "attempt ${attempt}: no matching draft; creating"
62+
gh api -X POST "repos/${REPO}/releases" \
4963
-f tag_name="${TAG_NAME}" \
5064
-f name="${RELEASE_NAME}" \
51-
-f target_commitish="${{ github.sha }}" \
52-
-F draft=true -F prerelease=true \
53-
--jq '.id')
54-
echo "Created release id=${RELEASE_ID}"
55-
else
56-
echo "Reusing existing draft id=${RELEASE_ID}"
65+
-f target_commitish="${SHA}" \
66+
-F draft=true -F prerelease=true >/dev/null 2>&1 || true
67+
sleep $(( (RANDOM % 4) + 2 ))
68+
done
69+
70+
if [ -z "$RELEASE_ID" ]; then
71+
echo "ERROR: could not find or create draft release after retries" >&2
72+
exit 1
5773
fi
5874
5975
echo "release_id=${RELEASE_ID}" >> "$GITHUB_OUTPUT"

.github/workflows/CI-package-amd64-almalinux10-genai.yml

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@ concurrency:
1515
jobs:
1616
init_release:
1717
runs-on: ubuntu-latest
18-
concurrency:
19-
group: release-init-${{ github.sha }}
20-
cancel-in-progress: false
18+
# No concurrency group: GitHub's "1 running + 1 pending" rule causes
19+
# mass cancellations when many workflows share a group. Instead we
20+
# run all init jobs in parallel and converge via a race-tolerant
21+
# find-or-create loop; all workers deterministically pick the
22+
# lowest-id draft matching this SHA+tag.
2123
outputs:
2224
release_id: ${{ steps.release.outputs.release_id }}
2325
release_name: ${{ steps.release.outputs.release_name }}
@@ -38,22 +40,36 @@ jobs:
3840
GIT_DESC=$(git describe --long --abbrev=7 --tags)
3941
TAG_NAME="${{ github.ref_name }}-head"
4042
RELEASE_NAME="${TAG_NAME} - ${GIT_DESC}"
41-
echo "Target: $RELEASE_NAME (sha ${{ github.sha }})"
43+
REPO="${{ github.repository }}"
44+
SHA="${{ github.sha }}"
45+
echo "Target: $RELEASE_NAME (sha $SHA)"
4246
43-
RELEASE_ID=$(gh api "repos/${{ github.repository }}/releases" --paginate \
44-
--jq ".[] | select(.draft==true and .name==\"${RELEASE_NAME}\") | .id" | head -1)
47+
# Stagger start to reduce the thundering-herd on first create
48+
sleep $(( RANDOM % 10 ))
4549
46-
if [ -z "$RELEASE_ID" ]; then
47-
echo "No matching draft; creating."
48-
RELEASE_ID=$(gh api -X POST "repos/${{ github.repository }}/releases" \
50+
RELEASE_ID=""
51+
for attempt in 1 2 3 4 5 6; do
52+
IDS=$(gh api "repos/${REPO}/releases" --paginate \
53+
--jq ".[] | select(.draft==true and .target_commitish==\"${SHA}\" and .tag_name==\"${TAG_NAME}\") | .id" \
54+
| sort -n)
55+
if [ -n "$IDS" ]; then
56+
RELEASE_ID=$(echo "$IDS" | head -1)
57+
NDUPES=$(echo "$IDS" | wc -l)
58+
echo "attempt ${attempt}: found ${NDUPES} draft(s); using lowest id=${RELEASE_ID}"
59+
break
60+
fi
61+
echo "attempt ${attempt}: no matching draft; creating"
62+
gh api -X POST "repos/${REPO}/releases" \
4963
-f tag_name="${TAG_NAME}" \
5064
-f name="${RELEASE_NAME}" \
51-
-f target_commitish="${{ github.sha }}" \
52-
-F draft=true -F prerelease=true \
53-
--jq '.id')
54-
echo "Created release id=${RELEASE_ID}"
55-
else
56-
echo "Reusing existing draft id=${RELEASE_ID}"
65+
-f target_commitish="${SHA}" \
66+
-F draft=true -F prerelease=true >/dev/null 2>&1 || true
67+
sleep $(( (RANDOM % 4) + 2 ))
68+
done
69+
70+
if [ -z "$RELEASE_ID" ]; then
71+
echo "ERROR: could not find or create draft release after retries" >&2
72+
exit 1
5773
fi
5874
5975
echo "release_id=${RELEASE_ID}" >> "$GITHUB_OUTPUT"

.github/workflows/CI-package-amd64-almalinux10-v31-clang.yml

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@ concurrency:
1515
jobs:
1616
init_release:
1717
runs-on: ubuntu-latest
18-
concurrency:
19-
group: release-init-${{ github.sha }}
20-
cancel-in-progress: false
18+
# No concurrency group: GitHub's "1 running + 1 pending" rule causes
19+
# mass cancellations when many workflows share a group. Instead we
20+
# run all init jobs in parallel and converge via a race-tolerant
21+
# find-or-create loop; all workers deterministically pick the
22+
# lowest-id draft matching this SHA+tag.
2123
outputs:
2224
release_id: ${{ steps.release.outputs.release_id }}
2325
release_name: ${{ steps.release.outputs.release_name }}
@@ -38,22 +40,36 @@ jobs:
3840
GIT_DESC=$(git describe --long --abbrev=7 --tags)
3941
TAG_NAME="${{ github.ref_name }}-head"
4042
RELEASE_NAME="${TAG_NAME} - ${GIT_DESC}"
41-
echo "Target: $RELEASE_NAME (sha ${{ github.sha }})"
43+
REPO="${{ github.repository }}"
44+
SHA="${{ github.sha }}"
45+
echo "Target: $RELEASE_NAME (sha $SHA)"
4246
43-
RELEASE_ID=$(gh api "repos/${{ github.repository }}/releases" --paginate \
44-
--jq ".[] | select(.draft==true and .name==\"${RELEASE_NAME}\") | .id" | head -1)
47+
# Stagger start to reduce the thundering-herd on first create
48+
sleep $(( RANDOM % 10 ))
4549
46-
if [ -z "$RELEASE_ID" ]; then
47-
echo "No matching draft; creating."
48-
RELEASE_ID=$(gh api -X POST "repos/${{ github.repository }}/releases" \
50+
RELEASE_ID=""
51+
for attempt in 1 2 3 4 5 6; do
52+
IDS=$(gh api "repos/${REPO}/releases" --paginate \
53+
--jq ".[] | select(.draft==true and .target_commitish==\"${SHA}\" and .tag_name==\"${TAG_NAME}\") | .id" \
54+
| sort -n)
55+
if [ -n "$IDS" ]; then
56+
RELEASE_ID=$(echo "$IDS" | head -1)
57+
NDUPES=$(echo "$IDS" | wc -l)
58+
echo "attempt ${attempt}: found ${NDUPES} draft(s); using lowest id=${RELEASE_ID}"
59+
break
60+
fi
61+
echo "attempt ${attempt}: no matching draft; creating"
62+
gh api -X POST "repos/${REPO}/releases" \
4963
-f tag_name="${TAG_NAME}" \
5064
-f name="${RELEASE_NAME}" \
51-
-f target_commitish="${{ github.sha }}" \
52-
-F draft=true -F prerelease=true \
53-
--jq '.id')
54-
echo "Created release id=${RELEASE_ID}"
55-
else
56-
echo "Reusing existing draft id=${RELEASE_ID}"
65+
-f target_commitish="${SHA}" \
66+
-F draft=true -F prerelease=true >/dev/null 2>&1 || true
67+
sleep $(( (RANDOM % 4) + 2 ))
68+
done
69+
70+
if [ -z "$RELEASE_ID" ]; then
71+
echo "ERROR: could not find or create draft release after retries" >&2
72+
exit 1
5773
fi
5874
5975
echo "release_id=${RELEASE_ID}" >> "$GITHUB_OUTPUT"

0 commit comments

Comments
 (0)