From 918fa5a9b5b5f30e4bb096a83d95ff77f4b0fb3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?oliver=20k=C3=B6nig?= Date: Thu, 7 May 2026 08:48:26 +0000 Subject: [PATCH 01/13] ci: consolidate PR + release workflows; use validate-only MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adopts the FW-CI-templates v1.0.0 pattern (NVIDIA-NeMo/FW-CI-templates#466): - single release.yaml caller for both push (validate-only) and workflow_dispatch (real release / dry-run) - no PyPI wheel publish (skip-wheel-build: true) — same pattern as RL - App-only auth (drops PAT/SSH_KEY/SSH_PWD) - pre-flight gate skips heavy work on deploy-release/* + docs_only - Slack webhook resolves at env scope (public for inert; main for real) Co-Authored-By: Claude Opus 4.7 (1M context) Signed-off-by: oliver könig --- .github/workflows/release.yaml | 94 ++++++++++++++++++++++++++++++---- 1 file changed, 84 insertions(+), 10 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index fcddf5f8..44939ad8 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -1,4 +1,4 @@ -# Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2025-2026, NVIDIA CORPORATION. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -11,9 +11,15 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -name: "Release Emerging-Optimizers" +name: "Build, validate, and release Emerging-Optimizers" on: + push: + branches: + - main + - "r**" + - "pull-request/**" + - "deploy-release/*" workflow_dispatch: inputs: release-ref: @@ -21,7 +27,7 @@ on: required: true type: string dry-run: - description: Do not publish a wheel and GitHub release. + description: Compute the release but do not publish wheel, GH release, or docs. required: true default: true type: boolean @@ -30,25 +36,93 @@ on: required: true default: true type: boolean + generate-changelog: + description: Generate changelog + required: false + default: true + type: boolean version-bump-branch: description: Branch for version bump required: true type: string + gh-release-from-tag: + description: Tag of previous release for changelog builder + required: false + type: string + default: "" + +defaults: + run: + shell: bash -x -e -u -o pipefail {0} + +permissions: + id-token: write + contents: write + pull-requests: write + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}-${{ github.event_name }} + cancel-in-progress: ${{ github.event_name == 'push' }} jobs: + pre-flight: + if: github.event_name != 'workflow_dispatch' + uses: NVIDIA-NeMo/FW-CI-templates/.github/workflows/_cicd_preflight.yml@v0.94.1 + release: - uses: NVIDIA-NeMo/FW-CI-templates/.github/workflows/_release_library.yml@v0.57.0 + needs: [pre-flight] + if: | + !cancelled() + && (needs.pre-flight.result == 'success' || needs.pre-flight.result == 'skipped') + && ( + github.event_name == 'workflow_dispatch' + || !(needs.pre-flight.outputs.docs_only == 'true' + || needs.pre-flight.outputs.is_deployment_workflow == 'true') + ) + uses: NVIDIA-NeMo/FW-CI-templates/.github/workflows/_release_library.yml@43d259e5b5f0a6cb4c14eefa04738a5bdf316fe1 with: - release-ref: ${{ inputs.release-ref }} + release-ref: ${{ inputs.release-ref || github.sha }} python-package: emerging_optimizers library-name: Emerging-Optimizers - dry-run: ${{ inputs.dry-run }} - version-bump-branch: ${{ inputs.version-bump-branch }} - create-gh-release: ${{ inputs.create-gh-release }} + validate-only: ${{ github.event_name != 'workflow_dispatch' }} + dry-run: ${{ inputs.dry-run || false }} + version-bump-branch: ${{ inputs.version-bump-branch || github.ref_name }} + create-gh-release: ${{ inputs.create-gh-release || true }} packaging: uv + skip-wheel-build: true + app-id: ${{ vars.BOT_ID }} + gh-release-use-changelog-builder: ${{ inputs.generate-changelog || false }} + publish-docs: false + gh-release-from-tag: ${{ inputs.gh-release-from-tag || '' }} + restrict-to-admins: true secrets: TWINE_USERNAME: ${{ secrets.TWINE_USERNAME }} TWINE_PASSWORD: ${{ secrets.TWINE_PASSWORD }} SLACK_WEBHOOK_ADMIN: ${{ secrets.SLACK_WEBHOOK_ADMIN }} - SLACK_WEBHOOK: ${{ secrets.SLACK_RELEASE_ENDPOINT }} - PAT: ${{ secrets.PAT }} + BOT_KEY: ${{ secrets.BOT_KEY }} + + release-summary: + needs: [pre-flight, release] + if: | + ( + needs.pre-flight.outputs.docs_only == 'true' + || needs.pre-flight.outputs.is_deployment_workflow == 'true' + || always() + ) + && !cancelled() + runs-on: ubuntu-latest + steps: + - name: Result + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + FAILED_JOBS=$(gh run view $GITHUB_RUN_ID --repo ${{ github.repository }} --json jobs --jq '[.jobs[] | select(.conclusion == "failure" or .conclusion == "timed_out" or .conclusion == "action_required")] | length') + + if [ "${FAILED_JOBS:-0}" -eq 0 ]; then + echo "✅ All previous jobs completed successfully" + exit 0 + else + echo "❌ Found $FAILED_JOBS failed job(s)" + gh run view $GITHUB_RUN_ID --repo ${{ github.repository }} --json jobs --jq '.jobs[] | select(.conclusion == "failure" or .conclusion == "timed_out" or .conclusion == "action_required") | .name' + exit 1 + fi From eb723b5a5615a0d8790d256863ea4d2560693e03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?oliver=20k=C3=B6nig?= Date: Thu, 7 May 2026 09:24:31 +0000 Subject: [PATCH 02/13] ci: bump FW-CI pin to d2f3dd3 + use secrets inherit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Lets env-scoped SLACK_WEBHOOK reach the notify job in the called workflow. Signed-off-by: oliver könig --- .github/workflows/release.yaml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 44939ad8..24f48f0e 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -79,7 +79,7 @@ jobs: || !(needs.pre-flight.outputs.docs_only == 'true' || needs.pre-flight.outputs.is_deployment_workflow == 'true') ) - uses: NVIDIA-NeMo/FW-CI-templates/.github/workflows/_release_library.yml@43d259e5b5f0a6cb4c14eefa04738a5bdf316fe1 + uses: NVIDIA-NeMo/FW-CI-templates/.github/workflows/_release_library.yml@d2f3dd32aad11b7034f3f1821174556507d61670 with: release-ref: ${{ inputs.release-ref || github.sha }} python-package: emerging_optimizers @@ -95,11 +95,7 @@ jobs: publish-docs: false gh-release-from-tag: ${{ inputs.gh-release-from-tag || '' }} restrict-to-admins: true - secrets: - TWINE_USERNAME: ${{ secrets.TWINE_USERNAME }} - TWINE_PASSWORD: ${{ secrets.TWINE_PASSWORD }} - SLACK_WEBHOOK_ADMIN: ${{ secrets.SLACK_WEBHOOK_ADMIN }} - BOT_KEY: ${{ secrets.BOT_KEY }} + secrets: inherit release-summary: needs: [pre-flight, release] From 6a8f8e706cd8fde31484bce39123ae027bcfb238 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?oliver=20k=C3=B6nig?= Date: Thu, 7 May 2026 10:57:22 +0000 Subject: [PATCH 03/13] ci: enable docs publish for EO MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: oliver könig --- .github/workflows/release.yaml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 24f48f0e..2b5ca6b9 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -50,6 +50,11 @@ on: required: false type: string default: "" + publish-docs: + description: Publish docs + required: false + default: true + type: boolean defaults: run: @@ -92,7 +97,8 @@ jobs: skip-wheel-build: true app-id: ${{ vars.BOT_ID }} gh-release-use-changelog-builder: ${{ inputs.generate-changelog || false }} - publish-docs: false + publish-docs: ${{ inputs.publish-docs || false }} + docs-target-path: nemo/emerging-optimizers gh-release-from-tag: ${{ inputs.gh-release-from-tag || '' }} restrict-to-admins: true secrets: inherit From 0384a1f1aa8fcb68abd7f4aa38a357dc10fa8584 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?oliver=20k=C3=B6nig?= Date: Thu, 7 May 2026 11:05:03 +0000 Subject: [PATCH 04/13] ci: docs-fail-on-warning false for EO (43 known warnings) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: oliver könig --- .github/workflows/release.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 2b5ca6b9..8067b26f 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -99,6 +99,7 @@ jobs: gh-release-use-changelog-builder: ${{ inputs.generate-changelog || false }} publish-docs: ${{ inputs.publish-docs || false }} docs-target-path: nemo/emerging-optimizers + docs-fail-on-warning: false gh-release-from-tag: ${{ inputs.gh-release-from-tag || '' }} restrict-to-admins: true secrets: inherit From 888df7b134ee665023373f6d1ffa3a78b4b567f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?oliver=20k=C3=B6nig?= Date: Thu, 7 May 2026 11:14:21 +0000 Subject: [PATCH 05/13] ci: build docs on PR push (validate-only) for EO MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: oliver könig --- .github/workflows/release.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 8067b26f..33c8a7bb 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -97,7 +97,7 @@ jobs: skip-wheel-build: true app-id: ${{ vars.BOT_ID }} gh-release-use-changelog-builder: ${{ inputs.generate-changelog || false }} - publish-docs: ${{ inputs.publish-docs || false }} + publish-docs: true docs-target-path: nemo/emerging-optimizers docs-fail-on-warning: false gh-release-from-tag: ${{ inputs.gh-release-from-tag || '' }} From 66de54d0ece365d96131e3c679bca48f40983f47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?oliver=20k=C3=B6nig?= Date: Thu, 7 May 2026 11:27:26 +0000 Subject: [PATCH 06/13] ci: bump FW-CI pin to 64293f6 (slack render fix) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: oliver könig --- .github/workflows/release.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 33c8a7bb..a8d783db 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -84,7 +84,7 @@ jobs: || !(needs.pre-flight.outputs.docs_only == 'true' || needs.pre-flight.outputs.is_deployment_workflow == 'true') ) - uses: NVIDIA-NeMo/FW-CI-templates/.github/workflows/_release_library.yml@d2f3dd32aad11b7034f3f1821174556507d61670 + uses: NVIDIA-NeMo/FW-CI-templates/.github/workflows/_release_library.yml@64293f6d11ccd1a14a8d23c403761a543b4c21f9 with: release-ref: ${{ inputs.release-ref || github.sha }} python-package: emerging_optimizers From c3dfa12218a1af0f4abae57d68d6d025bc0f53be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?oliver=20k=C3=B6nig?= Date: Thu, 7 May 2026 20:14:41 +0000 Subject: [PATCH 07/13] ci: pin FW-CI templates to v1.0.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: oliver könig --- .github/workflows/release.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index a8d783db..ba013aba 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -84,7 +84,7 @@ jobs: || !(needs.pre-flight.outputs.docs_only == 'true' || needs.pre-flight.outputs.is_deployment_workflow == 'true') ) - uses: NVIDIA-NeMo/FW-CI-templates/.github/workflows/_release_library.yml@64293f6d11ccd1a14a8d23c403761a543b4c21f9 + uses: NVIDIA-NeMo/FW-CI-templates/.github/workflows/_release_library.yml@v1.0.0 with: release-ref: ${{ inputs.release-ref || github.sha }} python-package: emerging_optimizers From 06eb6d907a9379dbaa107b60e67d39a25d7cc15b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?oliver=20k=C3=B6nig?= Date: Thu, 7 May 2026 20:21:20 +0000 Subject: [PATCH 08/13] ci: pragma allowlist secret on 'secrets: inherit' lines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: oliver könig --- .github/workflows/release.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index ba013aba..37038fd2 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -102,7 +102,7 @@ jobs: docs-fail-on-warning: false gh-release-from-tag: ${{ inputs.gh-release-from-tag || '' }} restrict-to-admins: true - secrets: inherit + secrets: inherit # pragma: allowlist secret release-summary: needs: [pre-flight, release] From 7a13f48a1740a565af591120094cd308f06250fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?oliver=20k=C3=B6nig?= Date: Fri, 8 May 2026 08:19:54 +0000 Subject: [PATCH 09/13] ci: simplify release-summary if-block (always() was dead code) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: oliver könig --- .github/workflows/release.yaml | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 37038fd2..1bd0e1d6 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -106,13 +106,7 @@ jobs: release-summary: needs: [pre-flight, release] - if: | - ( - needs.pre-flight.outputs.docs_only == 'true' - || needs.pre-flight.outputs.is_deployment_workflow == 'true' - || always() - ) - && !cancelled() + if: ${{ !cancelled() }} runs-on: ubuntu-latest steps: - name: Result From cdd26946663cabddc0015d1e484ca394d52c26cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?oliver=20k=C3=B6nig?= Date: Fri, 8 May 2026 08:24:33 +0000 Subject: [PATCH 10/13] ci: simplify release if-block (replace explicit success/skipped with !failure) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: oliver könig --- .github/workflows/release.yaml | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 1bd0e1d6..c3a1ea6f 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -77,13 +77,9 @@ jobs: release: needs: [pre-flight] if: | - !cancelled() - && (needs.pre-flight.result == 'success' || needs.pre-flight.result == 'skipped') - && ( - github.event_name == 'workflow_dispatch' - || !(needs.pre-flight.outputs.docs_only == 'true' - || needs.pre-flight.outputs.is_deployment_workflow == 'true') - ) + !cancelled() && !failure() + && !(needs.pre-flight.outputs.docs_only == 'true' + || needs.pre-flight.outputs.is_deployment_workflow == 'true') uses: NVIDIA-NeMo/FW-CI-templates/.github/workflows/_release_library.yml@v1.0.0 with: release-ref: ${{ inputs.release-ref || github.sha }} From 0a90778a22fb1e976586ab078d7e2fa0fbbaec89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?oliver=20k=C3=B6nig?= Date: Fri, 8 May 2026 08:26:25 +0000 Subject: [PATCH 11/13] ci: drop docs-fail-on-warning: false (treat warnings as errors) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: oliver könig --- .github/workflows/release.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index c3a1ea6f..e6b89971 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -95,7 +95,6 @@ jobs: gh-release-use-changelog-builder: ${{ inputs.generate-changelog || false }} publish-docs: true docs-target-path: nemo/emerging-optimizers - docs-fail-on-warning: false gh-release-from-tag: ${{ inputs.gh-release-from-tag || '' }} restrict-to-admins: true secrets: inherit # pragma: allowlist secret From 7c1e8d4983f6a03847f805566ab73178f230d3c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?oliver=20k=C3=B6nig?= Date: Fri, 8 May 2026 12:48:48 +0000 Subject: [PATCH 12/13] ci: test FW-CI@2ba61fb + docs-sync-all (verify before tagging) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: oliver könig --- .github/workflows/release.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index e6b89971..e3e6c142 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -80,7 +80,7 @@ jobs: !cancelled() && !failure() && !(needs.pre-flight.outputs.docs_only == 'true' || needs.pre-flight.outputs.is_deployment_workflow == 'true') - uses: NVIDIA-NeMo/FW-CI-templates/.github/workflows/_release_library.yml@v1.0.0 + uses: NVIDIA-NeMo/FW-CI-templates/.github/workflows/_release_library.yml@2ba61fb4dc42ce6e8eabac7a6064d73bc962c9ec with: release-ref: ${{ inputs.release-ref || github.sha }} python-package: emerging_optimizers @@ -95,6 +95,7 @@ jobs: gh-release-use-changelog-builder: ${{ inputs.generate-changelog || false }} publish-docs: true docs-target-path: nemo/emerging-optimizers + docs-sync-all: true gh-release-from-tag: ${{ inputs.gh-release-from-tag || '' }} restrict-to-admins: true secrets: inherit # pragma: allowlist secret From fc0e75b0104cf7903aaf3dfd66b092769bc677e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?oliver=20k=C3=B6nig?= Date: Fri, 8 May 2026 12:55:38 +0000 Subject: [PATCH 13/13] ci: pin FW-CI templates to v1.1.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: oliver könig --- .github/workflows/release.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index e3e6c142..4fbc1687 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -80,7 +80,7 @@ jobs: !cancelled() && !failure() && !(needs.pre-flight.outputs.docs_only == 'true' || needs.pre-flight.outputs.is_deployment_workflow == 'true') - uses: NVIDIA-NeMo/FW-CI-templates/.github/workflows/_release_library.yml@2ba61fb4dc42ce6e8eabac7a6064d73bc962c9ec + uses: NVIDIA-NeMo/FW-CI-templates/.github/workflows/_release_library.yml@v1.1.0 with: release-ref: ${{ inputs.release-ref || github.sha }} python-package: emerging_optimizers