@@ -23,8 +23,15 @@ defaults:
2323 shell : bash
2424
2525jobs :
26+ validate :
27+ name : Validate
28+ uses : ./.github/workflows/validate.yml
29+ with :
30+ ref : ${{ github.event.inputs.tag || github.ref }}
31+
2632 wheel :
2733 name : Build wheel
34+ needs : validate
2835 runs-on : ubuntu-24.04
2936 env :
3037 IMPORT_NAME : src_py_lib
4552 python-version : ${{ env.PYTHON_VERSION }}
4653 cache : pip
4754
55+ - name : Cache uv
56+ uses : actions/cache@v4
57+ with :
58+ path : ~/.cache/uv
59+ key : uv-${{ runner.os }}-py${{ env.PYTHON_VERSION }}-${{ hashFiles('uv.lock') }}
60+ restore-keys : |
61+ uv-${{ runner.os }}-py${{ env.PYTHON_VERSION }}-
62+
4863 - name : Install build tools
4964 run : |
5065 python -m pip install --upgrade pip
6277 echo "::error title=Missing tag::Tag '${release_tag}' was not fetched. Create and push it before running this workflow."
6378 exit 1
6479 fi
80+ tag_revision="$(git rev-list -n 1 "${release_tag}")"
81+ git fetch --no-tags origin main
82+ main_revision="$(git rev-parse origin/main)"
83+ if ! git merge-base --is-ancestor "${tag_revision}" "${main_revision}"; then
84+ echo "::error title=Tag is not on main::Tag '${release_tag}' points at ${tag_revision}, which is not reachable from origin/main."
85+ echo "::error::Merge the release PR first, then tag the main commit."
86+ exit 1
87+ fi
6588
6689 project_version=$(uv run --frozen python - <<'PY'
6790 import tomllib
@@ -77,22 +100,6 @@ jobs:
77100
78101 echo "tag=${release_tag}" >> "${GITHUB_OUTPUT}"
79102
80- - name : Validate package
81- run : |
82- uv lock --check
83- uv run --frozen ruff check .
84- uv run --frozen ruff format --check .
85- uv run --frozen pyright
86- uv run --frozen python -m unittest discover -s tests
87- uv run --frozen python - <<'PY'
88- import os
89-
90- import src_py_lib
91-
92- if src_py_lib.__name__ != os.environ["IMPORT_NAME"]:
93- raise SystemExit(f"unexpected import name: {src_py_lib.__name__}")
94- PY
95-
96103 - name : Build distributions
97104 id : build
98105 run : |
@@ -115,17 +122,24 @@ jobs:
115122 wheel_path="${project_wheels[0]}"
116123 wheel_name="$(basename "${wheel_path}")"
117124 source_distribution_path="${source_distributions[0]}"
118- checksum_path="${wheel_path}.sha256"
125+ source_distribution_name="$(basename "${source_distribution_path}")"
126+ wheel_checksum_path="${wheel_path}.sha256"
127+ source_distribution_checksum_path="${source_distribution_path}.sha256"
119128
120129 (
121130 cd "$(dirname "${wheel_path}")"
122- shasum -a 256 "${wheel_name}" > "$(basename "${checksum_path}")"
131+ shasum -a 256 "${wheel_name}" > "$(basename "${wheel_checksum_path}")"
132+ shasum -a 256 "${source_distribution_name}" > "$(basename "${source_distribution_checksum_path}")"
123133 )
124134
125- echo "wheel_path=${wheel_path}" >> "${GITHUB_OUTPUT}"
126- echo "wheel_name=${wheel_name}" >> "${GITHUB_OUTPUT}"
127- echo "source_distribution_path=${source_distribution_path}" >> "${GITHUB_OUTPUT}"
128- echo "checksum_path=${checksum_path}" >> "${GITHUB_OUTPUT}"
135+ {
136+ echo "wheel_path=${wheel_path}"
137+ echo "wheel_name=${wheel_name}"
138+ echo "source_distribution_path=${source_distribution_path}"
139+ echo "source_distribution_name=${source_distribution_name}"
140+ echo "wheel_checksum_path=${wheel_checksum_path}"
141+ echo "source_distribution_checksum_path=${source_distribution_checksum_path}"
142+ } >> "${GITHUB_OUTPUT}"
129143
130144 - name : Smoke test installed wheel
131145 run : |
@@ -147,6 +161,7 @@ jobs:
147161 run : |
148162 release_tag="${{ steps.release.outputs.tag }}"
149163 wheel_name="${{ steps.build.outputs.wheel_name }}"
164+ source_distribution_name="${{ steps.build.outputs.source_distribution_name }}"
150165 notes_path="build/release/release-notes.md"
151166 cat > "${notes_path}" <<EOF
152167 ## Install
@@ -163,13 +178,19 @@ jobs:
163178 pip install "https://github.com/sourcegraph/src-py-lib/releases/download/${release_tag}/${wheel_name}"
164179 \`\`\`
165180
181+ Source distribution:
182+
183+ \`\`\`sh
184+ curl -LO "https://github.com/sourcegraph/src-py-lib/releases/download/${release_tag}/${source_distribution_name}"
185+ \`\`\`
186+
166187 Or install this tag with uv:
167188
168189 \`\`\`sh
169190 uv add "git+https://github.com/sourcegraph/src-py-lib.git@${release_tag}"
170191 \`\`\`
171192
172- Verify downloaded wheel assets with the matching \`.sha256\` file .
193+ Verify downloaded assets with the matching \`.sha256\` files .
173194 EOF
174195 echo "path=${notes_path}" >> "${GITHUB_OUTPUT}"
175196
@@ -179,7 +200,9 @@ jobs:
179200 name : src-py-lib-release
180201 path : |
181202 ${{ steps.build.outputs.wheel_path }}
182- ${{ steps.build.outputs.checksum_path }}
203+ ${{ steps.build.outputs.source_distribution_path }}
204+ ${{ steps.build.outputs.wheel_checksum_path }}
205+ ${{ steps.build.outputs.source_distribution_checksum_path }}
183206 ${{ steps.notes.outputs.path }}
184207
185208 - name : Upload PyPI artifact
@@ -196,16 +219,23 @@ jobs:
196219 run : |
197220 release_tag="${{ steps.release.outputs.tag }}"
198221 wheel_path="${{ steps.build.outputs.wheel_path }}"
199- checksum_path="${{ steps.build.outputs.checksum_path }}"
222+ source_distribution_path="${{ steps.build.outputs.source_distribution_path }}"
223+ wheel_checksum_path="${{ steps.build.outputs.wheel_checksum_path }}"
224+ source_distribution_checksum_path="${{ steps.build.outputs.source_distribution_checksum_path }}"
200225 notes_path="${{ steps.notes.outputs.path }}"
226+ release_assets=(
227+ "${wheel_path}"
228+ "${source_distribution_path}"
229+ "${wheel_checksum_path}"
230+ "${source_distribution_checksum_path}"
231+ )
201232
202233 if gh release view "${release_tag}" >/dev/null 2>&1; then
203234 gh release edit "${release_tag}" --title "${release_tag}" --notes-file "${notes_path}"
204- gh release upload "${release_tag}" "${wheel_path}" "${checksum_path }" --clobber
235+ gh release upload "${release_tag}" "${release_assets[@] }" --clobber
205236 else
206237 gh release create "${release_tag}" \
207- "${wheel_path}" \
208- "${checksum_path}" \
238+ "${release_assets[@]}" \
209239 --title "${release_tag}" \
210240 --notes-file "${notes_path}" \
211241 --verify-tag
0 commit comments