|
| 1 | +#!/usr/bin/env bash |
| 2 | +# |
| 3 | +# This Source Code Form is subject to the terms of the Mozilla Public |
| 4 | +# License, v. 2.0. If a copy of the MPL was not distributed with this |
| 5 | +# file, You can obtain one at http://mozilla.org/MPL/2.0/. |
| 6 | + |
| 7 | +# Prepare a new release by updating the version numbers in all related files, |
| 8 | +# updating the changelog to include the released version. |
| 9 | +# |
| 10 | +# Optionally, it can create the release commit and tag it. |
| 11 | +# |
| 12 | +# Usage: prepare-release.sh <new version> |
| 13 | +# |
| 14 | +# Environment: |
| 15 | +# |
| 16 | +# DRY_RUN - Do not modify files or run destructive commands when set. |
| 17 | +# VERB - Log commands that are run when set. |
| 18 | + |
| 19 | +set -eo pipefail |
| 20 | + |
| 21 | +run() { |
| 22 | + [ "${VERB:-0}" != 0 ] && echo "+ $*" |
| 23 | + if [ "$DOIT" = y ]; then |
| 24 | + "$@" |
| 25 | + else |
| 26 | + true |
| 27 | + fi |
| 28 | +} |
| 29 | + |
| 30 | +# All sed commands below work with either |
| 31 | +# GNU sed (standard on Linux distrubtions) or BSD sed (standard on macOS) |
| 32 | +SED="sed" |
| 33 | + |
| 34 | +WORKSPACE_ROOT="$( cd "$(dirname "$0")/.." ; pwd -P )" |
| 35 | + |
| 36 | +if [ -z "$1" ]; then |
| 37 | + echo "Usage: $(basename "$0") <new version>" |
| 38 | + echo |
| 39 | + echo "Prepare for a new release by setting the version number" |
| 40 | + exit 1 |
| 41 | +fi |
| 42 | + |
| 43 | +NEW_VERSION="$1" |
| 44 | +DATE=$(date +%Y-%m-%d) |
| 45 | + |
| 46 | +if ! echo "$NEW_VERSION" | grep --quiet --extended-regexp '^[0-9]+\.[0-9]+\.[0-9]+(-[a-z0-9.-]+)?$'; then |
| 47 | + echo "error: Specified version '${NEW_VERSION}' doesn't match the Semantic Versioning pattern." |
| 48 | + echo "error: Use MAJOR.MINOR.PATCH versioning." |
| 49 | + echo "error: See https://semver.org/" |
| 50 | + exit 1 |
| 51 | +fi |
| 52 | + |
| 53 | +echo "Preparing update to v${NEW_VERSION} (${DATE})" |
| 54 | +echo "Workspace root: ${WORKSPACE_ROOT}" |
| 55 | +echo |
| 56 | + |
| 57 | +GIT_STATUS_OUTPUT=$(git status --untracked-files=no --porcelain) |
| 58 | +if [ -z "$ALLOW_DIRTY" ] && [ -n "${GIT_STATUS_OUTPUT}" ]; then |
| 59 | + lines=$(echo "$GIT_STATUS_OUTPUT" | wc -l | tr -d '[:space:]') |
| 60 | + echo "error: ${lines} files in the working directory contain changes that were not yet committed into git:" |
| 61 | + echo |
| 62 | + echo "${GIT_STATUS_OUTPUT}" |
| 63 | + echo |
| 64 | + echo 'To proceed despite this and include the uncommited changes, set the `ALLOW_DIRTY` environment variable.' |
| 65 | + exit 1 |
| 66 | + |
| 67 | +fi |
| 68 | + |
| 69 | +DOIT=y |
| 70 | +if [[ -n "$DRY_RUN" ]]; then |
| 71 | + echo "Dry-run. Not modifying files." |
| 72 | + DOIT=n |
| 73 | +fi |
| 74 | + |
| 75 | +# Update Glean.js version |
| 76 | + |
| 77 | +FILE=glean/package.json |
| 78 | +run $SED -i.bak -E \ |
| 79 | + -e "s/^version: \"[0-9a-z.-]+\"/version: \"${NEW_VERSION}\"/" \ |
| 80 | + "${WORKSPACE_ROOT}/${FILE}" |
| 81 | +run rm "${WORKSPACE_ROOT}/${FILE}.bak" |
| 82 | + |
| 83 | +### Update package-lock.json |
| 84 | + |
| 85 | +(cd glean && npm i --package-lock-only) |
| 86 | + |
| 87 | +### CHANGELOG ### |
| 88 | + |
| 89 | +FILE=CHANGELOG.md |
| 90 | +run $SED -i.bak -E \ |
| 91 | + -e "s/# Unreleased changes/# v${NEW_VERSION} (${DATE})/" \ |
| 92 | + -e "s/\.\.\.main/...v${NEW_VERSION}/" \ |
| 93 | + "${WORKSPACE_ROOT}/${FILE}" |
| 94 | +run rm "${WORKSPACE_ROOT}/${FILE}.bak" |
| 95 | + |
| 96 | +if [ "$DOIT" = y ]; then |
| 97 | + CHANGELOG=$(cat "${WORKSPACE_ROOT}/${FILE}") |
| 98 | + cat > "${WORKSPACE_ROOT}/${FILE}" <<EOL |
| 99 | +# Unreleased changes |
| 100 | +
|
| 101 | +[Full changelog](https://github.com/mozilla/glean.js/compare/v${NEW_VERSION}...main) |
| 102 | +${CHANGELOG} |
| 103 | +EOL |
| 104 | +fi |
| 105 | + |
| 106 | +echo "Everything prepared for v${NEW_VERSION}" |
| 107 | +echo |
| 108 | +echo "Changed files:" |
| 109 | +git status --untracked-files=no --porcelain || true |
| 110 | +echo |
| 111 | +echo "Create release commit v${NEW_VERSION} now? [y/N]" |
| 112 | +read -r RESP |
| 113 | +echo |
| 114 | +if [ "$RESP" != "y" ] && [ "$RESP" != "Y" ]; then |
| 115 | + echo "No new commit. No new tag. Proceed manually." |
| 116 | + exit 0 |
| 117 | +fi |
| 118 | + |
| 119 | +run git add --update "${WORKSPACE_ROOT}" |
| 120 | +run git commit --message "Bumped version to ${NEW_VERSION}" |
| 121 | + |
| 122 | +if git remote | grep -q upstream; then |
| 123 | + remote=upstream |
| 124 | +else |
| 125 | + remote=origin |
| 126 | +fi |
| 127 | +branch=$(git rev-parse --abbrev-ref HEAD) |
| 128 | + |
| 129 | +echo "Don't forget to push this commit:" |
| 130 | +echo |
| 131 | +echo " git push $remote $branch" |
| 132 | +echo |
| 133 | +echo "Once pushed, wait for the CI build to finish: https://circleci.com/gh/mozilla/glean.js/tree/$branch" |
0 commit comments