diff --git a/.github/actions/version-update/action.yml b/.github/actions/version-update/action.yml new file mode 100644 index 00000000000..7b084a5726a --- /dev/null +++ b/.github/actions/version-update/action.yml @@ -0,0 +1,132 @@ +name: "Branch Version Update" +description: "Creates a PR to update the version of a specific branch." + +# The target branch when starting this workflow should be: +# "branch/{major}.{minor}.x" if it exists, or "main" + +inputs: + new_version: + description: "Version 'X.Y.Z' for the release branch." + type: string + required: true + default: "0.0.0" + target_branch: + description: "Target branch for the version update" + type: string + required: false + default: "main" + force: + description: "Enable overwriting existing PR branches (this does not force overwrite the target branch or skip creating a PR)" + type: boolean + required: true + default: false + +runs: + using: "composite" + steps: + + - name: Checkout the repository + uses: actions/checkout@v4 + with: + ref: ${{ inputs.target_branch }} + + - name: Prepare environment + id: prepare-env + shell: bash --noprofile --norc -euo pipefail {0} + run: | + log_and_export_vars() { + for var in "$@"; do + printf "%-15s %s\n" "$var:" "${!var}" | tee -a $GITHUB_STEP_SUMMARY + echo "${var}=${!var}" | tee -a $GITHUB_ENV | tee -a $GITHUB_OUTPUT + done + } + + full_version=${{ inputs.new_version }} + major_version=$(echo ${full_version} | cut -d. -f1) + minor_version=$(echo ${full_version} | cut -d. -f2) + patch_version=$(echo ${full_version} | cut -d. -f3) + branch_name=${{ inputs.target_branch }} + enable_force_push="${{ inputs.force }}" + pr_title="[Version] Update ${branch_name} to v${full_version}" + pr_body="Bump ${branch_name} to ${full_version}." + pr_branch="pr/ver/${branch_name}-v${full_version}" + + log_and_export_vars \ + full_version major_version minor_version patch_version \ + branch_name pr_title pr_branch pr_body enable_force_push + + echo "Branch ref: $GITHUB_REF" | tee -a $GITHUB_STEP_SUMMARY + echo "Branch SHA: $GITHUB_SHA" | tee -a $GITHUB_STEP_SUMMARY + echo "Branch commit: $(git show --oneline --no-patch ${GITHUB_SHA})" | tee -a $GITHUB_STEP_SUMMARY + + - name: Verify environment + id: verify-env + shell: bash --noprofile --norc -euo pipefail {0} + run: | + # Target branch must already exist + if ! git ls-remote --exit-code origin ${branch_name}; then + echo " Target branch must already exist" | tee -a $GITHUB_STEP_SUMMARY + exit 1 + fi + + #Ensure that target branch version is compatible. + if [[ "${branch_name}" =~ ^branch/[0-9]+\.[0-9]+\.x$ ]]; then + branch_version=$(echo ${branch_name} | cut -d/ -f1 --complement) + branch_major=$(echo ${branch_version} | cut -d. -f1) + branch_minor=$(echo ${branch_version} | cut -d. -f2) + if [ "${branch_major}" != "${major_version}" ]; then + echo " Target branch major version mismatch" + exit 1 + fi; + if [ "${branch_minor}" != "${minor_version}" ]; then + echo " Target branch minor version mismatch" + exit 1 + fi + fi + + # PR branch must *not* exist + if [ "${enable_force_push}" == "false" ]; then + if git ls-remote --exit-code origin ${pr_branch}; then + echo " PR branch cannot already exist - Delete branch and retry workflow or enable 'force'" | tee -a $GITHUB_STEP_SUMMARY + exit 1 + fi + fi + + if [[ ! $full_version =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "Invalid version number: $full_version" + exit 1 + fi + + - name: Update version numbers in target branch + id: create-pr-branch + shell: bash --noprofile --norc -euo pipefail {0} + run: | + git checkout -b ${pr_branch} + echo "::group::Running update_version.sh" + ./ci/update_version.sh ${major_version} ${minor_version} ${patch_version} + echo "::endgroup::" + + if ! git diff --quiet; then + echo "::group::Diff" + git diff + echo "::endgroup::" + + git add . + + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + git commit -m "${pr_body}" + + # Push the changes to the release branch: + git push --force origin ${pr_branch} + fi + + - name: Create pull request for target branch + id: create-pr + shell: bash --noprofile --norc -euo pipefail {0} + run: | + gh pr create \ + -B "${branch_name}" \ + -b "${pr_body}" \ + -t "${pr_title}" \ + -H "${pr_branch}" diff --git a/.github/workflows/release-create-new.yml b/.github/workflows/release-create-new.yml new file mode 100644 index 00000000000..c79e04ea6d7 --- /dev/null +++ b/.github/workflows/release-create-new.yml @@ -0,0 +1,146 @@ +# SPDX-FileCopyrightText: Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# 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: 1. Begin Release Cycle" + +# The branch or tag selected when starting the workflow should be: +# 1. "branch/{major}.{minor}.x" if it exists, or +# 2. The ref to use when branching the release branch. + +on: + workflow_dispatch: + inputs: + main_version: + description: "Next version of main. (x.y.z)" + type: string + required: true + +defaults: + run: + shell: bash --noprofile --norc -euo pipefail {0} + +jobs: + create-release-branch: + env: + GH_TOKEN: ${{ github.token }} + permissions: + actions: write + contents: write + pull-requests: write + runs-on: ubuntu-latest + steps: + - name: Checkout the repository + uses: actions/checkout@v4 + + - name: Prepare environment + id: prepare-env + run: | + log_and_export_vars() { + for var in "$@"; do + printf "%-15s %s\n" "$var:" "${!var}" | tee -a $GITHUB_STEP_SUMMARY + echo "${var}=${!var}" | tee -a $GITHUB_ENV | tee -a $GITHUB_OUTPUT + done + } + + repo_version=$(jq -r .full cccl-version.json) + main_version=${{ inputs.main_version }} + + if [[ ! $repo_version =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "Invalid version number: $repo_version" + exit 1 + fi + + if [[ ! $main_version =~ ^[0-9]+\.[0-9]+\.[0-9]*$ ]]; then + echo "Invalid main version number: $main_version" + exit 1 + fi + + major_version=$(echo ${repo_version} | cut -d. -f1) + minor_version=$(echo ${repo_version} | cut -d. -f2) + patch_version=$(echo ${repo_version} | cut -d. -f3) + branch_name="branch/${major_version}.${minor_version}.x" + + main_major_version=$(echo ${main_version} | cut -d. -f1) + main_minor_version=$(echo ${main_version} | cut -d. -f2) + main_patch_version=$(echo ${main_version} | cut -d. -f3) + + log_and_export_vars \ + repo_version major_version minor_version patch_version \ + main_version main_major_version main_minor_version main_patch_version \ + branch_name + + echo "Branch ref: $GITHUB_REF" | tee -a $GITHUB_STEP_SUMMARY + echo "Branch SHA: $GITHUB_SHA" | tee -a $GITHUB_STEP_SUMMARY + echo "Branch commit: $(git show --oneline --no-patch ${GITHUB_SHA})" | tee -a $GITHUB_STEP_SUMMARY + + - name: Verify environment + run: | + # If the release branch already exists, it must match the branch point: + if git ls-remote --exit-code origin $branch_name; then + echo "Branch $branch_name already exists" | tee -a $GITHUB_STEP_SUMMARY + echo " GITHUB_REF: $GITHUB_REF" | tee -a $GITHUB_STEP_SUMMARY + echo " branch_name: $branch_name" | tee -a $GITHUB_STEP_SUMMARY + exit 1 + fi + + - name: Create release branch + id: create_branch + run: | + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + + git push origin ${GITHUB_SHA}:"refs/heads/$branch_name" + echo "Created branch $branch_name at:" | tee -a $GITHUB_STEP_SUMMARY + + git show --oneline --no-patch HEAD | tee -a $GITHUB_STEP_SUMMARY + + - name: Update version numbers in main + uses: ./.github/actions/version-update + with: + new_version: ${{ inputs.main_version }} + target_branch: "main" + + - name: Notify Slack + if: ${{ success()}} + uses: slackapi/slack-github-action@v1.26.0 + env: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_NOTIFIER_BOT_TOKEN }} + SUMMARY_URL: https://github.com/${{github.repository}}/actions/runs/${{github.run_id}} + BRANCH_NAME: ${{ steps.prepare-env.outputs.branch_name }} + BRANCH_VERSION: ${{ inputs.branch_version }} + MAIN_VERSION: ${{ inputs.main_version }} + MAIN_PR_URL: ${{ steps.create_pr.outputs.pull-request-url }} + with: + channel-id: ${{ secrets.SLACK_CHANNEL_RELEASE_LOG }} + slack-message: | + A new release cycle has started for `v${{ env.BRANCH_VERSION }}` on `${{ env.BRANCH_NAME }}`. + + If requested, a PR to update `main` to `v${{ env.MAIN_VERSION }}` has been created: ${{ env.MAIN_PR_URL }}. + + Workflow summary: ${{ env.SUMMARY_URL }} + + - name: Notify Slack (failure) + if: ${{ failure() }} + uses: slackapi/slack-github-action@v1.26.0 + env: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_NOTIFIER_BOT_TOKEN }} + SUMMARY_URL: https://github.com/${{github.repository}}/actions/runs/${{github.run_id}} + BRANCH_VERSION: ${{ inputs.branch_version }} + with: + channel-id: ${{ secrets.SLACK_CHANNEL_RELEASE_LOG }} + slack-message: | + An error has occurred while initiating a new release cycle for `v${{ env.BRANCH_VERSION }}`. + + Details: ${{ env.SUMMARY_URL }} diff --git a/.github/workflows/release-finalize.yml b/.github/workflows/release-finalize.yml index 67e2aad6015..a68c3587c4d 100644 --- a/.github/workflows/release-finalize.yml +++ b/.github/workflows/release-finalize.yml @@ -142,8 +142,8 @@ jobs: - name: Tag run: | - git config user.name github-actions - git config user.email github-actions@github.com + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" git tag -a -m "CCCL Release ${release_tag}" ${release_tag} ${rc_tag} git push origin ${release_tag} diff --git a/.github/workflows/update-branch-version.yml b/.github/workflows/update-branch-version.yml index 08f5d7359f5..e2c3b585fbe 100644 --- a/.github/workflows/update-branch-version.yml +++ b/.github/workflows/update-branch-version.yml @@ -16,8 +16,7 @@ name: "Release: 0. Update version in target branch" # The target branch when starting this workflow should be: -# 1. "branch/{major}.{minor}.x" if it exists, or -# 2. "main" +# "branch/{major}.{minor}.x" if it exists, or "main" on: workflow_dispatch: @@ -56,108 +55,9 @@ jobs: with: ref: ${{ inputs.target_branch }} - - name: Verify run from main - id: verify-main - run: | - # This action can only be run from main. - if [[ $GITHUB_REF != refs/heads/main ]]; then - echo " This action may only be run fom main" | tee -a $GITHUB_STEP_SUMMARY - exit 1 - fi - - - name: Prepare environment - id: prepare-env - run: | - log_and_export_vars() { - for var in "$@"; do - printf "%-15s %s\n" "$var:" "${!var}" | tee -a $GITHUB_STEP_SUMMARY - echo "${var}=${!var}" | tee -a $GITHUB_ENV | tee -a $GITHUB_OUTPUT - done - } - - full_version=${{ inputs.new_version }} - major_version=$(echo ${full_version} | cut -d. -f1) - minor_version=$(echo ${full_version} | cut -d. -f2) - patch_version=$(echo ${full_version} | cut -d. -f3) - branch_name=${{ inputs.target_branch }} - enable_force_push="${{ inputs.force }}" - pr_title="[Version] Update ${branch_name} to v${full_version}" - pr_body="Bump ${branch_name} to ${full_version}." - pr_branch="pr/ver/${branch_name}-v${full_version}" - - log_and_export_vars \ - full_version major_version minor_version patch_version \ - branch_name pr_title pr_branch pr_body enable_force_push - - echo "Branch ref: $GITHUB_REF" | tee -a $GITHUB_STEP_SUMMARY - echo "Branch SHA: $GITHUB_SHA" | tee -a $GITHUB_STEP_SUMMARY - echo "Branch commit: $(git show --oneline --no-patch ${GITHUB_SHA})" | tee -a $GITHUB_STEP_SUMMARY - - - name: Verify environment - id: verify-env - run: | - # Target branch must already exist - if ! git ls-remote --exit-code origin ${branch_name}; then - echo " Target branch must already exist" | tee -a $GITHUB_STEP_SUMMARY - exit 1 - fi - - #Ensure that target branch version is compatible. - if [[ "${branch_name}" =~ ^branch/[0-9]+\.[0-9]+\.x$ ]]; then - branch_version=$(echo ${branch_name} | cut -d/ -f1 --complement) - branch_major=$(echo ${branch_version} | cut -d. -f1) - branch_minor=$(echo ${branch_version} | cut -d. -f2) - if [ "${branch_major}" != "${major_version}" ]; then - echo " Target branch major version mismatch" - exit 1 - fi; - if [ "${branch_minor}" != "${minor_version}" ]; then - echo " Target branch minor version mismatch" - exit 1 - fi - fi - - # PR branch must *not* exist - if [ "${enable_force_push}" == "false" ]; then - if git ls-remote --exit-code origin ${pr_branch}; then - echo " PR branch cannot already exist - Delete branch and retry workflow or enable 'force'" | tee -a $GITHUB_STEP_SUMMARY - exit 1 - fi - fi - - if [[ ! $full_version =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then - echo "Invalid version number: $full_version" - exit 1 - fi - - - name: Update version numbers in target branch - id: create-pr-branch - run: | - git checkout -b ${pr_branch} - echo "::group::Running update_version.sh" - ./ci/update_version.sh ${major_version} ${minor_version} ${patch_version} - echo "::endgroup::" - - if ! git diff --quiet; then - echo "::group::Diff" - git diff - echo "::endgroup::" - - git add . - - git config user.name github-actions - git config user.email github-actions@github.com - git commit -m "${pr_body}" - - # Push the changes to the release branch: - git push --force origin ${pr_branch} - fi - - - name: Create pull request for target branch - id: create-pr - run: | - gh pr create \ - -B "${branch_name}" \ - -b "${pr_body}" \ - -t "${pr_title}" \ - -H "${pr_branch}" + - name: Update version + uses: ./.github/actions/version-update + with: + new_version: ${{ inputs.new_version }} + target_branch: ${{ inputs.target_branch }} + force: ${{ inputs.force }}