|
| 1 | +#!/usr/bin/env bash |
| 2 | + |
| 3 | +# This script should be called to create a new release. |
| 4 | +# |
| 5 | +# When run, this script will display the new version number and optionally a |
| 6 | +# preview of the release notes. The new version will be selected automatically |
| 7 | +# based on if the release contains breaking changes or not. If the release |
| 8 | +# contains breaking changes, a new minor version will be created. Otherwise, a |
| 9 | +# new patch version will be created. |
| 10 | +# |
| 11 | +# Set --ref if you need to specify a specific commit that the new version will |
| 12 | +# be tagged at, otherwise the latest commit will be used. |
| 13 | +# |
| 14 | +# Set --minor to force a minor version bump, even when there are no breaking |
| 15 | +# changes. |
| 16 | +# |
| 17 | +# To mark a release as containing breaking changes, the commit title should |
| 18 | +# either contain a known prefix with an exclamation mark ("feat!:", |
| 19 | +# "feat(api)!:") or the PR that was merged can be tagged with the |
| 20 | +# "release/breaking" label. |
| 21 | +# |
| 22 | +# Usage: ./release.sh [--ref <ref>] [--minor] |
| 23 | + |
| 24 | +set -euo pipefail |
| 25 | +# shellcheck source=scripts/lib.sh |
| 26 | +source "$(dirname "${BASH_SOURCE[0]}")/lib.sh" |
| 27 | +cdroot |
| 28 | + |
| 29 | +ref= |
| 30 | +minor=0 |
| 31 | + |
| 32 | +args="$(getopt -o n -l ref:,minor -- "$@")" |
| 33 | +eval set -- "$args" |
| 34 | +while true; do |
| 35 | + case "$1" in |
| 36 | + --ref) |
| 37 | + ref="$2" |
| 38 | + shift 2 |
| 39 | + ;; |
| 40 | + --minor) |
| 41 | + minor=1 |
| 42 | + shift |
| 43 | + ;; |
| 44 | + --) |
| 45 | + shift |
| 46 | + break |
| 47 | + ;; |
| 48 | + *) |
| 49 | + error "Unrecognized option: $1" |
| 50 | + ;; |
| 51 | + esac |
| 52 | +done |
| 53 | + |
| 54 | +# Check dependencies. |
| 55 | +dependencies gh sort |
| 56 | + |
| 57 | +# Make sure the repository is up-to-date before generating release notes. |
| 58 | +log "Fetching main and tags from origin..." |
| 59 | +git fetch --quiet --tags origin main |
| 60 | + |
| 61 | +# Resolve to the latest ref on origin/main unless otherwise specified. |
| 62 | +ref=$(git rev-parse --short "${ref:-origin/main}") |
| 63 | + |
| 64 | +# Make sure that we're running the latest release script. |
| 65 | +if [[ -n $(git diff --name-status origin/main -- ./scripts/release.sh) ]]; then |
| 66 | + error "Release script is out-of-date. Please check out the latest version and try again." |
| 67 | +fi |
| 68 | + |
| 69 | +# Check the current version tag from GitHub (by number) using the API to |
| 70 | +# ensure no local tags are considered. |
| 71 | +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) |
| 72 | +old_version=${versions[0]} |
| 73 | + |
| 74 | +log "Checking commit metadata for changes since $old_version..." |
| 75 | +# shellcheck source=scripts/check_commit_metadata.sh |
| 76 | +source "$SCRIPT_DIR/check_commit_metadata.sh" "$old_version..$ref" |
| 77 | + |
| 78 | +mapfile -d . -t version_parts <<<"$old_version" |
| 79 | +if [[ $minor == 1 ]] || [[ $COMMIT_METADATA_BREAKING == 1 ]]; then |
| 80 | + if [[ $COMMIT_METADATA_BREAKING == 1 ]]; then |
| 81 | + log "Breaking change detected, incrementing minor version..." |
| 82 | + else |
| 83 | + log "Forcing minor version bump..." |
| 84 | + fi |
| 85 | + version_parts[1]=$((version_parts[1] + 1)) |
| 86 | + version_parts[2]=0 |
| 87 | +else |
| 88 | + log "No breaking changes detected, incrementing patch version..." |
| 89 | + version_parts[2]=$((version_parts[2] + 1)) |
| 90 | +fi |
| 91 | +new_version="${version_parts[0]}.${version_parts[1]}.${version_parts[2]}" |
| 92 | + |
| 93 | +log "Old version: ${old_version}" |
| 94 | +log "New version: ${new_version}" |
| 95 | + |
| 96 | +release_notes="$(execrelative ./generate_release_notes.sh --old-version "$old_version" --new-version "$new_version" --ref "$ref")" |
| 97 | + |
| 98 | +echo |
| 99 | +read -p "Preview release notes? (y/n) " -n 1 -r show_reply |
| 100 | +echo |
| 101 | +if [[ $show_reply =~ ^[Yy]$ ]]; then |
| 102 | + echo -e "$release_notes\n" |
| 103 | +fi |
| 104 | + |
| 105 | +read -p "Create release? (y/n) " -n 1 -r create |
| 106 | +echo |
| 107 | +if [[ $create =~ ^[Yy]$ ]]; then |
| 108 | + log "Tagging commit $ref as $new_version..." |
| 109 | + echo git tag -a "$new_version" -m "$new_version" "$ref" |
| 110 | + log "Pushing tag to origin..." |
| 111 | + echo git push -u origin "$new_version" |
| 112 | +fi |
0 commit comments