Skip to content
Closed
Show file tree
Hide file tree
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
12 changes: 11 additions & 1 deletion .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1100,7 +1100,6 @@ jobs:
needs: [plan-release, poll-final-release]
if: >-
needs.plan-release.outputs.release_type == 'stable' &&
needs.plan-release.outputs.release_scope == 'all' &&
needs.plan-release.outputs.dry_run != 'true' &&
needs.poll-final-release.result == 'success'
runs-on: ubuntu-latest
Expand All @@ -1124,6 +1123,17 @@ jobs:
run: |
set -euo pipefail

tag_sha="$(git rev-parse --verify --quiet "refs/tags/${RELEASE_TAG}^{commit}" || true)"
if [[ -n "${tag_sha}" && "${tag_sha}" != "${SOURCE_SHA}" ]]; then
echo "Tag ${RELEASE_TAG} already points to ${tag_sha}, not requested ${SOURCE_SHA}." >&2
exit 1
fi

if gh release view "${RELEASE_TAG}" >/dev/null 2>&1; then
echo "GitHub Release ${RELEASE_TAG} already exists; nothing to do."
exit 0
fi
Comment on lines +1132 to +1135

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Require the tag before skipping an existing release. If gh release view succeeds while RELEASE_TAG is missing, this exits 0 and leaves the release untagged. Skip only when tag_sha == SOURCE_SHA; otherwise recreate the tag or fail.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/release.yaml around lines 1132 - 1135, Update the
release-check logic around RELEASE_TAG and gh release view to require a
non-empty tag before treating an existing release as complete. Compare the
existing tag’s commit SHA (tag_sha) with SOURCE_SHA, skipping only when they
match; otherwise recreate the tag or fail, and preserve failure when the
required tag is missing.


notes_start_tag="$(
{
git tag -l | grep -E '^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$' || true
Expand Down
18 changes: 11 additions & 7 deletions RELEASING.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,10 @@ and select **Run workflow**. The form shows the allowed custom artifact IDs.

| Input | Use |
| --- | --- |
| `release-type` | `nightly` by default. Select `stable` for a full release. |
| `release-type` | `nightly` by default. Select `stable` for a versioned release. Every successful non-dry-run stable release creates or confirms its Git tag and GitHub Release. |
| `source-sha` | Required for stable releases. Optional for nightlies; a normal nightly with no SHA uses the current default-branch head. A dry-run nightly with no SHA uses the workflow commit so a branch can be validated. |
| `version` | Required for stable releases. Enter the `MAJOR.MINOR.PATCH` release version. |
| `release-scope` | `all` by default. Select `wheels`, `containers`, `helm`, or `custom` for a subset. |
| `release-scope` | `all` by default. Select `wheels`, `containers`, `helm`, or `custom` for a subset. Scope controls which artifacts are released, not whether a stable tag and GitHub Release are created. |
| `wheel-ids`, `container-ids` | Comma-separated IDs used only with `release-scope: custom`. Each ID must be in the catalog above; duplicates and empty entries fail validation. |
| `include-helm` | Includes the Helm chart in a custom release. |
| `helm-version` | Optional exact SemVer Helm chart version for stable Helm-only releases. The stable release label still comes from `version`. |
Expand All @@ -67,7 +67,8 @@ Examples:
| --- | --- |
| Scheduled-style nightly | Leave `release-type` as `nightly` and use the default `all` scope. |
| Stable full release | `release-type: stable`, `source-sha: <40-character SHA>`, `version: <MAJOR.MINOR.PATCH>`, `release-scope: all`. |
| One container | `release-scope: custom`, `container-ids: nmp-customizer-tasks`. |
| Stable one-container release or retry | `release-type: stable`, `source-sha: <40-character SHA>`, `version: <MAJOR.MINOR.PATCH>`, `release-scope: custom`, `container-ids: nmp-customizer-tasks`. |
| Stable one-wheel release or retry | `release-type: stable`, `source-sha: <40-character SHA>`, `version: <MAJOR.MINOR.PATCH>`, `release-scope: custom`, `wheel-ids: nemo-platform`. |
| Helm-only validation | `release-scope: helm`, `dry-run: true`. |
| Stable Helm-only chart override | `release-type: stable`, `source-sha: <40-character SHA>`, `version: 0.1.0`, `release-scope: helm`, `helm-version: 0.1.0+helmfix1`. |

Expand Down Expand Up @@ -95,10 +96,13 @@ America/Los_Angeles.
available before continuing. Nightly wheels are staged but not published, so
they are not polled. The polling job times out after four hours and sends
a Slack alert after two hours if it is still waiting.
7. For a non-dry-run stable release with `release-scope: all`, creates the
GitHub release and tag at the selected SHA. GitHub generates the release
notes from the previous numeric SemVer tag. Subset releases do not create a
GitHub release or tag.
7. For every non-dry-run stable release, creates the GitHub release and tag at
the selected SHA after the selected artifacts become available. This is
independent of release scope, so stable subset and custom runs can release or
retry individual artifacts. A rerun reuses a matching tag and release,
creates a missing release for an existing matching tag, and fails if the
version tag points to a different SHA. GitHub generates the release notes
from the previous numeric SemVer tag.
8. After polling succeeds, releases that include the Helm chart dispatch a
deployment signal to the configured internal release repository. The
downstream workflow creates a pending GitHub Deployment, and the deployment
Expand Down
Loading