8080 echo "::error title=Missing tag::Tag '${release_tag}' was not fetched. Create and push it before running this workflow."
8181 exit 1
8282 fi
83+ tag_revision="$(git rev-list -n 1 "${release_tag}")"
84+ git fetch --no-tags origin main
85+ main_revision="$(git rev-parse origin/main)"
86+ if ! git merge-base --is-ancestor "${tag_revision}" "${main_revision}"; then
87+ echo "::error title=Tag is not on main::Tag '${release_tag}' points at ${tag_revision}, which is not reachable from origin/main."
88+ echo "::error::Merge the release PR first, then tag the main commit."
89+ exit 1
90+ fi
8391
8492 project_version=$(uv run --frozen python - <<'PY'
8593 import tomllib
@@ -109,8 +117,8 @@ jobs:
109117 fi
110118
111119 uv lock --check
112- uv run --frozen ruff check src_auth_perms_sync/
113- uv run --frozen ruff format --check src_auth_perms_sync/
120+ uv run --frozen ruff check src/ src_auth_perms_sync/
121+ uv run --frozen ruff format --check src/ src_auth_perms_sync/
114122 uv run --frozen pyright
115123 uv run --frozen src-auth-perms-sync --help >/tmp/src-auth-perms-sync-help.txt
116124
@@ -129,7 +137,6 @@ jobs:
129137 rm -rf build/release
130138 mkdir -p "${wheelhouse_dir}" "${dist_dir}"
131139
132- uv build --wheel git-subtree/src-py-lib --out-dir "${wheelhouse_dir}" --no-create-gitignore
133140 uv build --wheel --out-dir "${dist_dir}" --no-create-gitignore
134141 project_wheels=("${dist_dir}"/*.whl)
135142 if [[ "${#project_wheels[@]}" -ne 1 ]]; then
@@ -152,7 +159,11 @@ jobs:
152159 --frozen \
153160 --output-file "${requirements_file}"
154161
155- grep -v '^\./git-subtree/src-py-lib$' "${requirements_file}" > "${runtime_requirements_file}"
162+ cp "${requirements_file}" "${runtime_requirements_file}"
163+ if grep -q '^\./' "${runtime_requirements_file}"; then
164+ echo "::error title=Unexpected local dependency::Runtime requirements must resolve from PyPI."
165+ exit 1
166+ fi
156167
157168 python -m pip wheel \
158169 --only-binary=:all: \
@@ -165,8 +176,6 @@ jobs:
165176 echo "::error title=Unexpected src-py-lib wheel count::Expected one src-py-lib wheel, found ${#src_py_lib_wheels[@]}."
166177 exit 1
167178 fi
168- src_py_lib_wheel_path="${src_py_lib_wheels[0]}"
169- src_py_lib_wheel_name="$(basename "${src_py_lib_wheel_path}")"
170179
171180 cat > "${wheelhouse_dir}/INSTALL.txt" <<EOF
172181 # src-auth-perms-sync ${release_tag} offline install
@@ -179,11 +188,13 @@ jobs:
179188 pip install --no-index --find-links ./wheelhouse ${PACKAGE_NAME}
180189 src-auth-perms-sync --help
181190
182- Connected install, for environments that can reach GitHub and PyPI:
191+ Connected install from PyPI:
192+
193+ pip install ${PACKAGE_NAME}
194+
195+ GitHub release asset install, using the same project wheel uploaded to PyPI:
183196
184- pip install \
185- "https://github.com/sourcegraph/src-auth-perms-sync/releases/download/${release_tag}/${src_py_lib_wheel_name}" \
186- "https://github.com/sourcegraph/src-auth-perms-sync/releases/download/${release_tag}/${project_wheel_name}"
197+ pip install "https://github.com/sourcegraph/src-auth-perms-sync/releases/download/${release_tag}/${project_wheel_name}"
187198 EOF
188199
189200 (cd "${wheelhouse_dir}" && shasum -a 256 *.whl > WHEELS.sha256)
@@ -210,8 +221,6 @@ jobs:
210221 echo "checksum_path=${checksum_path}" >> "${GITHUB_OUTPUT}"
211222 echo "project_wheel_path=${project_wheel_path}" >> "${GITHUB_OUTPUT}"
212223 echo "project_wheel_name=${project_wheel_name}" >> "${GITHUB_OUTPUT}"
213- echo "src_py_lib_wheel_path=${src_py_lib_wheel_path}" >> "${GITHUB_OUTPUT}"
214- echo "src_py_lib_wheel_name=${src_py_lib_wheel_name}" >> "${GITHUB_OUTPUT}"
215224
216225 - name : Validate offline install from tarball
217226 run : |
@@ -235,7 +244,6 @@ jobs:
235244 run : |
236245 release_tag="${{ steps.release.outputs.tag }}"
237246 project_wheel_name="${{ steps.build.outputs.project_wheel_name }}"
238- src_py_lib_wheel_name="${{ steps.build.outputs.src_py_lib_wheel_name }}"
239247 notes_path="build/release/release-notes.md"
240248 cat > "${notes_path}" <<EOF
241249 ## Customer install
@@ -267,12 +275,16 @@ jobs:
267275 The tarball includes this project, \`src-py-lib\`, and all runtime wheels.
268276 Verify the download with the matching \`.sha256\` file.
269277
270- ### Connected install
278+ ### Connected PyPI install
271279
272280 \`\`\`sh
273- pip install \
274- "https://github.com/sourcegraph/src-auth-perms-sync/releases/download/${release_tag}/${src_py_lib_wheel_name}" \
275- "https://github.com/sourcegraph/src-auth-perms-sync/releases/download/${release_tag}/${project_wheel_name}"
281+ pip install ${PACKAGE_NAME}
282+ \`\`\`
283+
284+ ### GitHub release asset install
285+
286+ \`\`\`sh
287+ pip install "https://github.com/sourcegraph/src-auth-perms-sync/releases/download/${release_tag}/${project_wheel_name}"
276288 \`\`\`
277289 EOF
278290 echo "path=${notes_path}" >> "${GITHUB_OUTPUT}"
@@ -285,9 +297,15 @@ jobs:
285297 ${{ steps.build.outputs.asset_path }}
286298 ${{ steps.build.outputs.checksum_path }}
287299 ${{ steps.build.outputs.project_wheel_path }}
288- ${{ steps.build.outputs.src_py_lib_wheel_path }}
289300 ${{ steps.notes.outputs.path }}
290301
302+ - name : Upload PyPI artifact
303+ if : matrix.platform == 'linux-x86_64'
304+ uses : actions/upload-artifact@v7
305+ with :
306+ name : pypi-distributions
307+ path : ${{ steps.build.outputs.project_wheel_path }}
308+
291309 - name : Publish GitHub release assets
292310 env :
293311 GH_TOKEN : ${{ github.token }}
@@ -296,19 +314,43 @@ jobs:
296314 asset_path="${{ steps.build.outputs.asset_path }}"
297315 checksum_path="${{ steps.build.outputs.checksum_path }}"
298316 project_wheel_path="${{ steps.build.outputs.project_wheel_path }}"
299- src_py_lib_wheel_path="${{ steps.build.outputs.src_py_lib_wheel_path }}"
300317 notes_path="${{ steps.notes.outputs.path }}"
318+ release_assets=("${asset_path}" "${checksum_path}")
319+
320+ if [[ "${{ matrix.platform }}" == "linux-x86_64" ]]; then
321+ release_assets+=("${project_wheel_path}")
322+ fi
301323
302324 if gh release view "${release_tag}" >/dev/null 2>&1; then
303325 gh release edit "${release_tag}" --title "${release_tag}" --notes-file "${notes_path}"
304- gh release upload "${release_tag}" "${asset_path}" "${checksum_path}" "${project_wheel_path}" "${src_py_lib_wheel_path }" --clobber
326+ gh release upload "${release_tag}" "${release_assets[@] }" --clobber
305327 else
306328 gh release create "${release_tag}" \
307- "${asset_path}" \
308- "${checksum_path}" \
309- "${project_wheel_path}" \
310- "${src_py_lib_wheel_path}" \
329+ "${release_assets[@]}" \
311330 --title "${release_tag}" \
312331 --notes-file "${notes_path}" \
313332 --verify-tag
314333 fi
334+
335+ pypi :
336+ name : Publish PyPI package
337+ needs : wheelhouse
338+ runs-on : ubuntu-24.04
339+ permissions :
340+ contents : read
341+ id-token : write
342+ environment :
343+ name : pypi
344+ url : https://pypi.org/project/src-auth-perms-sync/
345+
346+ steps :
347+ - name : Download built distribution
348+ uses : actions/download-artifact@v7
349+ with :
350+ name : pypi-distributions
351+ path : dist
352+
353+ - name : Publish PyPI package
354+ uses : pypa/gh-action-pypi-publish@release/v1
355+ with :
356+ packages-dir : dist
0 commit comments