From b139e1fb4e417d005f1f95f5b1d5938ad227d582 Mon Sep 17 00:00:00 2001 From: Leo Fang Date: Tue, 21 Jan 2025 03:36:47 +0000 Subject: [PATCH 1/8] add release upload workflow --- .github/workflows/release-upload.yml | 59 ++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 .github/workflows/release-upload.yml diff --git a/.github/workflows/release-upload.yml b/.github/workflows/release-upload.yml new file mode 100644 index 0000000000..4e41bdca3d --- /dev/null +++ b/.github/workflows/release-upload.yml @@ -0,0 +1,59 @@ +name: CI: Upload git archive + +on: + workflow_call: + inputs: + git-tag: + type: string + required: true + +concurrency: + # Concurrency group that uses the workflow name and PR number if available + # or commit SHA as a fallback. If a new build is triggered under that + # concurrency group while a previous build is running it will be canceled. + # Repeated pushes to a PR will cancel all previous builds, while multiple + # merges to main will not cancel. + group: ${{ github.workflow }}-${{ github.ref_name || github.sha }} + cancel-in-progress: true + +permissions: + contents: write + +jobs: + # create source archive and upload it to the published release + # URL to the archive: https://github.com/NVIDIA//releases/download//-.tar.gz + upload: + if: ${{ !github.event.repository.fork }} + runs-on: ubuntu-latest + env: + ARCHIVE_NAME: ${{ github.event.repository.name }}-${{ inputs.git-tag }} + steps: + - name: Checkout Source + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + + - name: Create Release Directory + run: mkdir -p release + + - name: Archive Source + run: > + git archive + --format=tar.gz + --prefix="${{ env.ARCHIVE_NAME }}/" + --output="release/${{ env.ARCHIVE_NAME }}.tar.gz" + ${{ inputs.git-tag }} + + - name: Compute Checksum + run: > + sha256sum "release/${{ env.ARCHIVE_NAME }}.tar.gz" + | awk '{print $1}' + > "release/${{ env.ARCHIVE_NAME }}.tar.gz.sha256sum" + + - name: Upload Archive + env: + GH_TOKEN: ${{ github.token }} + run: > + gh release upload + ${{ inputs.git-tag }} + release/* + --clobber "${{ github.ref_name }}" + --repo "${{ github.repository }}" From 3d06a079fc0feb13071533951cc0ae00680b3633 Mon Sep 17 00:00:00 2001 From: Leo Fang Date: Tue, 21 Jan 2025 05:01:39 +0000 Subject: [PATCH 2/8] add a release workflow --- .github/workflows/build-docs.yml | 59 ++++++++++++++--- .github/workflows/release.yml | 105 +++++++++++++++++++++++++++++++ 2 files changed, 154 insertions(+), 10 deletions(-) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml index e2e45868a1..abcc700686 100644 --- a/.github/workflows/build-docs.yml +++ b/.github/workflows/build-docs.yml @@ -6,6 +6,26 @@ on: build-ctk-ver: type: string required: true + component: + description: "Component(s) to build docs for" + required: true + default: "all" + type: choice + options: + - cuda-core + - cuda-bindings + - cuda-python + - all + git-tag: + description: "Target git tag to build docs for" + required: true + default: "" + type: string + is-release: + description: "Are we building release docs?" + required: true + default: false + type: boolean jobs: build: @@ -27,6 +47,7 @@ jobs: uses: actions/checkout@v4 with: fetch-depth: 0 + ref: ${{ inputs.git-tag }} # TODO: cache conda env to speed up the workflow once conda-incubator/setup-miniconda#267 # is resolved @@ -114,23 +135,40 @@ jobs: pip install cuda_python*.whl - # This step sets the PR_NUMBER env var. + # This step sets the PR_NUMBER/BUILD_LATEST/BUILD_PREVIEW env vars. - name: Get PR number + if: ${{ !inputs.is-release }} uses: ./.github/actions/get_pr_number - - name: Build all (latest) docs - id: build + - name: Set up artifact directories + run: | + mkdir -p artifacts/docs + # create an empty folder for removal use + mkdir -p artifacts/empty_docs + + - name: Build all docs + if: ${{ inputs.component == 'all' }} + env: + DOC_ACTION: ${{ (inputs.is-release && '') || 'latest-only' }} run: | pushd cuda_python/docs/ - ./build_all_docs.sh latest-only + ./build_all_docs.sh $DOC_ACTION ls -l build popd - - mkdir -p artifacts/docs mv cuda_python/docs/build/html/* artifacts/docs/ - # create an empty folder for removal use - mkdir -p artifacts/empty_docs + - name: Build component docs + if: ${{ inputs.component != 'all' }} + env: + DOC_ACTION: ${{ (inputs.is-release && '') || 'latest-only' }} + run: | + COMPONENT=$(echo "${{ inputs.component }}" | tr '-' '_') + pushd ${COMPONENT}/docs/ + ./build_docs.sh $DOC_ACTION + ls -l build + rm -rf build/html/latest + popd + mv ${COMPONENT}/docs/build/html/* artifacts/docs/ # TODO: Consider removing this step? - name: Upload doc artifacts @@ -140,6 +178,7 @@ jobs: retention-days: 3 - name: Deploy or clean up doc preview + if: ${{ inputs.is-release }} uses: ./.github/actions/doc_preview with: source-folder: ${{ (github.ref_name != 'main' && 'artifacts/docs') || @@ -147,12 +186,12 @@ jobs: pr-number: ${{ env.PR_NUMBER }} - name: Deploy doc update - if: ${{ github.ref_name == 'main' }} + if: ${{ github.ref_name == 'main' || inputs.is-release }} uses: JamesIves/github-pages-deploy-action@v4 with: git-config-name: cuda-python-bot git-config-email: cuda-python-bot@users.noreply.github.com folder: artifacts/docs/ target-folder: docs/ - commit-message: "Deploy latest docs: ${{ github.sha }}" + commit-message: "Deploy ${{ (inputs.is-release && 'release') || 'latest' }} docs: ${{ github.sha }}" clean: false diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000000..da621eefca --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,105 @@ +name: "CI: Release" + +description: Manually-triggered release workflow. Must have a release note in the draft state and the release commit tagged. + +on: + workflow_dispatch: + inputs: + component: + description: "Component to release" + required: true + type: choice + options: + - cuda-core + - cuda-bindings + - cuda-python + - all + git-tag: + description: "The release git tag" + required: true + type: string + run-id: + description: "The GHA run ID that generated validated artifacts" + required: true + type: string + build-ctk-ver: + type: string + required: true + #print_tags: + # description: 'True to print to STDOUT' + # required: true + # type: boolean + +defaults: + run: + shell: bash --noprofile --norc -xeuo pipefail {0} + +jobs: + check-tag: + runs-on: ubuntu-latest + steps: + - name: Checkout ${{ github.event.repository.name }} + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Check if draft exists for the tag + env: + GH_TOKEN: ${{ github.token }} + run: | + tags= + for i in $(gh release list -R ${{ github.repository }} --json tagName --jq '.[]| .tagName'); do + tags+=( $i ) + done + is_draft= + for i in $(gh release list -R ${{ github.repository }} --json isDraft --jq '.[]| .isDraft'); do + is_draft+=( $i ) + done + + found=0 + for idx in ${!tags[@]}; do + if [[ "${tags[$idx]}" == "${{ inputs.git-tag }}" ]]; then + echo "found ${{ inputs.git-tag }}" + found=1 + if [[ "${is_draft[$idx]}" != "true" ]]; then + echo "the release note is not in draft state" + exit 1 + fi + break + fi + done + if [[ "$found" == 0 ]]; then + echo "the release is not yet tagged" + exit 1 + fi + + doc: + name: Build release docs + if: ${{ github.repository_owner == 'nvidia' }} + # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages + permissions: + id-token: write + contents: write + pull-requests: write + needs: + - check-tag + secrets: inherit + uses: + ./.github/workflows/build-docs.yml + with: + build-ctk-ver: ${{ inputs.build-ctk-ver }} + component: ${{ inputs.component }} + git-tag: ${{ inputs.git-tag }} + is-release: true + + upload-archive: + name: Upload source archive + permissions: + contents: write + needs: + - check-tag + secrets: inherit + uses: + ./.github/workflows/release-upload.yml + with: + git-tag: ${{ inputs.git-tag }} From 991dbd0fc0e7bb61c34ce995501d086d9cf2c9ea Mon Sep 17 00:00:00 2001 From: Leo Fang Date: Tue, 21 Jan 2025 05:03:04 +0000 Subject: [PATCH 3/8] fix typo --- .github/workflows/release-upload.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-upload.yml b/.github/workflows/release-upload.yml index 4e41bdca3d..5fa58de92c 100644 --- a/.github/workflows/release-upload.yml +++ b/.github/workflows/release-upload.yml @@ -1,4 +1,4 @@ -name: CI: Upload git archive +name: "CI: Upload git archive" on: workflow_call: From 262484b61e714a76389b175c6973c448db848366 Mon Sep 17 00:00:00 2001 From: Leo Fang Date: Tue, 21 Jan 2025 05:08:56 +0000 Subject: [PATCH 4/8] fix input arg type --- .github/workflows/build-docs.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml index abcc700686..008fb1bfed 100644 --- a/.github/workflows/build-docs.yml +++ b/.github/workflows/build-docs.yml @@ -10,12 +10,12 @@ on: description: "Component(s) to build docs for" required: true default: "all" - type: choice - options: - - cuda-core - - cuda-bindings - - cuda-python - - all + type: string + # below are the acceptable options: + # - cuda-core + # - cuda-bindings + # - cuda-python + # - all git-tag: description: "Target git tag to build docs for" required: true From 12031a58c51fa01cb594dfaeda8dcce0df205517 Mon Sep 17 00:00:00 2001 From: Leo Fang Date: Tue, 21 Jan 2025 05:14:32 +0000 Subject: [PATCH 5/8] fix latest doc logic --- .github/workflows/build-docs.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml index 008fb1bfed..4a50a40a3f 100644 --- a/.github/workflows/build-docs.yml +++ b/.github/workflows/build-docs.yml @@ -153,6 +153,10 @@ jobs: run: | pushd cuda_python/docs/ ./build_all_docs.sh $DOC_ACTION + if [[ -z "$DOC_ACTION" ]]; then + # At release time, we don't want to update the latest docs + rm -rf build/html/latest + fi ls -l build popd mv cuda_python/docs/build/html/* artifacts/docs/ @@ -165,8 +169,11 @@ jobs: COMPONENT=$(echo "${{ inputs.component }}" | tr '-' '_') pushd ${COMPONENT}/docs/ ./build_docs.sh $DOC_ACTION + if [[ -z "$DOC_ACTION" ]]; then + # At release time, we don't want to update the latest docs + rm -rf build/html/latest + fi ls -l build - rm -rf build/html/latest popd mv ${COMPONENT}/docs/build/html/* artifacts/docs/ From 8d42781d79168aa6ab766a937de9091108e037b9 Mon Sep 17 00:00:00 2001 From: Leo Fang Date: Tue, 21 Jan 2025 05:55:10 +0000 Subject: [PATCH 6/8] add wheel publish job --- .github/workflows/release.yml | 46 +++++++++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 5 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index da621eefca..3b93a1e0b0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -25,6 +25,13 @@ on: build-ctk-ver: type: string required: true + wheel-dst: + description: "Which wheel index to publish to?" + required: true + type: choice + options: + - testpypi + - pypi #print_tags: # description: 'True to print to STDOUT' # required: true @@ -38,11 +45,6 @@ jobs: check-tag: runs-on: ubuntu-latest steps: - - name: Checkout ${{ github.event.repository.name }} - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - name: Check if draft exists for the tag env: GH_TOKEN: ${{ github.token }} @@ -103,3 +105,37 @@ jobs: ./.github/workflows/release-upload.yml with: git-tag: ${{ inputs.git-tag }} + + publish-wheels: + name: Publish wheels + runs-on: ubuntu-latest + needs: + - check-tag + environment: + name: ${{ inputs.wheel-dst }} + url: https://${{ (inputs.wheel-dst == 'testpypi' && 'test.') || '' }}pypi.org/p/${{ inputs.component }}/ + permissions: + id-token: write + steps: + - name: Download component wheels + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + gh run download ${{ inputs.run-id }} -p "${{ inputs.component }}*" -R ${{ github.repository }} + mkdir dist + for p in "${{ inputs.component }}*"; do + mv ${p}/*.whl dist/ + done + rmdir "${{ inputs.component }}*" + + - name: Publish package distributions to PyPI + if: ${{ inputs.wheel-dst == 'pypi' }} + uses: pypa/gh-action-pypi-publish@release/v1 + + - name: Publish package distributions to TestPyPI + if: ${{ inputs.wheel-dst == 'testpypi' }} + uses: pypa/gh-action-pypi-publish@release/v1 + with: + repository-url: https://test.pypi.org/legacy/ + + # TODO: add another job to make the release leave the draft state? From aa23e698128f67d0a4903af8ad4934bb29d889da Mon Sep 17 00:00:00 2001 From: Leo Fang Date: Tue, 21 Jan 2025 06:01:36 +0000 Subject: [PATCH 7/8] match old behavior in build-docs --- .github/workflows/build-docs.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml index 4a50a40a3f..38cc3d6664 100644 --- a/.github/workflows/build-docs.yml +++ b/.github/workflows/build-docs.yml @@ -8,7 +8,7 @@ on: required: true component: description: "Component(s) to build docs for" - required: true + required: false default: "all" type: string # below are the acceptable options: @@ -18,12 +18,12 @@ on: # - all git-tag: description: "Target git tag to build docs for" - required: true + required: false default: "" type: string is-release: description: "Are we building release docs?" - required: true + required: false default: false type: boolean From bd7048ddeacb8e66d753b0e49dc0e9b9e2702201 Mon Sep 17 00:00:00 2001 From: Leo Fang Date: Tue, 21 Jan 2025 06:04:56 +0000 Subject: [PATCH 8/8] fix --- .github/workflows/build-docs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml index 38cc3d6664..17c6498c50 100644 --- a/.github/workflows/build-docs.yml +++ b/.github/workflows/build-docs.yml @@ -185,7 +185,7 @@ jobs: retention-days: 3 - name: Deploy or clean up doc preview - if: ${{ inputs.is-release }} + if: ${{ !inputs.is-release }} uses: ./.github/actions/doc_preview with: source-folder: ${{ (github.ref_name != 'main' && 'artifacts/docs') ||