Skip to content

Commit

Permalink
Add automated release process
Browse files Browse the repository at this point in the history
Closes ponylang#39
Closes ponylang#40
  • Loading branch information
SeanTAllen committed Nov 8, 2019
1 parent c8fe233 commit dada544
Show file tree
Hide file tree
Showing 11 changed files with 602 additions and 7 deletions.
174 changes: 174 additions & 0 deletions .ci-scripts/release/announce-a-release.bash
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
#!/bin/bash

# Announces a release after artifacts have been built:
#
# - Publishes release notes to GitHub
# - Announces in the #announce stream of Zulip
# - Adds a note about the release to LWIP
#
# Tools required in the environment that runs this:
#
# - bash
# - changelog-tool
# - curl
# - git
# - jq

set -o errexit
set -o nounset

# Pull in shared configuration specific to this repo
base=$(dirname "$0")
source "${base}/config.bash"

# Verify ENV is set up correctly
# We validate all that need to be set in case, in an absolute emergency,
# we need to run this by hand. Otherwise the GitHub actions environment should
# provide all of these if properly configured
if [[ -z "${APPLICATION_NAME} ]]; then
echo -e "\e[31mName of the application being announced needs to be set in APPLICATION_NAME. Exiting."
exit 1
fi
if [[ -z "${GITHUB_ACTOR}" ]]; then
echo -e "\e[31mName of the user to make changes to repo as need to be set in GITHUB_ACTOR. Exiting."
exit 1
fi
if [[ -z "${GITHUB_TOKEN}" ]]; then
echo -e "\e[31mA personal access token needs to be set in GITHUB_TOKEN. Exiting."
exit 1
fi
if [[ -z "${GITHUB_REF}" ]]; then
echo -e "\e[31mThe release tag needs to be set in GITHUB_REF."
echo -e "\e[31mThe tag should be in the following GitHub specific form:"
echo -e "\e[31m /refs/tags/announce-X.Y.Z"
echo -e "\e[31mwhere X.Y.Z is the version we are announcing"
echo -e "\e[31mExiting."
exit 1
fi
if [[ -z "${GITHUB_REPOSITORY}" ]]; then
echo -e "\e[31mName of this repository needs to be set in GITHUB_REPOSITORY."
echo -e "\e[31mShould be in the form OWNER/REPO, for example:"
echo -e "\e[31m ponylang/ponyup"
echo -e "\e[31mExiting."
exit 1
fi
if [[ -z "${ZULIP_TOKEN}" ]]; then
echo -e "\e[31mA Zulip access token needs to be set in ZULIP_TOKEN. Exiting."
exit 1
fi
# Set up .netrc file with GitHub credentials
cat <<- EOF > $HOME/.netrc
machine github.com
login $GITHUB_ACTOR
password $GITHUB_TOKEN
machine api.github.com
login $GITHUB_ACTOR
password $GITHUB_TOKEN
EOF
chmod 600 $HOME/.netrc
git config --global user.name 'Ponylang Main Bot'
git config --global user.email '[email protected]'
git config --global push.default simple
# Extract version from tag reference
# Tag ref version: "refs/tags/announce-1.0.0"
# Version: "1.0.0"
VERSION="${GITHUB_REF/refs\/tags\/announce-/}"
# Prepare release notes
echo -e "\e[34mPreparing to update GitHub release notes..."
body=$(changelog-tool get "${VERSION}")
jsontemplate="
{
\"tag_name\":\$version,
\"name\":\$version,
\"body\":\$body
}
"
json=$(jq -n \
--arg version "$VERSION" \
--arg body "$body" \
"${jsontemplate}")
# Upload release notes
echo -e "\e[34mUploading release notes..."
result=$(curl -X POST "https://api.github.com/repos/${GITHUB_REPOSITORY}/releases" \
-H "Content-Type: application/x-www-form-urlencoded" \
-u "${GITHUB_ACTOR}:${GITHUB_TOKEN}" \
--data "${json}")
rslt_scan=$(echo "${result}" | jq -r '.id')
if [ "$rslt_scan" != null ]; then
echo -e "\e[34mRelease notes uploaded"
else
echo -e "\e[31mUnable to upload release notes, here's the curl output..."
echo -e "\e[31m${result}"
exit 1
fi
# Send announcement to Zulip
message="
Version ${VERSION} of ${APPLICATION_NAME} has been released.
See the [release notes](https://github.com/${GITHUB_REPOSITORY}/releases/tag/${VERSION}) for more details.
"
curl -X POST https://ponylang.zulipchat.com/api/v1/messages \
-u ${ZULIP_TOKEN} \
-d "type=stream" \
-d "to=announce" \
-d "topic=${APPLICATION_NAME}" \
-d "content=${message}"
# Update Last Week in Pony
echo -e "\e[34mAdding release to Last Week in Pony..."
result=$(curl https://api.github.com/repos/ponylang/ponylang-website/issues?labels=last-week-in-pony)
lwip_url=$(echo "${result}" | jq -r '.[].url')
if [ "$lwip_url" != "" ]; then
body="
Version ${VERSION} of ${APPLICATION_NAME} has been released.
See the [release notes](https://github.com/${GITHUB_REPOSITORY}/releases/tag/${VERSION}) for more details.
"
jsontemplate="
{
\"body\":\$body
}
"
json=$(jq -n \
--arg body "$body" \
"${jsontemplate}")
result=$(curl -X POST "$lwip_url/comments" \
-H "Content-Type: application/x-www-form-urlencoded" \
-u "${GITHUB_ACTOR}:${GITHUB_TOKEN}" \
--data "${json}")
rslt_scan=$(echo "${result}" | jq -r '.id')
if [ "$rslt_scan" != null ]; then
echo -e "\e[34mRelease notice posted to LWIP"
else
echo -e "\e[31mUnable to post to LWIP, here's the curl output..."
echo -e "\e[31m${result}"
fi
else
echo -e "\e[31mUnable to post to Last Week in Pony. Can't find the issue."
fi
# delete announce-VERSION tag
echo -e "\e[34mDeleting no longer needed remote tag announce-${VERSION}"
git push --delete origin "announce-${VERSION}"
59 changes: 59 additions & 0 deletions .ci-scripts/release/build-docker-images-on-release.bash
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#!/bin/bash

# *** You should already be logged in to DockerHub when you run this ***
#
# Builds docker release images with two tags:
#
# - release
# - X.Y.Z for example 0.32.1
#
# Tools required in the environment that runs this:
#
# - bash
# - docker

set -o errexit
set -o nounset

# Pull in shared configuration specific to this repo
base=$(dirname "$0")
source "${base}/config.bash"

# Verify ENV is set up correctly
# We validate all that need to be set in case, in an absolute emergency,
# we need to run this by hand. Otherwise the GitHub actions environment should
# provide all of these if properly configured
if [[ -z "${GITHUB_REF}" ]]; then
echo -e "\e[31mThe release tag needs to be set in GITHUB_REF."
echo -e "\e[31mThe tag should be in the following GitHub specific form:"
echo -e "\e[31m /refs/tags/X.Y.Z"
echo -e "\e[31mwhere X.Y.Z is the version we are releasing"
echo -e "\e[31mExiting."
exit 1
fi

if [[ -z "${GITHUB_REPOSITORY}" ]]; then
echo -e "\e[31mName of this repository needs to be set in GITHUB_REPOSITORY."
echo -e "\e[31mShould be in the form OWNER/REPO, for example:"
echo -e "\e[31m ponylang/ponyup"
echo -e "\e[31mThis will be used as the docker image name."
echo -e "\e[31mExiting."
exit 1
fi

# We aren't validating TAG is in our x.y.z format but we could.
# For now, TAG validating is left up to the configuration in
# our GitHub workflow
# Tag ref version: "refs/tags/1.0.0"
# Version: "1.0.0"
VERSION="${GITHUB_REF/refs\/tags\//}"

# Build and push :VERSION tag e.g. ponylang/ponyup:0.32.1
DOCKER_TAG=${GITHUB_REPOSITORY}:"${VERSION}"
docker build -t "${DOCKER_TAG}" .
docker push "${DOCKER_TAG}"

# Build and push "release" tag e.g. ponylang/ponyup:release
DOCKER_TAG=${GITHUB_REPOSITORY}:release
docker build -t "${DOCKER_TAG}" .
docker push "${DOCKER_TAG}"
4 changes: 4 additions & 0 deletions .ci-scripts/release/config.bash
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/bash

export APPLICATION_NAME="changelog-tool"
export APPLICATION_SUMMARY="Tool for modifying the 'standard pony' changelogs"
125 changes: 125 additions & 0 deletions .ci-scripts/release/start-a-release.bash
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
#!/bin/bash

# Starts the release process by:
#
# - Getting latest changes on master
# - Updating version in
# - VERSION
# - CHANGELOG.md
# - Pushing updated VERSION and CHANGELOG.md back to master
# - Pushing tag to kick off building artifacts
# - Adding a new "unreleased" section to CHANGELOG
# - Pushing updated CHANGELOG back to master
#
# Tools required in the environment that runs this:
#
# - bash
# - changelog-tool
# - git

set -o errexit
set -o nounset

# Pull in shared configuration specific to this repo
base=$(dirname "$0")
source "${base}/config.bash"

# Verify ENV is set up correctly
# We validate all that need to be set in case, in an absolute emergency,
# we need to run this by hand. Otherwise the GitHub actions environment should
# provide all of these if properly configured
if [[ -z "${GITHUB_ACTOR}" ]]; then
echo -e "\e[31mName of the user to make changes to repo as need to be set in GITHUB_ACTOR. Exiting."
exit 1
fi

if [[ -z "${GITHUB_TOKEN}" ]]; then
echo -e "\e[31mA personal access token needs to be set in GITHUB_TOKEN. Exiting."
exit 1
fi

if [[ -z "${GITHUB_REF}" ]]; then
echo -e "\e[31mThe release tag needs to be set in GITHUB_REF."
echo -e "\e[31mThe tag should be in the following GitHub specific form:"
echo -e "\e[31m /refs/tags/release-X.Y.Z"
echo -e "\e[31mwhere X.Y.Z is the version we are releasing"
echo -e "\e[31mExiting."
exit 1
fi

if [[ -z "${GITHUB_REPOSITORY}" ]]; then
echo -e "\e[31mName of this repository needs to be set in GITHUB_REPOSITORY."
echo -e "\e[31mShould be in the form OWNER/REPO, for example:"
echo -e "\e[31m ponylang/ponyup"
echo -e "\e[31mExiting."
exit 1
fi

# Set up .netrc file with GitHub credentials
cat <<- EOF > $HOME/.netrc
machine github.com
login $GITHUB_ACTOR
password $GITHUB_TOKEN
machine api.github.com
login $GITHUB_ACTOR
password $GITHUB_TOKEN
EOF

chmod 600 $HOME/.netrc

git config --global user.name 'Ponylang Main Bot'
git config --global user.email '[email protected]'
git config --global push.default simple

# Extract version from tag reference
# Tag ref version: "refs/tags/release-1.0.0"
# Version: "1.0.0"
VERSION="${GITHUB_REF/refs\/tags\/release-/}"

### this doesn't account for master changing commit, assumes we are HEAD
# or can otherwise push without issue. that shouldl error out without issue.
# leaving us to restart from a different HEAD commit
git checkout master
git pull

# update VERSION
echo -e "\e[34mUpdating VERSION to ${VERSION}"
echo "${VERSION}" > VERSION

# version the changelog
echo -e "\e[34mUpdating CHANGELOG.md for release"
changelog-tool release "${VERSION}" -e

# commit CHANGELOG and VERSION updates
echo -e "\e[34mCommiting VERSION and CHANGELOG.md changes"
git add CHANGELOG.md VERSION
git commit -m "${VERSION} release"

# tag release
echo -e "\e[34mTagging for release to kick off building artifacts"
git tag "${VERSION}"

# push to release to remote
echo -e "\e[34mPushing commited changes back to master"
git push origin master
echo -e "\e[34mPushing ${VERSION} tag"
git push origin "${VERSION}"

# pull again, just in case, odds of this being needed are really slim
git pull

# update CHANGELOG for new entries
echo -e "\e[34mAdding new 'unreleased' section to CHANGELOG.md"
changelog-tool unreleased -e

# commit changelog and push to master
echo -e "\e[34mCommiting CHANGELOG.md change"
git add CHANGELOG.md
git commit -m "Add unreleased section to CHANGELOG post ${VERSION} release [skip ci]"

echo -e "\e[34mPushing CHANGELOG.md"
git push origin master

# delete release-VERSION tag
echo -e "\e[34mDeleting no longer needed remote tag release-${VERSION}"
git push --delete origin "release-${VERSION}"
Loading

0 comments on commit dada544

Please sign in to comment.