Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -134,3 +134,62 @@ jobs:
assert wave_sdk.__version__ == '$TAG_VERSION', wave_sdk.__version__
print('verified wave-sdk', wave_sdk.__version__, 'installed from PyPI, Wave facade OK')
"

# ---------------------------------------------------------------------------------------
# VER-001. Create the GitHub Release for the tag once the artifact is confirmed live on
# PyPI — this job needs `publish` (which itself only runs `if: startsWith(github.ref,
# 'refs/tags/v')`, i.e. never on a PR dry-run) to have SUCCEEDED, which for `publish`
# includes its own "Post-publish verification" step above, so a Release is never created
# for a wheel that reached `twine upload`/Trusted Publishing but was never actually
# confirmed live. Idempotent: a Release that already exists for this tag gets its
# dist/ artifacts re-uploaded with --clobber instead of failing on "already exists".
# ---------------------------------------------------------------------------------------
release:
name: Create GitHub Release
needs: publish
if: needs.publish.result == 'success'
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: write # create/upload the Release for this tag — nothing else
steps:
- uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
with:
name: dist

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: Publish the exact dist/ artifact used here, or make the release consume the artifact produced by the PyPI publish job. A separate rebuild can produce different metadata or bytes, leaving the GitHub Release out of sync with the package verified on PyPI.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/release.yml, line 158:

<comment>Publish the exact `dist/` artifact used here, or make the release consume the artifact produced by the PyPI publish job. A separate rebuild can produce different metadata or bytes, leaving the GitHub Release out of sync with the package verified on PyPI.</comment>

<file context>
@@ -134,3 +134,62 @@ jobs:
+    steps:
+      - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
+        with:
+          name: dist
+          path: dist
+
</file context>

path: dist
Comment on lines +156 to +159

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: The release downloads artifacts from the earlier build, while PyPI receives a separate rebuild, so non-reproducible metadata can make release assets differ from published artifacts. [api mismatch]

Assessment: 🟠 Major · 🔁 Occurrence: Sometimes

Use CodeAnt Skill Fix in Cursor Fix in VSCode Claude

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** .github/workflows/release.yml
**Line:** 156:159
**Comment:**
	*Api Mismatch: The release downloads artifacts from the earlier build, while PyPI receives a separate rebuild, so non-reproducible metadata can make release assets differ from published artifacts.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎


# TAG_NAME comes from the environment (never interpolated into the script body),
# matching the "Verify tag matches package version" step above.
- name: Create or update the GitHub Release (idempotent)
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG_NAME: ${{ github.ref_name }}
GH_REPO: ${{ github.repository }}
run: |
set -euo pipefail
shopt -s nullglob
ASSETS_TO_UPLOAD=(dist/*)
if [ "${#ASSETS_TO_UPLOAD[@]}" -eq 0 ]; then
echo "::error::no files under dist/ to attach to the release"
exit 1
fi
if gh release view "$TAG_NAME" >/dev/null 2>&1; then

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: Any gh release view failure is treated as absence, so authentication, repository, or transient API errors trigger misleading creation attempts and hide the original failure. [logic error]

Assessment: 🟠 Major · 🔁 Occurrence: Rarely

Use CodeAnt Skill Fix in Cursor Fix in VSCode Claude

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** .github/workflows/release.yml
**Line:** 176:176
**Comment:**
	*Logic Error: Any `gh release view` failure is treated as absence, so authentication, repository, or transient API errors trigger misleading creation attempts and hide the original failure.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

echo "release $TAG_NAME already exists — uploading dist/ (idempotent path, --clobber)"
gh release upload "$TAG_NAME" "${ASSETS_TO_UPLOAD[@]}" --clobber
else
echo "release $TAG_NAME does not exist — creating with generated notes"
gh release create "$TAG_NAME" "${ASSETS_TO_UPLOAD[@]}" --title "$TAG_NAME" --generate-notes

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: If the tag is deleted before this command runs, gh release create creates it from the default branch and attaches artifacts built from the original tag. Add --verify-tag so the job fails instead of publishing a release for a different commit.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/release.yml, line 181:

<comment>If the tag is deleted before this command runs, `gh release create` creates it from the default branch and attaches artifacts built from the original tag. Add `--verify-tag` so the job fails instead of publishing a release for a different commit.</comment>

<file context>
@@ -134,3 +134,62 @@ jobs:
+            gh release upload "$TAG_NAME" "${ASSETS_TO_UPLOAD[@]}" --clobber
+          else
+            echo "release $TAG_NAME does not exist — creating with generated notes"
+            gh release create "$TAG_NAME" "${ASSETS_TO_UPLOAD[@]}" --title "$TAG_NAME" --generate-notes
+          fi
+          echo "verifying the release exists and carries every dist/ asset"
</file context>
Suggested change
gh release create "$TAG_NAME" "${ASSETS_TO_UPLOAD[@]}" --title "$TAG_NAME" --generate-notes
gh release create "$TAG_NAME" "${ASSETS_TO_UPLOAD[@]}" --title "$TAG_NAME" --generate-notes --verify-tag

fi
Comment on lines +176 to +182

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: Distinguish a not-found response from other gh release view failures before entering the create branch. Otherwise authentication, repository, or transient API errors are masked and can produce a misleading create attempt.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/release.yml, line 176:

<comment>Distinguish a not-found response from other `gh release view` failures before entering the create branch. Otherwise authentication, repository, or transient API errors are masked and can produce a misleading create attempt.</comment>

<file context>
@@ -134,3 +134,62 @@ jobs:
+            echo "::error::no files under dist/ to attach to the release"
+            exit 1
+          fi
+          if gh release view "$TAG_NAME" >/dev/null 2>&1; then
+            echo "release $TAG_NAME already exists — uploading dist/ (idempotent path, --clobber)"
+            gh release upload "$TAG_NAME" "${ASSETS_TO_UPLOAD[@]}" --clobber
</file context>
Suggested change
if gh release view "$TAG_NAME" >/dev/null 2>&1; then
echo "release $TAG_NAME already exists — uploading dist/ (idempotent path, --clobber)"
gh release upload "$TAG_NAME" "${ASSETS_TO_UPLOAD[@]}" --clobber
else
echo "release $TAG_NAME does not exist — creating with generated notes"
gh release create "$TAG_NAME" "${ASSETS_TO_UPLOAD[@]}" --title "$TAG_NAME" --generate-notes
fi
release_view_error="$(mktemp)"
if gh release view "$TAG_NAME" >/dev/null 2>"$release_view_error"; then
rm -f "$release_view_error"
echo "release $TAG_NAME already exists — uploading dist/ (idempotent path, --clobber)"
gh release upload "$TAG_NAME" "${ASSETS_TO_UPLOAD[@]}" --clobber
else
release_view_status=$?
if ! grep -Eqi 'not found|404' "$release_view_error"; then
cat "$release_view_error" >&2
rm -f "$release_view_error"
exit "$release_view_status"
fi
rm -f "$release_view_error"
echo "release $TAG_NAME does not exist — creating with generated notes"
gh release create "$TAG_NAME" "${ASSETS_TO_UPLOAD[@]}" --title "$TAG_NAME" --generate-notes
fi

echo "verifying the release exists and carries every dist/ asset"
ASSETS="$(gh release view "$TAG_NAME" --json assets --jq '[.assets[].name] | join(" ")')"
echo "release assets: $ASSETS"
for f in "${ASSETS_TO_UPLOAD[@]}"; do
case "$ASSETS" in
*"$(basename "$f")"*) ;;
*)
echo "::error::$(basename "$f") missing from release $TAG_NAME after upload"
exit 1
;;
esac
done
echo "VER-001: GitHub Release for $TAG_NAME exists and carries the built dist/ artifacts."
Loading