Skip to content

Commit 4a2ab03

Browse files
cpcloudcursoragent
andcommitted
Require explicit commit for cuda-pathfinder release workflow
Pinning releases to a user-provided SHA prevents accidentally releasing additional commits merged to main while a release is being prepared. This also guards against reusing an existing tag that points at a different commit. Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 34ac246 commit 4a2ab03

File tree

1 file changed

+41
-4
lines changed

1 file changed

+41
-4
lines changed

.github/workflows/release-cuda-pathfinder.yml

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44

55
# One-click release workflow for cuda-pathfinder.
66
#
7-
# Provide a version number. The workflow automatically finds the CI run and
8-
# creates the git tag, creates a draft GitHub release with the standard
7+
# Provide a version number and commit SHA. The workflow automatically finds
8+
# the CI run and creates the git tag, creates a draft GitHub release with the standard
99
# body, builds versioned docs, uploads source archive + wheels to the
1010
# release, publishes to TestPyPI, verifies the install, publishes to PyPI,
1111
# verifies again, and finally marks the release as published.
@@ -19,6 +19,10 @@ on:
1919
description: "Version to release (e.g. 1.3.5)"
2020
required: true
2121
type: string
22+
commit:
23+
description: "Commit SHA to release (must be on default branch)"
24+
required: true
25+
type: string
2226

2327
concurrency:
2428
group: release-cuda-pathfinder
@@ -70,6 +74,33 @@ jobs:
7074
echo "version=${version}"
7175
} >> "$GITHUB_OUTPUT"
7276
77+
- name: Validate and resolve commit
78+
id: commit
79+
env:
80+
COMMIT_INPUT: ${{ inputs.commit }}
81+
DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
82+
run: |
83+
# Require a full SHA to avoid ambiguity and accidental releases.
84+
if [[ ! "${COMMIT_INPUT}" =~ ^[0-9a-fA-F]{40}$ ]]; then
85+
echo "::error::Commit must be a full 40-character SHA, got: ${COMMIT_INPUT}"
86+
exit 1
87+
fi
88+
89+
git fetch --no-tags origin "${DEFAULT_BRANCH}"
90+
commit=$(git rev-parse --verify "${COMMIT_INPUT}^{commit}" 2>/dev/null || true)
91+
if [[ -z "${commit}" ]]; then
92+
echo "::error::Commit not found in repository: ${COMMIT_INPUT}"
93+
exit 1
94+
fi
95+
96+
if ! git merge-base --is-ancestor "${commit}" "origin/${DEFAULT_BRANCH}"; then
97+
echo "::error::Commit ${commit} is not reachable from origin/${DEFAULT_BRANCH}"
98+
exit 1
99+
fi
100+
101+
echo "commit=${commit}" >> "$GITHUB_OUTPUT"
102+
echo "Using release commit: ${commit}"
103+
73104
- name: Check release notes exist
74105
env:
75106
VERSION: ${{ steps.vars.outputs.version }}
@@ -90,11 +121,17 @@ jobs:
90121
- name: Create tag
91122
env:
92123
TAG: ${{ steps.vars.outputs.tag }}
124+
TARGET_COMMIT: ${{ steps.commit.outputs.commit }}
93125
run: |
94126
if git rev-parse "${TAG}" >/dev/null 2>&1; then
95-
echo "Tag ${TAG} already exists"
127+
existing_commit=$(git rev-parse "${TAG}^{commit}")
128+
if [[ "${existing_commit}" != "${TARGET_COMMIT}" ]]; then
129+
echo "::error::Tag ${TAG} already exists at ${existing_commit}, expected ${TARGET_COMMIT}"
130+
exit 1
131+
fi
132+
echo "Tag ${TAG} already exists at requested commit ${TARGET_COMMIT}"
96133
else
97-
git tag "${TAG}"
134+
git tag "${TAG}" "${TARGET_COMMIT}"
98135
git push origin "${TAG}"
99136
fi
100137

0 commit comments

Comments
 (0)