From da91b81bb89907e5bffa6553540b248d0802a3ca Mon Sep 17 00:00:00 2001 From: Daniel Nephin Date: Fri, 11 Sep 2015 01:44:25 -0400 Subject: [PATCH] Add scripts for automating parts of the release. Signed-off-by: Daniel Nephin --- project/RELEASE-PROCESS.md | 57 +++++------------- script/release/cherry-pick-pr | 28 +++++++++ script/release/make-branch | 96 +++++++++++++++++++++++++++++++ script/release/push-release | 71 +++++++++++++++++++++++ script/release/rebase-bump-commit | 39 +++++++++++++ script/release/utils.sh | 20 +++++++ 6 files changed, 269 insertions(+), 42 deletions(-) create mode 100755 script/release/cherry-pick-pr create mode 100755 script/release/make-branch create mode 100755 script/release/push-release create mode 100755 script/release/rebase-bump-commit create mode 100644 script/release/utils.sh diff --git a/project/RELEASE-PROCESS.md b/project/RELEASE-PROCESS.md index 966e06ee4..631691a0c 100644 --- a/project/RELEASE-PROCESS.md +++ b/project/RELEASE-PROCESS.md @@ -3,11 +3,12 @@ Building a Compose release ## To get started with a new release -1. Create a `bump-$VERSION` branch off master: +Create a branch, update version, and add release notes by running `make-branch` - git checkout -b bump-$VERSION master + git checkout -b bump-$VERSION $BASE_VERSION -2. Merge in the `release` branch on the upstream repo, discarding its tree entirely: +`$BASE_VERSION` will default to master. Use the last version tag for a bug fix +release. git fetch origin git merge --strategy=ours origin/release @@ -58,38 +59,21 @@ Building a Compose release ## To release a version (whether RC or stable) -1. Check that CI is passing on the bump PR. - -2. Check out the bump branch: +Check out the bump branch and run the `push-release` script git checkout bump-$VERSION + ./script/release/push-release $VERSION -3. Build the Linux binary: - script/build-linux +When prompted test the binaries. -4. Build the Mac binary in a Mountain Lion VM: - script/prepare-osx - script/build-osx +1. Draft a release from the tag on GitHub (the script will open the window for + you) -5. Test the binaries and/or get some other people to test them. + In the "Tag version" dropdown, select the tag you just pushed. -6. Create a tag: - - TAG=$VERSION # or $VERSION-rcN, if it's an RC - git tag $TAG - -7. Push the tag to the upstream repo: - - git push git@github.com:docker/compose.git $TAG - -8. Draft a release from the tag on GitHub. - - - Go to https://github.com/docker/compose/releases and click "Draft a new release". - - In the "Tag version" dropdown, select the tag you just pushed. - -9. Paste in installation instructions and release notes. Here's an example - change the Compose version and Docker version as appropriate: +2. Paste in installation instructions and release notes. Here's an example - change the Compose version and Docker version as appropriate: Firstly, note that Compose 1.5.0 requires Docker 1.8.0 or later. @@ -108,24 +92,13 @@ Building a Compose release ...release notes go here... -10. Attach the binaries. +3. Attach the binaries. -11. Don’t publish it just yet! +4. Publish the release on GitHub. -12. Upload the latest version to PyPi: +5. Check that both binaries download (following the install instructions) and run. - python setup.py sdist upload - -13. Check that the pip package installs and runs (best done in a virtualenv): - - pip install -U docker-compose==$TAG - docker-compose version - -14. Publish the release on GitHub. - -15. Check that both binaries download (following the install instructions) and run. - -16. Email maintainers@dockerproject.org and engineering@docker.com about the new release. +6. Email maintainers@dockerproject.org and engineering@docker.com about the new release. ## If it’s a stable release (not an RC) diff --git a/script/release/cherry-pick-pr b/script/release/cherry-pick-pr new file mode 100755 index 000000000..7062f7aa0 --- /dev/null +++ b/script/release/cherry-pick-pr @@ -0,0 +1,28 @@ +#!/bin/bash +# +# Cherry-pick a PR into the release branch +# + +set -e +set -o pipefail + + +function usage() { + >&2 cat << EOM +Cherry-pick commits from a github pull request. + +Usage: + + $0 +EOM + exit 1 +} + +[ -n "$1" ] || usage + + +REPO=docker/compose +GITHUB=https://github.com/$REPO/pull +PR=$1 +url="$GITHUB/$PR" +hub am -3 $url diff --git a/script/release/make-branch b/script/release/make-branch new file mode 100755 index 000000000..99f711e16 --- /dev/null +++ b/script/release/make-branch @@ -0,0 +1,96 @@ +#!/bin/bash +# +# Prepare a new release branch +# + +set -e +set -o pipefail + +. script/release/utils.sh + +REPO=git@github.com:docker/compose + + +function usage() { + >&2 cat << EOM +Create a new release branch `release-` + +Usage: + + $0 [] + +Options: + + version version string for the release (ex: 1.6.0) + base_version branch or tag to start from. Defaults to master. For + bug-fix releases use the previous stage release tag. + +EOM + exit 1 +} + +[ -n "$1" ] || usage +VERSION=$1 +BRANCH=bump-$VERSION + +if [ -z "$2" ]; then + BASE_VERSION="master" +else + BASE_VERSION=$2 +fi + + +DEFAULT_REMOTE=release +REMOTE=$(find_remote $REPO) +# If we don't have a docker origin add one +if [ -z "$REMOTE" ]; then + echo "Creating $DEFAULT_REMOTE remote" + git remote add ${DEFAULT_REMOTE} ${REPO} +fi + +# handle the difference between a branch and a tag +if [ -z "$(git name-rev $BASE_VERSION | grep tags)" ]; then + BASE_VERSION=$REMOTE/$BASE_VERSION +fi + +echo "Creating a release branch $VERSION from $BASE_VERSION" +read -n1 -r -p "Continue? (ctrl+c to cancel)" +git fetch $REMOTE -p +git checkout -b $BRANCH $BASE_VERSION + + +# Store the release version for this branch in git, so that other release +# scripts can use it +git config "branch.${BRANCH}.release" $VERSION + + +echo "Update versions in docs/install.md and compose/__init__.py" +# TODO: automate this +$EDITOR docs/install.md +$EDITOR compose/__init__.py + + +echo "Write release notes in CHANGELOG.md" +browser "https://github.com/docker/compose/issues?q=milestone%3A$VERSION+is%3Aclosed" +$EDITOR CHANGELOG.md + + +echo "Verify changes before commit. Exit the shell to commit changes" +git diff +$SHELL +git commit -a -m "Bump $VERSION" --signoff + + +echo "Push branch to user remote" +GITHUB_USER=$USER +USER_REMOTE=$(find_remote $GITHUB_USER/compose) +if [ -z "$USER_REMOTE" ]; then + echo "No user remote found for $GITHUB_USER" + read -n1 -r -p "Enter the name of your github user: " GITHUB_USER + # assumes there is already a user remote somewhere + USER_REMOTE=$(find_remote $GITHUB_USER/compose) +fi + + +git push $USER_REMOTE +browser https://github.com/docker/compose/compare/docker:release...$GITHUB_USER:$BRANCH?expand=1 diff --git a/script/release/push-release b/script/release/push-release new file mode 100755 index 000000000..276d67c1f --- /dev/null +++ b/script/release/push-release @@ -0,0 +1,71 @@ +#!/bin/bash +# +# Create the official release +# + +set -e +set -o pipefail + +. script/release/utils.sh + +function usage() { + >&2 cat << EOM +Publish a release by building all artifacts and pushing them. + +This script requires that 'git config branch.${BRANCH}.release' is set to the +release version for the release branch. + +EOM + exit 1 +} + +BRANCH="$(git rev-parse --abbrev-ref HEAD)" +VERSION="$(git config "branch.${BRANCH}.release")" || usage + +API=https://api.github.com/repos +REPO=docker/compose +GITHUB_REPO=git@github.com:$REPO + +# Check the build status is green +sha=$(git rev-parse HEAD) +url=$API/$REPO/statuses/$sha +build_status=$(curl -s $url | jq -r '.[0].state') +if [[ "$build_status" != "success" ]]; then + >&2 echo "Build status is $build_status, but it should be success." + exit -1 +fi + + +# Build the binaries and sdists +script/build-linux +# TODO: build osx binary +# script/prepare-osx +# script/build-osx +python setup.py sdist --formats=gztar,zip + + +echo "Test those binaries! Exit the shell to continue." +$SHELL + + +echo "Tagging the release as $VERSION" +git tag $VERSION +git push $GITHUB_REPO $VERSION + + +echo "Create a github release" +# TODO: script more of this https://developer.github.com/v3/repos/releases/ +browser https://github.com/$REPO/releases/new + +echo "Uploading sdist to pypi" +python setup.py sdist upload + +echo "Testing pip package" +virtualenv venv-test +source venv-test/bin/activate +pip install docker-compose==$VERSION +docker-compose version +deactivate + +echo "Now publish the github release, and test the downloads." +echo "Email maintainers@dockerproject.org and engineering@docker.com about the new release. diff --git a/script/release/rebase-bump-commit b/script/release/rebase-bump-commit new file mode 100755 index 000000000..732b31944 --- /dev/null +++ b/script/release/rebase-bump-commit @@ -0,0 +1,39 @@ +#!/bin/bash +# +# Move the "bump to " commit to the HEAD of the branch +# + +set -e + + +function usage() { + >&2 cat << EOM +Move the "bump to " commit to the HEAD of the branch + +This script requires that 'git config branch.${BRANCH}.release' is set to the +release version for the release branch. + +EOM + exit 1 +} + + +BRANCH="$(git rev-parse --abbrev-ref HEAD)" +VERSION="$(git config "branch.${BRANCH}.release")" || usage + + +COMMIT_MSG="Bump $VERSION" +sha=$(git log --grep $COMMIT_MSG --format="%H") +if [ -z "$sha" ]; then + >&2 echo "No commit with message \"$COMMIT_MSG\"" + exit 2 +fi +if [[ "$sha" == "$(git rev-parse HEAD)" ]]; then + >&2 echo "Bump commit already at HEAD" + exit 0 +fi + +commits=$(git log --format="%H" HEAD..$sha | wc -l) + +git rebase --onto $sha~1 HEAD~$commits $BRANCH +git cherry-pick $sha diff --git a/script/release/utils.sh b/script/release/utils.sh new file mode 100644 index 000000000..d64d11618 --- /dev/null +++ b/script/release/utils.sh @@ -0,0 +1,20 @@ +#!/bin/bash +# +# Util functions for release scritps +# + +set -e + + +function browser() { + local url=$1 + xdg-open $url || open $url +} + + +function find_remote() { + local url=$1 + for remote in $(git remote); do + git config --get remote.${remote}.url | grep $url > /dev/null && echo -n $remote + done +}