From a3e00d5ef9c8b9bde656b823fdf4c4fe931afd61 Mon Sep 17 00:00:00 2001 From: Mathias Fredriksson Date: Fri, 13 Jan 2023 16:49:39 +0000 Subject: [PATCH 1/9] ci: Revert to local tag creation and push for releases --- .github/workflows/release.yaml | 78 +++++++--------------- scripts/release.sh | 84 ++++++------------------ scripts/release/check_commit_metadata.sh | 8 ++- scripts/release/publish.sh | 9 --- scripts/release/tag_version.sh | 32 ++++----- 5 files changed, 64 insertions(+), 147 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index f6ddf887c0240..ec148e0e7ac6e 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -1,7 +1,9 @@ # GitHub release workflow. name: Release -run-name: Release ${{ github.ref_name }}${{ inputs.dry_run && ' (DRYRUN)' || '' }} on: + push: + tags: + - "v*" workflow_dispatch: inputs: increment: @@ -13,20 +15,11 @@ on: - patch - minor - major - draft: - description: Create a draft release (for manually editing release notes before publishing). - type: boolean - required: true - default: false dry_run: description: Perform a dry-run release. type: boolean required: true default: false - ignore_missing_commit_metadata: - description: WARNING! This option disables the requirement that all commits have a PR. Not needed for dry_run. - type: boolean - default: false permissions: # Required to publish a release @@ -55,17 +48,9 @@ jobs: # Necessary for Docker manifest DOCKER_CLI_EXPERIMENTAL: "enabled" steps: - - name: Check release on main (or dry-run) - if: ${{ github.ref_name != 'main' && !inputs.dry_run }} - run: | - echo "Release not allowed on ${{ github.ref_name }}, use dry-run." - exit 1 - - uses: actions/checkout@v3 with: fetch-depth: 0 - # Set token for pushing protected tag (vX.X.X). - token: ${{ secrets.RELEASE_GITHUB_PAT }} # If the event that triggered the build was an annotated tag (which our # tags are supposed to be), actions/checkout has a bug where the tag in @@ -75,55 +60,39 @@ jobs: - name: Fetch git tags run: git fetch --tags --force - # Configure git user name/email for creating annotated version tag. - - name: Setup git config - run: | - git config user.name "Coder CI" - git config user.email "dean+cdrci@coder.com" - - - name: Create release tag and release notes + - name: Create release notes + if: ${{ inputs.dry_run }} + env: + # We always have to set this since there might be commits on + # main that didn't have a PR. + CODER_IGNORE_MISSING_COMMIT_METADATA: "1" run: | set -euo pipefail ref=HEAD old_version="$(git describe --abbrev=0 "$ref^1")" - if [[ "${{ inputs.ignore_missing_commit_metadata }}" == *t* ]]; then - export CODER_IGNORE_MISSING_COMMIT_METADATA=1 - fi - - # Warn if CODER_IGNORE_MISSING_COMMIT_METADATA is set any other way - # than via dry-run. - if [[ ${CODER_IGNORE_MISSING_COMMIT_METADATA:-0} != 0 ]]; then - echo "WARNING: CODER_IGNORE_MISSING_COMMIT_METADATA is enabled and we will ignore missing commit metadata." 1>&2 - fi - - version_args=() - if [[ $CODER_DRY_RUN == *t* ]]; then - # Allow dry-run of branches to pass. - export CODER_IGNORE_MISSING_COMMIT_METADATA=1 - version_args+=(--dry-run) - fi - # Cache commit metadata. . ./scripts/release/check_commit_metadata.sh "$old_version" "$ref" - declare -p version_args - - # Create new release tag (note that this tag is not pushed before - # release.sh is run). - version="$( - ./scripts/release/tag_version.sh \ - "${version_args[@]}" \ - --ref "$ref" \ - --"$CODER_RELEASE_INCREMENT" - )" + if [[ $CODER_DRY_RUN != *t* ]]; then + # This will fail if we're doing a non-dry-run without tag + # being present. + version="$(./scripts/version.sh)" + else + # Create a tag for this dry-run (local only, can't be uploaded). + version="$( + ./scripts/release/tag_version.sh \ + --ref "$ref" \ + --"$CODER_RELEASE_INCREMENT" + )" + fi # Generate notes. release_notes_file="$(mktemp -t release_notes.XXXXXX)" ./scripts/release/generate_release_notes.sh --old-version "$old_version" --new-version "$version" --ref "$ref" >> "$release_notes_file" echo CODER_RELEASE_NOTES_FILE="$release_notes_file" >> $GITHUB_ENV - - name: Echo release notes + - name: Show release notes run: | set -euo pipefail cat "$CODER_RELEASE_NOTES_FILE" @@ -243,9 +212,6 @@ jobs: set -euo pipefail publish_args=() - if [[ $CODER_RELEASE_DRAFT == *t* ]]; then - publish_args+=(--draft) - fi if [[ $CODER_DRY_RUN == *t* ]]; then publish_args+=(--dry-run) fi diff --git a/scripts/release.sh b/scripts/release.sh index dd8c27b2ed49f..17e17af44da9e 100755 --- a/scripts/release.sh +++ b/scripts/release.sh @@ -7,7 +7,7 @@ cdroot usage() { cat <] [--draft] [--dry-run] [--ref ] [--major | --minor | --patch] +Usage: ./release.sh [--dry-run] [--ref ] [--major | --minor | --patch] This script should be called to create a new release. @@ -23,47 +23,24 @@ be tagged at, otherwise the latest commit will be used. Set --minor to force a minor version bump, even when there are no breaking changes. Likewise for --major. By default a patch version will be created. -Set --dry-run to run the release workflow in CI as a dry-run (no release will -be created). +Set --dry-run to see what this script would do without making actual changes. To mark a release as containing breaking changes, the commit title should either contain a known prefix with an exclamation mark ("feat!:", "feat(api)!:") or the PR that was merged can be tagged with the "release/breaking" label. - -To test changes to this script, you can set --branch , which will -run the release workflow in CI as a dry-run and use the latest commit on the -specified branch as the release commit. This will also set --dry-run. EOH } -# Warn if CODER_IGNORE_MISSING_COMMIT_METADATA is set any other way than via -# --branch. -if [[ ${CODER_IGNORE_MISSING_COMMIT_METADATA:-0} != 0 ]]; then - log "WARNING: CODER_IGNORE_MISSING_COMMIT_METADATA is enabled externally, we will ignore missing commit metadata." -fi - branch=main -draft=0 dry_run=0 ref= increment= -args="$(getopt -o h -l branch:,draft,dry-run,help,ref:,major,minor,patch -- "$@")" +args="$(getopt -o h -l dry-run,help,ref:,major,minor,patch -- "$@")" eval set -- "$args" while true; do case "$1" in - --branch) - branch="$2" - log "Using branch $branch, implies DRYRUN and CODER_IGNORE_MISSING_COMMIT_METADATA." - dry_run=1 - export CODER_IGNORE_MISSING_COMMIT_METADATA=1 - shift 2 - ;; - --draft) - draft=1 - shift - ;; --dry-run) dry_run=1 shift @@ -109,70 +86,51 @@ git fetch --quiet --tags origin "$branch" ref=$(git rev-parse --short "${ref:-origin/$branch}") # Make sure that we're running the latest release script. -if [[ -n $(git diff --name-status origin/"$branch" -- ./scripts/release.sh) ]]; then - error "Release script is out-of-date. Please check out the latest version and try again." -fi +# if [[ -n $(git diff --name-status origin/"$branch" -- ./scripts/release.sh) ]]; then +# error "Release script is out-of-date. Please check out the latest version and try again." +# fi # Check the current version tag from GitHub (by number) using the API to # ensure no local tags are considered. +log "Checking GitHub for latest release..." mapfile -t versions < <(gh api -H "Accept: application/vnd.github+json" /repos/coder/coder/git/refs/tags -q '.[].ref | split("/") | .[2]' | grep '^v' | sort -r -V) old_version=${versions[0]} +log "Latest release: $old_version" +log trap 'log "Check commit metadata failed, you can try to set \"export CODER_IGNORE_MISSING_COMMIT_METADATA=1\" and try again, if you know what you are doing."' EXIT # shellcheck source=scripts/release/check_commit_metadata.sh source "$SCRIPT_DIR/release/check_commit_metadata.sh" "$old_version" "$ref" trap - EXIT -new_version="$(execrelative ./release/tag_version.sh --dry-run --ref "$ref" --"$increment")" +log "Executing DRYRUN of release tagging..." +new_version="$(execrelative ./release/tag_version.sh --old-version "$old_version" --ref "$ref" --"$increment" --dry-run)" +log +read -p "Continue? (y/n) " -n 1 -r show_reply + release_notes="$(execrelative ./release/generate_release_notes.sh --old-version "$old_version" --new-version "$new_version" --ref "$ref")" log read -p "Preview release notes? (y/n) " -n 1 -r show_reply log if [[ $show_reply =~ ^[Yy]$ ]]; then + log echo -e "$release_notes\n" fi -create_message="Create release" -if ((draft)); then - create_message="Create draft release" -fi -if ((dry_run)); then - create_message+=" (DRYRUN)" -fi -read -p "$create_message? (y/n) " -n 1 -r create +read -p "Create release? (y/n) " -n 1 -r create log if ! [[ $create =~ ^[Yy]$ ]]; then exit 0 fi -args=() - -# Draft and dry-run are required args. -if ((draft)); then - args+=(-F draft=true) -else - args+=(-F draft=false) -fi -if ((dry_run)); then - args+=(-F dry_run=true) -else - args+=(-F dry_run=false) - - # We only set this on non-dry-run releases because it will show a - # warning in CI. - if [[ ${CODER_IGNORE_MISSING_COMMIT_METADATA:-0} == 1 ]]; then - args+=(-F ignore_missing_commit_metadata=true) - fi -fi - -log -logrun gh workflow run release.yaml \ - --ref "$branch" \ - -F increment="$increment" \ - "${args[@]}" log +# Run without dry-run to actually create the tag, note we don't update the +# new_version variable here to ensure we're pushing what we showed before. +maybedryrun "$dry_run" execrelative ./release/tag_version.sh --old-version "$old_version" --ref "$ref" --"$increment" >/dev/null +maybedryrun "$dry_run" git push --tags -u origin "$new_version" +log read -p "Watch release? (y/n) " -n 1 -r watch log if ! [[ $watch =~ ^[Yy]$ ]]; then diff --git a/scripts/release/check_commit_metadata.sh b/scripts/release/check_commit_metadata.sh index bfdd3b33ba98c..8400567b551d9 100755 --- a/scripts/release/check_commit_metadata.sh +++ b/scripts/release/check_commit_metadata.sh @@ -91,10 +91,12 @@ main() { commit_sha_long=${parts[1]} commit_prefix=${parts[2]} - if [[ $ignore_missing_metadata != 1 ]]; then - # Safety-check, guarantee all commits had their metadata fetched. - if [[ ! -v labels[$commit_sha_long] ]]; then + # Safety-check, guarantee all commits had their metadata fetched. + if [[ ! -v labels[$commit_sha_long] ]]; then + if [[ $ignore_missing_metadata != 1 ]]; then error "Metadata missing for commit $commit_sha_short" + else + log "WARING: Metadata missing for commit $commit_sha_short" fi fi diff --git a/scripts/release/publish.sh b/scripts/release/publish.sh index e76bcdacb32c9..fa05a7fc3492c 100755 --- a/scripts/release/publish.sh +++ b/scripts/release/publish.sh @@ -134,20 +134,11 @@ popd log log -log "Pushing git tag" -maybedryrun "$dry_run" git push --quiet origin "$new_tag" - -args=() -if ((draft)); then - args+=(--draft) -fi - # We pipe `true` into `gh` so that it never tries to be interactive. true | maybedryrun "$dry_run" gh release create \ --title "$new_tag" \ --notes-file "$release_notes_file" \ - "${args[@]}" \ "$new_tag" \ "$temp_dir"/* diff --git a/scripts/release/tag_version.sh b/scripts/release/tag_version.sh index f5e47785a0048..c42c88eb4e68e 100755 --- a/scripts/release/tag_version.sh +++ b/scripts/release/tag_version.sh @@ -7,23 +7,27 @@ cdroot usage() { cat <] <--major | --minor | --patch> +Usage: ./version_tag.sh [--dry-run] [--old-version ] [--ref ] <--major | --minor | --patch> This script should be called to tag a new release. It will take the suggested increment (major, minor, patch) and optionally promote e.g. patch -> minor if there are breaking changes between the previous version and the given --ref (or HEAD). -This script will create a git tag, so it should only be run in CI (or via ---dry-run). +Pass --old-version optionally to ensure that the version is bumped from the +provided version instead of the latest tag (for use in release.sh). + +This script will create a git tag, it should only be called by release.sh or in +CI. EOH } dry_run=0 +old_version= ref=HEAD increment= -args="$(getopt -o h -l dry-run,help,ref:,major,minor,patch -- "$@")" +args="$(getopt -o h -l dry-run,help,old-version:,ref:,major,minor,patch -- "$@")" eval set -- "$args" while true; do case "$1" in @@ -31,6 +35,10 @@ while true; do dry_run=1 shift ;; + --old-version) + old_version="$2" + shift 2 + ;; --ref) ref="$2" shift 2 @@ -63,20 +71,12 @@ if [[ -z $increment ]]; then error "No version increment provided." fi -if [[ $dry_run != 1 ]] && [[ ${CI:-} == "" ]]; then - error "This script must be run in CI or with --dry-run." +if [[ -z $old_version ]]; then + old_version="$(git describe --abbrev=0 "$ref^1" --always)" fi - -old_version="$(git describe --abbrev=0 "$ref^1")" -cur_tag="$(git describe --abbrev=0 "$ref")" +cur_tag="$(git describe --abbrev=0 "$ref" --always)" if [[ $old_version != "$cur_tag" ]]; then - message="Ref \"$ref\" is already tagged with a release ($cur_tag)" - if ! ((dry_run)); then - error "$message." - fi - log "DRYRUN: $message, echoing current tag." - echo "$cur_tag" - exit 0 + error "A newer tag than \"$old_version\" already exists for \"$ref\" ($cur_tag), aborting." fi ref=$(git rev-parse --short "$ref") From 104bed6522794235fc3533082f5b78b90c63c22f Mon Sep 17 00:00:00 2001 From: Mathias Fredriksson Date: Fri, 13 Jan 2023 16:51:56 +0000 Subject: [PATCH 2/9] Whoops --- scripts/release.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/release.sh b/scripts/release.sh index 17e17af44da9e..afc22aa40de0f 100755 --- a/scripts/release.sh +++ b/scripts/release.sh @@ -86,9 +86,9 @@ git fetch --quiet --tags origin "$branch" ref=$(git rev-parse --short "${ref:-origin/$branch}") # Make sure that we're running the latest release script. -# if [[ -n $(git diff --name-status origin/"$branch" -- ./scripts/release.sh) ]]; then -# error "Release script is out-of-date. Please check out the latest version and try again." -# fi +if [[ -n $(git diff --name-status origin/"$branch" -- ./scripts/release.sh) ]]; then + error "Release script is out-of-date. Please check out the latest version and try again." +fi # Check the current version tag from GitHub (by number) using the API to # ensure no local tags are considered. From 8b408d154901411517675737d6581f12dbde1c04 Mon Sep 17 00:00:00 2001 From: Mathias Fredriksson Date: Fri, 13 Jan 2023 17:37:26 +0000 Subject: [PATCH 3/9] Fix continue check and typo --- scripts/release.sh | 7 +++++-- scripts/release/check_commit_metadata.sh | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/scripts/release.sh b/scripts/release.sh index afc22aa40de0f..4b61e7caa74a7 100755 --- a/scripts/release.sh +++ b/scripts/release.sh @@ -106,11 +106,14 @@ trap - EXIT log "Executing DRYRUN of release tagging..." new_version="$(execrelative ./release/tag_version.sh --old-version "$old_version" --ref "$ref" --"$increment" --dry-run)" log -read -p "Continue? (y/n) " -n 1 -r show_reply +read -p "Continue? (y/n) " -n 1 -r continue_release +log +if ! [[ $continue_release =~ ^[Yy]$ ]]; then + exit 0 +fi release_notes="$(execrelative ./release/generate_release_notes.sh --old-version "$old_version" --new-version "$new_version" --ref "$ref")" -log read -p "Preview release notes? (y/n) " -n 1 -r show_reply log if [[ $show_reply =~ ^[Yy]$ ]]; then diff --git a/scripts/release/check_commit_metadata.sh b/scripts/release/check_commit_metadata.sh index 8400567b551d9..e3df4c76f186d 100755 --- a/scripts/release/check_commit_metadata.sh +++ b/scripts/release/check_commit_metadata.sh @@ -96,7 +96,7 @@ main() { if [[ $ignore_missing_metadata != 1 ]]; then error "Metadata missing for commit $commit_sha_short" else - log "WARING: Metadata missing for commit $commit_sha_short" + log "WARNING: Metadata missing for commit $commit_sha_short" fi fi From 79e1e6d18849a9daccf6fbccbdca7bae8b0c0e88 Mon Sep 17 00:00:00 2001 From: Mathias Fredriksson Date: Fri, 13 Jan 2023 17:48:13 +0000 Subject: [PATCH 4/9] Remove draft env --- .github/workflows/release.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index ec148e0e7ac6e..ebcffb6b0d6cf 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -7,7 +7,7 @@ on: workflow_dispatch: inputs: increment: - description: Preferred version increment (release script may promote e.g. patch to minor depending on changes). + description: Version increment. type: choice required: true default: patch @@ -37,7 +37,6 @@ env: # https://github.blog/changelog/2022-06-10-github-actions-inputs-unified-across-manual-and-reusable-workflows/ CODER_RELEASE: ${{ !inputs.dry_run }} CODER_RELEASE_INCREMENT: ${{ inputs.increment }} - CODER_RELEASE_DRAFT: ${{ inputs.draft }} CODER_DRY_RUN: ${{ inputs.dry_run }} jobs: From 67d100c3b95a68671e741ff47f86d78f899d2477 Mon Sep 17 00:00:00 2001 From: Mathias Fredriksson Date: Fri, 13 Jan 2023 17:54:39 +0000 Subject: [PATCH 5/9] Simplify and remove if --- .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 ebcffb6b0d6cf..44f6f192449f4 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -41,7 +41,7 @@ env: jobs: release: - name: Create and publish + name: Build and publish runs-on: ${{ github.repository_owner == 'coder' && 'ubuntu-latest-16-cores' || 'ubuntu-latest' }} env: # Necessary for Docker manifest @@ -60,7 +60,6 @@ jobs: run: git fetch --tags --force - name: Create release notes - if: ${{ inputs.dry_run }} env: # We always have to set this since there might be commits on # main that didn't have a PR. @@ -69,15 +68,12 @@ jobs: set -euo pipefail ref=HEAD old_version="$(git describe --abbrev=0 "$ref^1")" + version="$(./scripts/version.sh)" # Cache commit metadata. . ./scripts/release/check_commit_metadata.sh "$old_version" "$ref" - if [[ $CODER_DRY_RUN != *t* ]]; then - # This will fail if we're doing a non-dry-run without tag - # being present. - version="$(./scripts/version.sh)" - else + if [[ $CODER_DRY_RUN == *t* ]]; then # Create a tag for this dry-run (local only, can't be uploaded). version="$( ./scripts/release/tag_version.sh \ From fcfb50df2886081cf24bf883419b157236fc3ad1 Mon Sep 17 00:00:00 2001 From: Mathias Fredriksson Date: Fri, 13 Jan 2023 18:08:29 +0000 Subject: [PATCH 6/9] Remove increment --- .github/workflows/release.yaml | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 44f6f192449f4..84822c657f5a1 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -6,17 +6,8 @@ on: - "v*" workflow_dispatch: inputs: - increment: - description: Version increment. - type: choice - required: true - default: patch - options: - - patch - - minor - - major dry_run: - description: Perform a dry-run release. + description: Perform a dry-run release (devel). type: boolean required: true default: false @@ -36,7 +27,6 @@ env: # booleans, not strings. # https://github.blog/changelog/2022-06-10-github-actions-inputs-unified-across-manual-and-reusable-workflows/ CODER_RELEASE: ${{ !inputs.dry_run }} - CODER_RELEASE_INCREMENT: ${{ inputs.increment }} CODER_DRY_RUN: ${{ inputs.dry_run }} jobs: @@ -70,18 +60,6 @@ jobs: old_version="$(git describe --abbrev=0 "$ref^1")" version="$(./scripts/version.sh)" - # Cache commit metadata. - . ./scripts/release/check_commit_metadata.sh "$old_version" "$ref" - - if [[ $CODER_DRY_RUN == *t* ]]; then - # Create a tag for this dry-run (local only, can't be uploaded). - version="$( - ./scripts/release/tag_version.sh \ - --ref "$ref" \ - --"$CODER_RELEASE_INCREMENT" - )" - fi - # Generate notes. release_notes_file="$(mktemp -t release_notes.XXXXXX)" ./scripts/release/generate_release_notes.sh --old-version "$old_version" --new-version "$version" --ref "$ref" >> "$release_notes_file" From 0c279e3aa4d1fbfc27490209fbff182f658f915b Mon Sep 17 00:00:00 2001 From: Mathias Fredriksson Date: Fri, 13 Jan 2023 18:15:02 +0000 Subject: [PATCH 7/9] Update dry-run description --- .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 84822c657f5a1..9866da9942cce 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -7,7 +7,7 @@ on: workflow_dispatch: inputs: dry_run: - description: Perform a dry-run release (devel). + description: Perform a dry-run release (devel). Note that ref must be an annotated tag when run without dry-run. type: boolean required: true default: false From ad6eec0db826d51767eb01a22c4b9ba1edd305eb Mon Sep 17 00:00:00 2001 From: Mathias Fredriksson Date: Fri, 13 Jan 2023 18:19:11 +0000 Subject: [PATCH 8/9] Remove one more instance of draft --- scripts/release/publish.sh | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/scripts/release/publish.sh b/scripts/release/publish.sh index fa05a7fc3492c..fd34b5759bedd 100755 --- a/scripts/release/publish.sh +++ b/scripts/release/publish.sh @@ -35,10 +35,9 @@ fi version="" release_notes_file="" -draft=0 dry_run=0 -args="$(getopt -o "" -l version:,release-notes-file:,draft,dry-run -- "$@")" +args="$(getopt -o "" -l version:,release-notes-file:,dry-run -- "$@")" eval set -- "$args" while true; do case "$1" in @@ -50,10 +49,6 @@ while true; do release_notes_file="$2" shift 2 ;; - --draft) - draft=1 - shift - ;; --dry-run) dry_run=1 shift From a52164427bb7678e8d0db80104c0f13a2f79b47b Mon Sep 17 00:00:00 2001 From: Mathias Fredriksson Date: Fri, 13 Jan 2023 18:26:00 +0000 Subject: [PATCH 9/9] Skip watch if dry run --- scripts/release.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scripts/release.sh b/scripts/release.sh index 4b61e7caa74a7..d68c6780987b0 100755 --- a/scripts/release.sh +++ b/scripts/release.sh @@ -133,6 +133,11 @@ log maybedryrun "$dry_run" execrelative ./release/tag_version.sh --old-version "$old_version" --ref "$ref" --"$increment" >/dev/null maybedryrun "$dry_run" git push --tags -u origin "$new_version" +if ((dry_run)); then + # We can't watch the release.yaml workflow if we're in dry-run mode. + exit 0 +fi + log read -p "Watch release? (y/n) " -n 1 -r watch log