diff --git a/RELEASING.md b/RELEASING.md index a20da22e152..bd8a5592442 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -7,33 +7,48 @@ on the master branch instead or released version. But they shouldn't be depending on the master. So it is not a concern. 1. Run the pre-release script. It creates a branch pre_release_ to make the changes. -2. Verify the changes. -3. Push the changes to upstream. -4. Create a PR on github and merge the PR once approved. ``` ./pre_release.sh -t + ``` + +2. Verify the changes. + + ``` git diff master + ``` + +3. Push the changes to upstream. + + ``` git push ``` +4. Create a PR on github and merge the PR once approved. + ## Tag Now create a new Tag on the commit hash of the changes made in pre-release step. Use the same tag as used in the pre-release step. 1. Run the tag.sh script. + + ``` + ./tag.sh + ``` + 2. Push tags upstream. Make sure you run this for all sub-modules as well. ``` - ./tag.sh -t -c git push upstream git push upstream + ... ``` ## Release -Now create a release for the new tag on github. tag.sh script generates commit logs since -last release. Use that to draft the new release. +Now create a release for the new `` on github. +The release body should include all the release notes in the Changelog for this release. +Additionally, the `tag.sh` script generates commit logs since last release which can be used to suppliment the release notes. ## Verify Examples After releasing run following script to verify that examples build outside of the otel repo. diff --git a/tag.sh b/tag.sh index 2816cd9aaaa..2a0ef1d26c2 100755 --- a/tag.sh +++ b/tag.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Copyright The OpenTelemetry Authors # @@ -14,76 +14,165 @@ # See the License for the specific language governing permissions and # limitations under the License. -set -e +readonly PROGNAME=$(basename "$0") +readonly PROGDIR=$(readlink -m "$(dirname "$0")") -help() -{ - printf "\n" - printf "Usage: $0 -t tag -c commit-hash\n" - printf "\t-t New tag that you would like to create\n" - printf "\t-c Commit hash to associate with the new tag\n" - exit 1 # Exit script after printing help +readonly EXCLUDE_PACKAGES="tools" +readonly SEMVER_REGEX="v(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(\\-[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?(\\+[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?" + +usage() { + cat <<- EOF +Usage: $PROGNAME [OPTIONS] SEMVER_TAG COMMIT_HASH + +Creates git tag for all Go packages in project. + +OPTIONS: + -h --help Show this help. + +ARGUMENTS: + SEMVER_TAG Semantic version to tag with. + COMMIT_HASH Git commit hash to tag. +EOF +} + +cmdline() { + local arg commit + + for arg + do + local delim="" + case "$arg" in + # Translate long form options to short form. + --help) args="${args}-h ";; + # Pass through for everything else. + *) [[ "${arg:0:1}" == "-" ]] || delim="\"" + args="${args}${delim}${arg}${delim} ";; + esac + done + + # Reset and process short form options. + eval set -- "$args" + + while getopts "h" OPTION + do + case $OPTION in + h) + usage + exit 0 + ;; + *) + echo "unknown option: $OPTION" + usage + exit 1 + ;; + esac + done + + # Positional arguments. + shift $((OPTIND-1)) + readonly TAG="$1" + if [ -z "$TAG" ] + then + echo "missing SEMVER_TAG" + usage + exit 1 + fi + if [[ ! "$TAG" =~ $SEMVER_REGEX ]] + then + printf "invalid semantic version: %s\n" "$TAG" + exit 2 + fi + if [[ "$( git tag --list "$TAG" )" ]] + then + printf "tag already exists: %s\n" "$TAG" + exit 2 + fi + + shift + commit="$1" + if [ -z "$commit" ] + then + echo "missing COMMIT_HASH" + usage + exit 1 + fi + # Verify rev is for a commit and unify hashes into a complete SHA1. + readonly SHA="$( git rev-parse --quiet --verify "${commit}^{commit}" )" + if [ -z "$SHA" ] + then + printf "invalid commit hash: %s\n" "$commit" + exit 2 + fi + if [ "$( git merge-base "$SHA" HEAD )" != "$SHA" ] + then + printf "commit '%s' not found on this branch\n" "$commit" + exit 2 + fi +} + +package_dirs() { + # Return a list of package directories in the form: + # + # package/directory/a + # package/directory/b + # deeper/package/directory/a + # ... + # + # Making sure to exclude any packages in the EXCLUDE_PACKAGES regexp. + find . -mindepth 2 -type f -name 'go.mod' -exec dirname {} \; \ + | grep -E -v "$EXCLUDE_PACKAGES" \ + | sed 's/^\.\///' \ + | sort +} + +git_tag() { + local tag="$1" + local commit="$2" + + git tag -a "$tag" -s -m "Version $tag" "$commit" } -while getopts "t:c:" opt -do - case "$opt" in - t ) TAG="$OPTARG" ;; - c ) COMMIT_HASH="$OPTARG" ;; - ? ) help ;; # Print help - esac -done - -# Print help in case parameters are empty -if [ -z "$TAG" ] || [ -z "${COMMIT_HASH}" ] -then - printf "Some or all of the parameters are missing\n"; - help -fi - -# Validate semver -SEMVER_REGEX="^v(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(\\-[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?(\\+[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?$" - - -if [[ "${TAG}" =~ ${SEMVER_REGEX} ]]; then - printf "${TAG} is valid semver tag.\n" -else - printf "${TAG} is not a valid semver tag.\n" - exit -1 -fi - -cd $(dirname $0) - -# Check if the commit-hash is valid -COMMIT_FOUND=`git log -50 --pretty=format:"%H" | grep ${COMMIT_HASH}` -if [ "${COMMIT_FOUND}" != "${COMMIT_HASH}" ] ; then - printf "Commit ${COMMIT_HASH} not found\n" - exit -1 -fi - -# Check if the tag doesn't alread exists. -TAG_FOUND=`git tag --list ${TAG}` -if [ "${TAG_FOUND}" = "${TAG}" ] ; then - printf "Tag ${TAG} already exists\n" - exit -1 -fi - -# Save most recent tag for generating logs -TAG_CURRENT=`git tag | grep '^v' | tail -1` - -PACKAGE_DIRS=$(find . -mindepth 2 -type f -name 'go.mod' -exec dirname {} \; | egrep -v 'tools' | sed 's/^\.\///' | sort) - -# Create tag for root module -git tag -a "${TAG}" -s -m "Version ${TAG}" ${COMMIT_HASH} - -# Create tag for submodules -for dir in $PACKAGE_DIRS; do - git tag -a "${dir}/${TAG}" -s -m "Version ${dir}/${TAG}" ${COMMIT_HASH} -done - -# Generate commit logs -printf "New tag ${TAG} created.\n" -printf "\n\n\nChange log since previous tag ${TAG_CURRENT}\n" -printf "======================================\n" -git --no-pager log --pretty=oneline ${TAG_CURRENT}..${TAG} +previous_version() { + local current="$1" + # Requires git > 2.0 + git tag -l --sort=v:refname \ + | grep -E "^${SEMVER_REGEX}$" \ + | grep -v "$current" \ + | tail -1 +} + +print_changes() { + local tag="$1" + local previous + + previous="$( previous_version "$tag" )" + if [ -n "$previous" ] + then + printf "\nRaw changes made between %s and %s\n" "$previous" "$tag" + printf "======================================\n" + git --no-pager log --pretty=oneline "${previous}..$tag" + fi +} + +main() { + local dir + + cmdline "$@" + + cd "$PROGDIR" || exit 3 + + # Create tag for root package. + git_tag "$TAG" "$SHA" + printf "created tag: %s\n" "$TAG" + + # Create tag for all sub-packages. + for dir in $( package_dirs ) + do + git_tag "${dir}/$TAG" "$SHA" + printf "created tag: %s\n" "${dir}/$TAG" + done + + print_changes "$TAG" +} +main "$@"