diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 6b893e4171..7a2dc31c44 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -127,6 +127,7 @@ env: RELEASE_HELM_ID: nemo-platform RELEASE_HELM_PATH: k8s/helm RELEASE_HELM_REGISTRY: nvcr.io/0921617854601259/nemo-platform + RELEASE_PUBLISH_NIGHTLY_WHEELS: "false" RELEASE_NIGHTLY_WHEEL_INDEX: https://pypi.nvidia.com RELEASE_STABLE_WHEEL_INDEX: https://pypi.org/simple # Nightly GHCR readiness checks authenticate with the repository GITHUB_TOKEN. @@ -548,6 +549,7 @@ jobs: WHEEL_IDS: ${{ needs.plan-release.outputs.wheel_ids }} CONTAINER_IDS: ${{ needs.plan-release.outputs.container_ids }} INCLUDE_HELM: ${{ needs.plan-release.outputs.include_helm }} + PUBLISH_NIGHTLY_WHEELS: ${{ env.RELEASE_PUBLISH_NIGHTLY_WHEELS }} DRY_RUN: ${{ needs.plan-release.outputs.dry_run }} COMMIT_URL: ${{ github.server_url }}/${{ github.repository }}/commit/${{ needs.plan-release.outputs.source_sha }} RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} @@ -568,7 +570,11 @@ jobs: "*Artifacts:*", ]; if (wheels.length > 0) { - lines.push("*:python: Wheels to publish:*"); + const wheelAction = releaseType === "nightly" + && process.env.PUBLISH_NIGHTLY_WHEELS !== "true" + ? "stage" + : "publish"; + lines.push(`*:python: Wheels to ${wheelAction}:*`); wheels.forEach((wheel) => lines.push(`- ${wheel}`)); } if (containers.length > 0) { @@ -659,6 +665,7 @@ jobs: NIGHTLY_TIMESTAMP: ${{ needs.plan-release.outputs.nightly_timestamp }} WHEEL_VERSION: ${{ needs.plan-release.outputs.wheel_version }} WHEEL_IDS: ${{ needs.plan-release.outputs.wheel_ids }} + PUBLISH_NIGHTLY_WHEELS: ${{ env.RELEASE_PUBLISH_NIGHTLY_WHEELS }} with: github-token: ${{ secrets.CI_DISPATCH_TOKEN }} script: | @@ -675,6 +682,7 @@ jobs: nightly_timestamp: process.env.NIGHTLY_TIMESTAMP, wheel_version: process.env.WHEEL_VERSION, wheels: JSON.parse(process.env.WHEEL_IDS), + publish_nightly_wheels: process.env.PUBLISH_NIGHTLY_WHEELS === "true", }, }); @@ -903,7 +911,9 @@ jobs: - name: Wait for selected wheels in PyPI if: >- needs.plan-release.outputs.has_wheels == 'true' && - needs.plan-release.outputs.dry_run != 'true' + needs.plan-release.outputs.dry_run != 'true' && + (needs.plan-release.outputs.release_type != 'nightly' || + env.RELEASE_PUBLISH_NIGHTLY_WHEELS == 'true') shell: bash env: WHEEL_IDS: ${{ needs.plan-release.outputs.wheel_ids }} @@ -1162,6 +1172,7 @@ jobs: CHART_VERSION: ${{ needs.stage-helm.outputs.chart_version }} NIGHTLY_WHEEL_INDEX: ${{ env.RELEASE_NIGHTLY_WHEEL_INDEX }} STABLE_WHEEL_INDEX: ${{ env.RELEASE_STABLE_WHEEL_INDEX }} + PUBLISH_NIGHTLY_WHEELS: ${{ env.RELEASE_PUBLISH_NIGHTLY_WHEELS }} NGC_CATALOG_BASE: ${{ env.RELEASE_NGC_CATALOG_BASE }} POLL_RESULT: ${{ needs.poll-final-release.result }} GITHUB_RELEASE_RESULT: ${{ needs.create-github-release.result }} @@ -1171,6 +1182,15 @@ jobs: with: script: | const releaseType = process.env.RELEASE_TYPE; + const wheelIds = JSON.parse(process.env.WHEEL_IDS); + const wheelCatalog = JSON.parse(process.env.WHEEL_CATALOG); + const containerIds = JSON.parse(process.env.CONTAINER_IDS); + const stagesNightlyWheels = releaseType === "nightly" + && process.env.PUBLISH_NIGHTLY_WHEELS !== "true" + && wheelIds.length > 0; + const hasPublishedArtifacts = (wheelIds.length > 0 && !stagesNightlyWheels) + || containerIds.length > 0 + || process.env.INCLUDE_HELM === "true"; const results = [ process.env.POLL_RESULT, process.env.GITHUB_RELEASE_RESULT, @@ -1184,7 +1204,7 @@ jobs: const title = published ? (releaseType === "stable" ? "*:ship: Release publish complete*" - : "*:crescent_moon: Nightly release publish complete*") + : "*:crescent_moon: Nightly release complete*") : (releaseType === "stable" ? "*:alert: Release publish failed*" : "*:alert: Nightly release publish failed*"); @@ -1195,11 +1215,10 @@ jobs: ]; if (published) { - const wheelIds = JSON.parse(process.env.WHEEL_IDS); - const wheelCatalog = JSON.parse(process.env.WHEEL_CATALOG); - const containerIds = JSON.parse(process.env.CONTAINER_IDS); - lines.push("", "*Artifacts published:*"); - if (wheelIds.length > 0) { + if (hasPublishedArtifacts) { + lines.push("", "*Artifacts published:*"); + } + if (wheelIds.length > 0 && !stagesNightlyWheels) { lines.push("*:python: Wheels published:*"); for (const wheelId of wheelIds) { const wheel = wheelCatalog.find((candidate) => candidate.id === wheelId); @@ -1228,6 +1247,13 @@ jobs: lines.push("*:helm: Helm chart published:*"); lines.push(`- ${chart}: ${process.env.CHART_VERSION}`); } + if (stagesNightlyWheels) { + lines.push("", "*:python: Wheel staging dispatched:*"); + for (const wheelId of wheelIds) { + const wheel = wheelCatalog.find((candidate) => candidate.id === wheelId); + lines.push(`- ${wheel.package}: ${process.env.WHEEL_VERSION}`); + } + } } else { lines.push( "", diff --git a/RELEASING.md b/RELEASING.md index 60e3709cf3..23d1a1e162 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -91,9 +91,10 @@ America/Los_Angeles. `-nightly-` appended, falling back to the `Chart.yaml` version if no such tag exists. A stable chart uses the stable release version unless `helm-version` is set for a stable Helm-only release. -6. Waits for every selected final artifact to become public before continuing. - The polling job times out after four hours and sends a Slack alert after two - hours if it is still waiting. +6. Waits for every selected final artifact that is published publicly to become + 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 @@ -107,7 +108,7 @@ America/Los_Angeles. | Artifact | Nightly | Stable | | --- | --- | --- | -| Wheels | [`pypi.nvidia.com`](https://pypi.nvidia.com) | [PyPI](https://pypi.org) | +| Wheels | Staged only | [PyPI](https://pypi.org) | | Containers | `ghcr.io/nvidia-nemo/nemo-platform/:nightly-...` | `nvcr.io/nvidia/nemo-platform/:` and the public NGC catalog | | Helm chart | OCI chart at `oci://ghcr.io/nvidia-nemo/nemo-platform` | Initially staged at `0921617854601259/nemo-platform`, then promoted to the public [NGC Helm repository](https://helm.ngc.nvidia.com/nvidia/nemo-platform) | @@ -148,7 +149,7 @@ release completes, check the selected artifacts at their destination above. For a full stable release, also verify that the GitHub tag and generated GitHub release point to the requested source SHA. -For a wheel release, a quick client check is: +For a stable wheel release, a quick client check is: ```bash uv tool upgrade nemo-platform