Automate the release

Signed-off-by: Jean-Laurent de Morlhon <jeanlaurent@morlhon.net>
This commit is contained in:
Jean-Laurent de Morlhon 2015-12-16 10:12:47 +01:00
parent eeec362ba4
commit 07a0dfdd58
5 changed files with 321 additions and 102 deletions

View File

@ -12,65 +12,29 @@ several "checklist items" which should be documented. This document is intended
to cover the current Docker Machine release process. It is written for Docker to cover the current Docker Machine release process. It is written for Docker
Machine core maintainers who might find themselves performing a release. Machine core maintainers who might find themselves performing a release.
1. **Version Bump** -- When all commits for the release have been merged into 1. **Get a GITHUB_TOKEN** Check that you have a proper `GITHUB_TOKEN`. This
master and/or the release branch, submit a pull request bumping the `Version` token needs only to have the `repo` scope. The token can be created on github
variable in `version/version.go` to the release version. Merge said pull in the settings > Personal Access Token menu.
request. 1. **Run the release script** At the root of the project, run the following
2. **Compile Binaries** -- Pull down the latest changes to master and command `GITHUB_TOKEN=XXXX script/release.sh X.Y.Z` where `XXXX` is the
cross-compile the core binary and plugin binaries for each supported OS / value of the GITHUB_TOKEN generated, `X.Y.Z` the version to release
architecture combination. As you may notice, this can potentially take a _very_ ( Explicitly excluding the 'v' prefix, the script takes care of it.). As of
long time so you may want to use a script like [this one for cross-compiling now, this version number must match the content of `version/version.go`. The
them on DigitalOcean in script has been built to be as resilient as possible, cleaning everything
parallel](https://gist.github.com/nathanleclaire/7f62fc5aa3df19a50f4e). it does along its way if necessary. You can run it many times in a row,
4. **Upload Binaries** -- Use a script or sequence of commands such as [this fixing the various bits along the way.
one](https://gist.github.com/nathanleclaire/a9bc1f8d60070aeda361) to create a 1. **Update the changelog on github** -- The script generated a list of all
git tag for the released version, a GitHub release for the released version, and commits since last release. You need to edit this manually, getting rid of
to upload the released binaries. At the time of writing the `release` target in non critical details, and putting emphasis to what need our users attention.
the `Makefile` does not work correctly for this step but it should eventually be 1. **Update the CHANGELOG.md** -- Add the same notes from the previous step to
split into a separate target and fixed. the `CHANGELOG.md` file in the repository.
5. **Generate Checksums** -- `make release-checksum` will spit out the checksums 1. **Update the Documentation** -- Ensure that the `docs` branch on GitHub
for the binaries, which you should copy and paste into the end of the release (which the Docker docs team uses to deploy from) is up to date with the
notes for anyone who wants to verify the checksums of the downloaded artifacts. changes to be deployed from the release branch / master.
6. **Add Installation Instructions** -- At the top of the release notes, copy and 1. **Verify the Installation** -- Copy and paste the suggested commands in the
paste the installation instructions from the previous release, taking care to
update the referenced download URLs to the new version.
7. **Add Release Notes** -- If release notes are already prepared, copy and
paste them into the release notes section after the installation instructions.
If they are not, you can look through the commits since the previous release
using `git log` and summarize the changes in Markdown, preferably by category.
8. **Update the CHANGELOG.md** -- Add the same notes from the previous step to the
`CHANGELOG.md` file in the repository.
9. **Generate and Add Contributor List** -- It is important to thank our
contributors for their good work and persistence. Usually I generate a list of
authors involved in the release as a Markdown ordered list using a series of
UNIX commands originating from `git` author information, and paste it into the
release notes.. For instance, to print out the list of all unique authors since
the v0.5.0 release:
$ git log v0.5.0.. --format="%aN" --reverse | sort | uniq | awk '{printf "- %s\n", $0 }'
- Amir Mohammad
- Anthony Dahanne
- David Gageot
- Jan Broer
- Jean-Laurent de Morlhon
- Kazumichi Yamamoto
- Kunal Kushwaha
- Mikhail Zholobov
- Nate McMaster
- Nathan LeClaire
- Olivier Gambier
- Soshi Katsuta
- aperepel
- jviide
- root
10. **Update the Documentation** -- Ensure that the `docs` branch on GitHub (which
the Docker docs team uses to deploy from) is up to date with the changes to be
deployed from the release branch / master.
11. **Verify the Installation** -- Copy and paste the suggested commands in the
installation notes to ensure that they work properly. Best of all, grab an installation notes to ensure that they work properly. Best of all, grab an
(uninvolved) buddy and have them try it. `docker-machine -v` should give them (uninvolved) buddy and have them try it. `docker-machine -v` should give
the released version once they have run the install commands. them the released version once they have run the install commands.
12. (Optional) **Drink a Glass of Wine** -- You've worked hard on this release. 1. (Optional) **Drink a Glass of Wine** -- You've worked hard on this release.
You deserve it. For wine suggestions, please consult your friendly neighborhood You deserve it. For wine suggestions, please consult your friendly
sommelier. neighborhood sommelier.

View File

@ -40,7 +40,6 @@ endif
include mk/build.mk include mk/build.mk
include mk/coverage.mk include mk/coverage.mk
include mk/dev.mk include mk/dev.mk
include mk/release.mk
include mk/test.mk include mk/test.mk
include mk/validate.mk include mk/validate.mk

View File

@ -1,40 +0,0 @@
release-checksum:
$(foreach MACHINE_FILE, $(wildcard $(PREFIX)/bin/*), \
$(shell printf "%-50s %-50s\n" "sha256 $(shell basename $(MACHINE_FILE))" "$(shell openssl dgst -sha256 < $(MACHINE_FILE))" > /dev/stderr) \
$(shell printf "%-50s %-50s\n" "md5 $(shell basename $(MACHINE_FILE))" "$(shell openssl dgst -md5 < $(MACHINE_FILE))" > /dev/stderr) \
)
@:
release: clean validate build-x release-checksum
# Github infos
GH_USER ?= $(shell git config --get remote.origin.url | sed -e 's/.*[:/]\(.*\)\/\([^.]*\)\(.*\)/\1/')
GH_REPO ?= $(shell git config --get remote.origin.url | sed -e 's/.*[:/]\(.*\)\/\([^.]*\)\(.*\)/\2/')
$(if $(GITHUB_TOKEN), , \
$(error GITHUB_TOKEN must be set for github-release))
$(eval VERSION=$(filter-out $@,$(MAKECMDGOALS)))
$(if $(VERSION), , \
$(error Pass the version number as the first arg. E.g.: make release 1.2.3))
git tag $(VERSION)
git push --tags
github-release release
--user $(GH_USER) \
--repo $(GH_REPO) \
--tag $(VERSION) \
--name $(VERSION) \
--description "" \
--pre-release
$(foreach MACHINE_FILE, $(wildcard $(PREFIX)/bin/*.zip), \
$(shell github-release upload \
--user $(GH_USER) \
--repo $(GH_REPO) \
--tag $(VERSION) \
--name $(MACHINE_FILE) \
--file $(MACHINE_FILE) \
) \
)

247
script/release.sh Executable file
View File

@ -0,0 +1,247 @@
#!/bin/bash
#Put your github username here, while testing performing new releases
#GITHUB_USER=jeanlaurent
GITHUB_USER=docker
GITHUB_REPO=machine
function usage {
echo "Usage: "
echo " GITHUB_TOKEN=XXXXX release/release.sh 0.5.x"
}
function display {
echo "🐳 $1"
echo ""
}
function checkError {
if [[ "$?" -ne 0 ]]; then
echo "😡 $1"
if [[ "$2" == "showUsage" ]]; then
usage
fi
exit 1
fi
}
function createMachine {
docker-machine rm -f release 2> /dev/null
docker-machine create -d virtualbox --virtualbox-cpu-count=2 --virtualbox-memory=2048 release
}
VERSION=$1
GITHUB_VERSION="v${VERSION}"
PROJECT_URL="git@github.com:${GITHUB_USER}/${GITHUB_REPO}"
RELEASE_DIR="$(git rev-parse --show-toplevel)/../release-${VERSION}"
GITHUB_RELEASE_FILE="github-release-${VERSION}.md"
if [[ -z "${VERSION}" ]]; then
#TODO: Check version is well formed
echo "Missing version argument"
usage
exit 1
fi
if [[ -z "${GITHUB_TOKEN}" ]]; then
echo "GITHUB_TOKEN missing"
usage
exit 1
fi
command -v git > /dev/null 2>&1
checkError "You obviously need git, please consider installing it..." "showUsage"
command -v github-release > /dev/null 2>&1
checkError "github-release is not installed, go get -u github.com/aktau/github-release or check https://github.com/aktau/github-release, aborting." "showUsage"
command -v openssl > /dev/null 2>&1
checkError "You need openssl to generate binaries signature, brew install it, aborting." "showUsage"
command -v docker-machine > /dev/null 2>&1
checkError "You must have a docker-machine in your path" "showUsage"
LAST_RELEASE_VERSION=$(git describe --abbrev=0 --tags)
#TODO: ABORT if not found (very unlikely but could happen if two tags are on the same commits )
# this is tag search is done on master not on the clone...
display "Starting release from ${LAST_RELEASE_VERSION} to ${GITHUB_VERSION} on ${PROJECT_URL} with token ${GITHUB_TOKEN}"
while true; do
read -p "Do you want to proceed with this release? (y/n) > " yn
case $yn in
[Yy]* ) break;;
[Nn]* ) exit;;
* ) echo "Please answer yes or no.";;
esac
done
display "Checking machine 'release' status"
MACHINE_STATUS=$(docker-machine status release)
if [[ "$?" -ne 0 ]]; then
display "Machine 'release' does not exist, creating it"
createMachine
else
if [[ "${MACHINE_STATUS}" != "Running" ]]; then
display "Machine 'release' is not running, trying to start it."
docker-machine start release
if [[ "$?" -ne 0 ]]; then
display "Machine 'release' could not be started, removing and creating a fresh new one."
createMachine
fi
display "Loosing 5 seconds to the virtualbox gods."
sleep 5
fi
fi
eval $(docker-machine env release)
checkError "Machine 'release' is in a weird state, aborting."
if [[ -d "${RELEASE_DIR}" ]]; then
display "Cleaning up ${RELEASE_DIR}"
rm -rdf "${RELEASE_DIR}"
checkError "Can't clean up ${RELEASE_DIR}. You should do it manually and retry."
fi
display "Cloning into ${RELEASE_DIR} from ${PROJECT_URL}"
mkdir -p "${RELEASE_DIR}"
checkError "Can't create ${RELEASE_DIR}, aborting."
git clone -q "${PROJECT_URL}" "${RELEASE_DIR}"
checkError "Can't clone into ${RELEASE_DIR}, aborting."
cd "${RELEASE_DIR}"
display "Bump version number to ${VERSION}"
#TODO: This only works with the version written in the version.go file
sed -i.bak s/"${VERSION}-dev"/"${VERSION}"/g version/version.go
checkError "Sed borkage..., aborting."
git add version/version.go
git commit -q -m"Bump version to ${VERSION}" -s
checkError "Can't git commit the version upgrade, aborting."
rm version/version.go.bak
display "Building in-container style"
USE_CONTAINER=true make clean validate build-x
checkError "Build error, aborting."
# this is temporary -> Remove following two lines once merged
mkdir -p script/release
cp ../machine/script/release/github-release-template.md script/release/github-release-template.md
display "Generating github release"
cp -f script/release/github-release-template.md "${GITHUB_RELEASE_FILE}"
checkError "Can't find github release template"
CONTRIBUTORS=$(git log "${LAST_RELEASE_VERSION}".. --format="%aN" --reverse | sort | uniq | awk '{printf "- %s\n", $0 }')
CHANGELOG=$(git log "${LAST_RELEASE_VERSION}".. --oneline)
CHECKSUM=""
cd bin/
for file in $(ls docker-machine*); do
SHA256=$(openssl dgst -sha256 < "${file}")
MD5=$(openssl dgst -md5 < "${file}")
LINE=$(printf "\n * **%s**\n * sha256 \`%s\`\n * md5 \`%s\`\n\n" "${file}" "${SHA256}" "${MD5}")
CHECKSUM="${CHECKSUM}${LINE}"
done
cd ..
TEMPLATE=$(cat "${GITHUB_RELEASE_FILE}")
echo "${TEMPLATE//\{\{VERSION\}\}/$GITHUB_VERSION}" > "${GITHUB_RELEASE_FILE}"
checkError "Couldn't replace [ ${GITHUB_VERSION} ]"
TEMPLATE=$(cat "${GITHUB_RELEASE_FILE}")
echo "${TEMPLATE//\{\{CHANGELOG\}\}/$CHANGELOG}" > "${GITHUB_RELEASE_FILE}"
checkError "Couldn't replace [ ${CHANGELOG} ]"
TEMPLATE=$(cat "${GITHUB_RELEASE_FILE}")
echo "${TEMPLATE//\{\{CONTRIBUTORS\}\}/$CONTRIBUTORS}" > "${GITHUB_RELEASE_FILE}"
checkError "Couldn't replace [ ${CONTRIBUTORS} ]"
TEMPLATE=$(cat "${GITHUB_RELEASE_FILE}")
echo "${TEMPLATE//\{\{CHECKSUM\}\}/$CHECKSUM}" > "${GITHUB_RELEASE_FILE}"
checkError "Couldn't replace [ ${CHECKSUM} ]"
RELEASE_DOCUMENTATION="$(cat ${GITHUB_RELEASE_FILE})"
display "Tagging and pushing tags"
git remote | grep -q remote.prod.url
if [[ "$?" -ne 0 ]]; then
display "Adding 'remote.prod.url' remote git url"
git remote add remote.prod.url "${PROJECT_URL}"
fi
display "Checking if remote tag ${GITHUB_VERSION} already exists."
git ls-remote --tags 2> /dev/null | grep -q "${GITHUB_VERSION}" # returns 0 if found, 1 if not
if [[ "$?" -ne 1 ]]; then
display "Deleting previous tag ${GITHUB_VERSION}"
git tag -d "${GITHUB_VERSION}"
git push origin :refs/tags/"${GITHUB_VERSION}"
else
echo "Tag ${GITHUB_VERSION} does not exist... yet"
fi
display "Tagging release on github"
git tag "${GITHUB_VERSION}"
git push remote.prod.url "${GITHUB_VERSION}"
checkError "Could not push to remote url"
display "Checking if release already exists"
github-release info \
--security-token "${GITHUB_TOKEN}" \
--user "${GITHUB_USER}" \
--repo "${GITHUB_REPO}" \
--tag "${GITHUB_VERSION}" > /dev/null 2>&1
if [[ "$?" -ne 1 ]]; then
display "Release already exists, cleaning it up."
github-release delete \
--security-token "${GITHUB_TOKEN}" \
--user "${GITHUB_USER}" \
--repo "${GITHUB_REPO}" \
--tag "${GITHUB_VERSION}"
checkError "Could not delete release, aborting."
fi
display "Creating release on github"
github-release release \
--security-token "${GITHUB_TOKEN}" \
--user "${GITHUB_USER}" \
--repo "${GITHUB_REPO}" \
--tag "${GITHUB_VERSION}" \
--name "${GITHUB_VERSION}" \
--description "${RELEASE_DOCUMENTATION}" \
--pre-release
checkError "Could not create release, aborting."
display "Uploading binaries"
cd bin/
for file in $(ls docker-machine*); do
display "Uploading ${file}..."
github-release upload \
--security-token "${GITHUB_TOKEN}" \
--user "${GITHUB_USER}" \
--repo "${GITHUB_REPO}" \
--tag "${GITHUB_VERSION}" \
--name "${file}" \
--file "${file}"
if [[ "$?" -ne 0 ]]; then
display "Could not upload ${file}, continuing with others."
fi
done
cd ..
git remote rm remote.prod.url
rm ${GITHUB_RELEASE_FILE}
echo "There is a couple of tasks your still need to do manually, either until this script if updated or because this is a manual thing."
echo " 1 Head over to the release note created for you on github https://github.com/docker/machine/releases/tag/${GITHUB_VERSION}, you'll have a chance to enhance commit details a bit."
echo " 2 Once you're happy with your release note on github, add the revelant part to the CHANGELOG.md"
echo " 3 Update the documentation branch"
echo " 4 Test the binaries linked from the github release page"
echo " 6 Change version/version.go to the next version"
echo " 7 Party !!"
echo " The full details of these tasks are described in the RELEASE.md document, available at https://github.com/docker/machine/blob/master/docs/RELEASE.md"

View File

@ -0,0 +1,49 @@
## Installation
1. Download the file for your OS and architecture.
2. Move the binary to your PATH.
e.g., for Mac OSX:
```console
$ curl -L https://github.com/docker/machine/releases/download/{{VERSION}}/docker-machine_darwin-amd64 >/usr/local/bin/docker-machine && \
chmod +x /usr/local/bin/docker-machine
```
Linux:
```console
$ curl -L https://github.com/docker/machine/releases/download/{{VERSION}}/docker-machine_linux-amd64 >/usr/local/bin/docker-machine && \
chmod +x /usr/local/bin/docker-machine
```
Windows (using [git bash](https://git-for-windows.github.io/)):
```console
$ if [[ ! -d "$HOME/bin" ]]; then mkdir -p "$HOME/bin"; fi && \
curl -L https://github.com/docker/machine/releases/download/{{VERSION}}/docker-machine_windows-amd64.exe > "$HOME/bin/docker-machine.exe" && \
chmod +x "$HOME/bin/docker-machine.exe"
```
## Changelog
*Edit the changelog below by hand*
{{CHANGELOG}}
## Thank You
Thank you very much to our active users and contributors. If you have filed detailed bug reports, THANK YOU! Please continue to do so if you encounter any issues. It's your hard work that makes Machine better.
The following authors contributed changes to this release:
{{CONTRIBUTORS}}
Great thanks to all of the above! We appreciate it. Keep up the great work!
## Checksums
{{CHECKSUM}}