Skip to content

Commit 07a0dfd

Browse files
committed
Automate the release
Signed-off-by: Jean-Laurent de Morlhon <jeanlaurent@morlhon.net>
1 parent eeec362 commit 07a0dfd

File tree

5 files changed

+321
-102
lines changed

5 files changed

+321
-102
lines changed

docs/RELEASE.md

Lines changed: 25 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -12,65 +12,29 @@ several "checklist items" which should be documented. This document is intended
1212
to cover the current Docker Machine release process. It is written for Docker
1313
Machine core maintainers who might find themselves performing a release.
1414

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

mk/main.mk

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ endif
4040
include mk/build.mk
4141
include mk/coverage.mk
4242
include mk/dev.mk
43-
include mk/release.mk
4443
include mk/test.mk
4544
include mk/validate.mk
4645

mk/release.mk

Lines changed: 0 additions & 40 deletions
This file was deleted.

script/release.sh

Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
1+
#!/bin/bash
2+
3+
#Put your github username here, while testing performing new releases
4+
#GITHUB_USER=jeanlaurent
5+
GITHUB_USER=docker
6+
GITHUB_REPO=machine
7+
8+
function usage {
9+
echo "Usage: "
10+
echo " GITHUB_TOKEN=XXXXX release/release.sh 0.5.x"
11+
}
12+
13+
function display {
14+
echo "🐳 $1"
15+
echo ""
16+
}
17+
18+
function checkError {
19+
if [[ "$?" -ne 0 ]]; then
20+
echo "😡 $1"
21+
if [[ "$2" == "showUsage" ]]; then
22+
usage
23+
fi
24+
exit 1
25+
fi
26+
}
27+
28+
function createMachine {
29+
docker-machine rm -f release 2> /dev/null
30+
docker-machine create -d virtualbox --virtualbox-cpu-count=2 --virtualbox-memory=2048 release
31+
}
32+
33+
VERSION=$1
34+
GITHUB_VERSION="v${VERSION}"
35+
PROJECT_URL="git@github.com:${GITHUB_USER}/${GITHUB_REPO}"
36+
37+
RELEASE_DIR="$(git rev-parse --show-toplevel)/../release-${VERSION}"
38+
GITHUB_RELEASE_FILE="github-release-${VERSION}.md"
39+
40+
if [[ -z "${VERSION}" ]]; then
41+
#TODO: Check version is well formed
42+
echo "Missing version argument"
43+
usage
44+
exit 1
45+
fi
46+
47+
if [[ -z "${GITHUB_TOKEN}" ]]; then
48+
echo "GITHUB_TOKEN missing"
49+
usage
50+
exit 1
51+
fi
52+
53+
command -v git > /dev/null 2>&1
54+
checkError "You obviously need git, please consider installing it..." "showUsage"
55+
56+
command -v github-release > /dev/null 2>&1
57+
checkError "github-release is not installed, go get -u github.com/aktau/github-release or check https://github.com/aktau/github-release, aborting." "showUsage"
58+
59+
command -v openssl > /dev/null 2>&1
60+
checkError "You need openssl to generate binaries signature, brew install it, aborting." "showUsage"
61+
62+
command -v docker-machine > /dev/null 2>&1
63+
checkError "You must have a docker-machine in your path" "showUsage"
64+
65+
LAST_RELEASE_VERSION=$(git describe --abbrev=0 --tags)
66+
#TODO: ABORT if not found (very unlikely but could happen if two tags are on the same commits )
67+
# this is tag search is done on master not on the clone...
68+
69+
display "Starting release from ${LAST_RELEASE_VERSION} to ${GITHUB_VERSION} on ${PROJECT_URL} with token ${GITHUB_TOKEN}"
70+
while true; do
71+
read -p "Do you want to proceed with this release? (y/n) > " yn
72+
case $yn in
73+
[Yy]* ) break;;
74+
[Nn]* ) exit;;
75+
* ) echo "Please answer yes or no.";;
76+
esac
77+
done
78+
79+
display "Checking machine 'release' status"
80+
MACHINE_STATUS=$(docker-machine status release)
81+
if [[ "$?" -ne 0 ]]; then
82+
display "Machine 'release' does not exist, creating it"
83+
createMachine
84+
else
85+
if [[ "${MACHINE_STATUS}" != "Running" ]]; then
86+
display "Machine 'release' is not running, trying to start it."
87+
docker-machine start release
88+
if [[ "$?" -ne 0 ]]; then
89+
display "Machine 'release' could not be started, removing and creating a fresh new one."
90+
createMachine
91+
fi
92+
display "Loosing 5 seconds to the virtualbox gods."
93+
sleep 5
94+
fi
95+
fi
96+
97+
eval $(docker-machine env release)
98+
checkError "Machine 'release' is in a weird state, aborting."
99+
100+
if [[ -d "${RELEASE_DIR}" ]]; then
101+
display "Cleaning up ${RELEASE_DIR}"
102+
rm -rdf "${RELEASE_DIR}"
103+
checkError "Can't clean up ${RELEASE_DIR}. You should do it manually and retry."
104+
fi
105+
106+
display "Cloning into ${RELEASE_DIR} from ${PROJECT_URL}"
107+
108+
mkdir -p "${RELEASE_DIR}"
109+
checkError "Can't create ${RELEASE_DIR}, aborting."
110+
git clone -q "${PROJECT_URL}" "${RELEASE_DIR}"
111+
checkError "Can't clone into ${RELEASE_DIR}, aborting."
112+
113+
cd "${RELEASE_DIR}"
114+
115+
display "Bump version number to ${VERSION}"
116+
#TODO: This only works with the version written in the version.go file
117+
sed -i.bak s/"${VERSION}-dev"/"${VERSION}"/g version/version.go
118+
checkError "Sed borkage..., aborting."
119+
120+
git add version/version.go
121+
git commit -q -m"Bump version to ${VERSION}" -s
122+
checkError "Can't git commit the version upgrade, aborting."
123+
rm version/version.go.bak
124+
125+
display "Building in-container style"
126+
USE_CONTAINER=true make clean validate build-x
127+
checkError "Build error, aborting."
128+
129+
# this is temporary -> Remove following two lines once merged
130+
mkdir -p script/release
131+
cp ../machine/script/release/github-release-template.md script/release/github-release-template.md
132+
133+
display "Generating github release"
134+
cp -f script/release/github-release-template.md "${GITHUB_RELEASE_FILE}"
135+
checkError "Can't find github release template"
136+
CONTRIBUTORS=$(git log "${LAST_RELEASE_VERSION}".. --format="%aN" --reverse | sort | uniq | awk '{printf "- %s\n", $0 }')
137+
CHANGELOG=$(git log "${LAST_RELEASE_VERSION}".. --oneline)
138+
139+
CHECKSUM=""
140+
cd bin/
141+
for file in $(ls docker-machine*); do
142+
SHA256=$(openssl dgst -sha256 < "${file}")
143+
MD5=$(openssl dgst -md5 < "${file}")
144+
LINE=$(printf "\n * **%s**\n * sha256 \`%s\`\n * md5 \`%s\`\n\n" "${file}" "${SHA256}" "${MD5}")
145+
CHECKSUM="${CHECKSUM}${LINE}"
146+
done
147+
cd ..
148+
149+
TEMPLATE=$(cat "${GITHUB_RELEASE_FILE}")
150+
echo "${TEMPLATE//\{\{VERSION\}\}/$GITHUB_VERSION}" > "${GITHUB_RELEASE_FILE}"
151+
checkError "Couldn't replace [ ${GITHUB_VERSION} ]"
152+
153+
TEMPLATE=$(cat "${GITHUB_RELEASE_FILE}")
154+
echo "${TEMPLATE//\{\{CHANGELOG\}\}/$CHANGELOG}" > "${GITHUB_RELEASE_FILE}"
155+
checkError "Couldn't replace [ ${CHANGELOG} ]"
156+
157+
TEMPLATE=$(cat "${GITHUB_RELEASE_FILE}")
158+
echo "${TEMPLATE//\{\{CONTRIBUTORS\}\}/$CONTRIBUTORS}" > "${GITHUB_RELEASE_FILE}"
159+
checkError "Couldn't replace [ ${CONTRIBUTORS} ]"
160+
161+
TEMPLATE=$(cat "${GITHUB_RELEASE_FILE}")
162+
echo "${TEMPLATE//\{\{CHECKSUM\}\}/$CHECKSUM}" > "${GITHUB_RELEASE_FILE}"
163+
checkError "Couldn't replace [ ${CHECKSUM} ]"
164+
165+
166+
RELEASE_DOCUMENTATION="$(cat ${GITHUB_RELEASE_FILE})"
167+
168+
display "Tagging and pushing tags"
169+
git remote | grep -q remote.prod.url
170+
if [[ "$?" -ne 0 ]]; then
171+
display "Adding 'remote.prod.url' remote git url"
172+
git remote add remote.prod.url "${PROJECT_URL}"
173+
fi
174+
175+
display "Checking if remote tag ${GITHUB_VERSION} already exists."
176+
git ls-remote --tags 2> /dev/null | grep -q "${GITHUB_VERSION}" # returns 0 if found, 1 if not
177+
if [[ "$?" -ne 1 ]]; then
178+
display "Deleting previous tag ${GITHUB_VERSION}"
179+
git tag -d "${GITHUB_VERSION}"
180+
git push origin :refs/tags/"${GITHUB_VERSION}"
181+
else
182+
echo "Tag ${GITHUB_VERSION} does not exist... yet"
183+
fi
184+
185+
display "Tagging release on github"
186+
git tag "${GITHUB_VERSION}"
187+
git push remote.prod.url "${GITHUB_VERSION}"
188+
checkError "Could not push to remote url"
189+
190+
display "Checking if release already exists"
191+
github-release info \
192+
--security-token "${GITHUB_TOKEN}" \
193+
--user "${GITHUB_USER}" \
194+
--repo "${GITHUB_REPO}" \
195+
--tag "${GITHUB_VERSION}" > /dev/null 2>&1
196+
197+
if [[ "$?" -ne 1 ]]; then
198+
display "Release already exists, cleaning it up."
199+
github-release delete \
200+
--security-token "${GITHUB_TOKEN}" \
201+
--user "${GITHUB_USER}" \
202+
--repo "${GITHUB_REPO}" \
203+
--tag "${GITHUB_VERSION}"
204+
checkError "Could not delete release, aborting."
205+
fi
206+
207+
display "Creating release on github"
208+
github-release release \
209+
--security-token "${GITHUB_TOKEN}" \
210+
--user "${GITHUB_USER}" \
211+
--repo "${GITHUB_REPO}" \
212+
--tag "${GITHUB_VERSION}" \
213+
--name "${GITHUB_VERSION}" \
214+
--description "${RELEASE_DOCUMENTATION}" \
215+
--pre-release
216+
checkError "Could not create release, aborting."
217+
218+
219+
display "Uploading binaries"
220+
cd bin/
221+
for file in $(ls docker-machine*); do
222+
display "Uploading ${file}..."
223+
github-release upload \
224+
--security-token "${GITHUB_TOKEN}" \
225+
--user "${GITHUB_USER}" \
226+
--repo "${GITHUB_REPO}" \
227+
--tag "${GITHUB_VERSION}" \
228+
--name "${file}" \
229+
--file "${file}"
230+
if [[ "$?" -ne 0 ]]; then
231+
display "Could not upload ${file}, continuing with others."
232+
fi
233+
done
234+
cd ..
235+
236+
git remote rm remote.prod.url
237+
238+
rm ${GITHUB_RELEASE_FILE}
239+
240+
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."
241+
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."
242+
echo " 2 Once you're happy with your release note on github, add the revelant part to the CHANGELOG.md"
243+
echo " 3 Update the documentation branch"
244+
echo " 4 Test the binaries linked from the github release page"
245+
echo " 6 Change version/version.go to the next version"
246+
echo " 7 Party !!"
247+
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"

0 commit comments

Comments
 (0)