浏览代码

Merge pull request #2034 from dnephin/release_scripts

Automated release scripts
mnowster 10 年之前
父节点
当前提交
8616e291c5

+ 28 - 61
project/RELEASE-PROCESS.md

@@ -3,20 +3,20 @@ 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
+        ./script/release/make-branch $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
+As part of this script you'll be asked to:
 
-3.  Update the version in `docs/install.md` and `compose/__init__.py`.
+1.  Update the version in `docs/install.md` and `compose/__init__.py`.
 
     If the next release will be an RC, append `rcN`, e.g. `1.4.0rc1`.
 
-4.  Write release notes in `CHANGES.md`.
+2.  Write release notes in `CHANGES.md`.
 
     Almost every feature enhancement should be mentioned, with the most visible/exciting ones first. Use descriptive sentences and give context where appropriate.
 
@@ -24,72 +24,44 @@ Building a Compose release
 
     Improvements to the code are not worth mentioning.
 
-5.   Add a bump commit:
-
-        git commit -am "Bump $VERSION"
-
-6.   Push the bump branch to your fork:
-
-        git push --set-upstream $USERNAME bump-$VERSION
-
-7.  Open a PR from the bump branch against the `release` branch on the upstream repo, **not** against master.
 
 ## When a PR is merged into master that we want in the release
 
-1.  Check out the bump branch:
+1. Check out the bump branch and run the cherry pick script
 
         git checkout bump-$VERSION
+        ./script/release/cherry-pick-pr $PR_NUMBER
 
-2.   Cherry-pick the merge commit, fixing any conflicts if necessary:
-
-        git cherry-pick -xm1 $MERGE_COMMIT_HASH
-
-3.  Add a signoff (it’s missing from merge commits):
-
-        git commit --amend --signoff
-
-4.  Move the bump commit back to the tip of the branch:
-
-        git rebase --interactive $PARENT_OF_BUMP_COMMIT
-
-5.  Force-push the bump branch to your fork:
+2. When you are done cherry-picking branches move the bump version commit to HEAD
 
+        ./script/release/rebase-bump-commit
         git push --force $USERNAME bump-$VERSION
 
-## To release a version (whether RC or stable)
 
-1.  Check that CI is passing on the bump PR.
+## To release a version (whether RC or stable)
 
-2.  Check out the bump branch:
+Check out the bump branch and run the `build-binary` script
 
         git checkout bump-$VERSION
+        ./script/release/build-binary
 
-3.  Build the Linux binary:
-
-        script/build-linux
+When prompted build the non-linux binaries and test them.
 
-4.  Build the Mac binary in a Mountain Lion VM:
+1.  Build the Mac binary in a Mountain Lion VM:
 
         script/prepare-osx
         script/build-osx
 
-5.  Test the binaries and/or get some other people to test them.
+2.  Download the windows binary from AppVeyor
 
-6.  Create a tag:
+    https://ci.appveyor.com/project/docker/compose/build/<build id>/artifacts
 
-        TAG=$VERSION # or $VERSION-rcN, if it's an RC
-        git tag $TAG
+3.  Draft a release from the tag on GitHub (the script will open the window for
+    you)
 
-7.  Push the tag to the upstream repo:
+    In the "Tag version" dropdown, select the tag you just pushed.
 
-        git push [email protected]: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:
+4.  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 +80,19 @@ Building a Compose release
 
         ...release notes go here...
 
-10.  Attach the binaries.
-
-11. Don’t publish it just yet!
+5.  Attach the binaries.
 
-12. Upload the latest version to PyPi:
+6. If everything looks good, it's time to push the release.
 
-        python setup.py sdist upload
 
-13. Check that the pip package installs and runs (best done in a virtualenv):
+        ./script/release/push-release
 
-        pip install -U docker-compose==$TAG
-        docker-compose version
 
-14. Publish the release on GitHub.
+7.  Publish the release on GitHub.
 
-15. Check that both binaries download (following the install instructions) and run.
+8.  Check that both binaries download (following the install instructions) and run.
 
-16. Email [email protected] and [email protected] about the new release.
+9.  Email [email protected] and [email protected] about the new release.
 
 ## If it’s a stable release (not an RC)
 

+ 21 - 0
script/release/build-binaries

@@ -0,0 +1,21 @@
+#!/bin/bash
+#
+# Build the release binaries
+#
+
+. "$(dirname "${BASH_SOURCE[0]}")/utils.sh"
+
+REPO=docker/compose
+
+# Build the binaries
+script/clean
+script/build-linux
+# TODO: build osx binary
+# script/prepare-osx
+# script/build-osx
+# TODO: build or fetch the windows binary
+echo "You need to build the osx/windows binaries, that step is not automated yet."
+
+echo "Create a github release"
+# TODO: script more of this https://developer.github.com/v3/repos/releases/
+browser https://github.com/$REPO/releases/new

+ 34 - 0
script/release/cherry-pick-pr

@@ -0,0 +1,34 @@
+#!/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 <github PR number>
+EOM
+    exit 1
+}
+
+[ -n "$1" ] || usage
+
+if [ -z "$(command -v hub 2> /dev/null)" ]; then
+    >&2 echo "$0 requires https://hub.github.com/."
+    >&2 echo "Please install it and ake sure it is available on your \$PATH."
+    exit 2
+fi
+
+
+REPO=docker/compose
+GITHUB=https://github.com/$REPO/pull
+PR=$1
+url="$GITHUB/$PR"
+hub am -3 $url

+ 96 - 0
script/release/make-branch

@@ -0,0 +1,96 @@
+#!/bin/bash
+#
+# Prepare a new release branch
+#
+
+. "$(dirname "${BASH_SOURCE[0]}")/utils.sh"
+
+function usage() {
+    >&2 cat << EOM
+Create a new release branch 'release-<version>'
+
+Usage:
+
+    $0 <version> [<base_version>]
+
+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
+REPO=docker/compose
[email protected]:$REPO
+
+if [ -z "$2" ]; then
+    BASE_VERSION="master"
+else
+    BASE_VERSION=$2
+fi
+
+
+DEFAULT_REMOTE=release
+REMOTE="$(find_remote "$GITHUB_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} ${GITHUB_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"
+$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
+
+
+git diff
+echo "Verify changes before commit. Exit the shell to commit changes"
+$SHELL || true
+git commit -a -m "Bump $VERSION" --signoff --no-verify
+
+
+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 -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
+if [ -z "$USER_REMOTE" ]; then
+    >&2 echo "No user remote found. You need to 'git push' your branch."
+    exit 2
+fi
+
+
+git push $USER_REMOTE
+browser https://github.com/$REPO/compare/docker:release...$GITHUB_USER:$BRANCH?expand=1

+ 63 - 0
script/release/push-release

@@ -0,0 +1,63 @@
+#!/bin/bash
+#
+# Create the official release
+#
+
+. "$(dirname "${BASH_SOURCE[0]}")/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
+
+if [ -z "$(command -v jq 2> /dev/null)" ]; then
+    >&2 echo "$0 requires https://stedolan.github.io/jq/"
+    >&2 echo "Please install it and ake sure it is available on your \$PATH."
+    exit 2
+fi
+
+
+API=https://api.github.com/repos
+REPO=docker/compose
[email protected]:$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
+
+echo "Tagging the release as $VERSION"
+git tag $VERSION
+git push $GITHUB_REPO $VERSION
+
+echo "Uploading sdist to pypi"
+python setup.py sdist
+
+if [ "$(command -v twine 2> /dev/null)" ]; then
+    twine upload ./dist/docker-compose-${VERSION}.tar.gz
+else
+    python setup.py upload
+fi
+
+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 [email protected] and [email protected] about the new release."

+ 38 - 0
script/release/rebase-bump-commit

@@ -0,0 +1,38 @@
+#!/bin/bash
+#
+# Move the "bump to <version>" commit to the HEAD of the branch
+#
+
+. "$(dirname "${BASH_SOURCE[0]}")/utils.sh"
+
+function usage() {
+    >&2 cat << EOM
+Move the "bump to <version>" 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" "$sha..HEAD" | wc -l)
+
+git rebase --onto $sha~1 HEAD~$commits $BRANCH
+git cherry-pick $sha

+ 23 - 0
script/release/utils.sh

@@ -0,0 +1,23 @@
+#!/bin/bash
+#
+# Util functions for release scritps
+#
+
+set -e
+set -o pipefail
+
+
+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
+    # Always return true, extra remotes cause it to return false
+    true
+}