|
| 1 | +#!/bin/bash |
| 2 | +# |
| 3 | +# ci/scripts/release |
| 4 | +# |
| 5 | +# Script for generating Github release / tag assets |
| 6 | +# and managing release notes for a Golang project |
| 7 | +# |
| 8 | +# author: Dennis Bell <[email protected]> |
| 9 | +# created: 2023-06-02 |
| 10 | +# shellcheck disable=2291 |
| 11 | + |
| 12 | +set -eu |
| 13 | + |
| 14 | +header() { |
| 15 | + echo |
| 16 | + echo "================================================================================" |
| 17 | + echo "$1" |
| 18 | + echo "--------------------------------------------------------------------------------" |
| 19 | + echo |
| 20 | +} |
| 21 | + |
| 22 | +bail() { |
| 23 | + echo >&2 "$* Did you misconfigure Concourse?" |
| 24 | + exit 2 |
| 25 | +} |
| 26 | +export REPO_ROOT="git" |
| 27 | +export BUILD_ROOT="build" |
| 28 | +export RELEASE_NOTES_ROOT="release-notes" |
| 29 | +export VERSION_FROM="version/number" |
| 30 | +[[ "${PRERELEASE:-0}" =~ (0|f|false|n|no) ]] && PRERELEASE="" |
| 31 | + |
| 32 | + |
| 33 | +test -f "${VERSION_FROM}" || bail "Version file (${VERSION_FROM}) not found." |
| 34 | +VERSION=$(cat ${VERSION_FROM}) |
| 35 | +test -n "${VERSION}" || bail "Version file (${VERSION_FROM}) was empty." |
| 36 | + |
| 37 | +test -n "${DEVELOP_BRANCH:-}" || bail "DEVELOP_BRANCH must be set to the development Git repository branch." |
| 38 | +test -n "${RELEASE_BRANCH:-}" || bail "RELEASE_BRANCH must be set to the main Git repository branch." |
| 39 | + |
| 40 | +if [[ -n "${PRERELEASE}" ]] ; then |
| 41 | + RELEASE_NOTES_PATH="pre-release-notes" |
| 42 | + cat <<EOF > "$RELEASE_NOTES_PATH" |
| 43 | +<!--- Release Notes for v${VERSION} -- Do not move ---> |
| 44 | +This is a prerelease - please see commit messages for changes |
| 45 | +EOF |
| 46 | +else |
| 47 | + test -n "${GIT_EMAIL:-}" || bail "GIT_EMAIL must be set to an email address to use for Git commits." |
| 48 | + test -n "${GIT_NAME:-}" || bail "GIT_NAME must be set to something; it will be used for Git commits." |
| 49 | + test -n "${RELEASE_ROOT:-}" || bail "RELEASE_ROOT must be set to the output directory where release artifacts should go." |
| 50 | + test -n "${RELEASE_NOTES:-}" || bail "RELEASE_NOTES must be set to the filename of the release notes." |
| 51 | + RELEASE_NOTES_PATH="${RELEASE_NOTES_ROOT}/${RELEASE_NOTES}" |
| 52 | + test -f "${RELEASE_NOTES_PATH}" || \ |
| 53 | + bail "Release notes file (${RELEASE_NOTES_PATH}) not found." |
| 54 | +fi |
| 55 | + |
| 56 | +test -n "${PROJECT:-}" || bail "PROJECT must be set to the name of this project." |
| 57 | +test -n "${GITHUB_OWNER:-}" || bail "GITHUB_OWNER must be set to the name of the Github user or organization that owns the Git repository." |
| 58 | +echo "Environment OK" |
| 59 | + |
| 60 | +############################################################### |
| 61 | +header "Assembling Github Release Artifacts..." |
| 62 | +mkdir -p "${RELEASE_ROOT}/artifacts" |
| 63 | +echo "v${VERSION}" "-> ${RELEASE_ROOT}/tag" |
| 64 | +echo "v${VERSION}" > "${RELEASE_ROOT}/tag" |
| 65 | +echo "v${VERSION}" "-> ${RELEASE_ROOT}/name" |
| 66 | +echo "v${VERSION}" > "${RELEASE_ROOT}/name" |
| 67 | +if [[ -n "$PRERELEASE" ]] ; then |
| 68 | + echo "$(cat git/.git/ref)" "-> ${RELEASE_ROOT}/commit (pre-release)" |
| 69 | + cp git/.git/ref "${RELEASE_ROOT}/commit" |
| 70 | +fi |
| 71 | +cp -av "${BUILD_ROOT}/${PROJECT}-${VERSION}"-* "${RELEASE_ROOT}/artifacts" |
| 72 | + |
| 73 | +header "Release Notes for v${VERSION}" |
| 74 | +header="$(sed -i -e '1{w /dev/stdout' -e 'd}' "${RELEASE_NOTES_PATH}")" |
| 75 | +re="^<\!--- Release Notes for v${VERSION} -- Do not move --->$" |
| 76 | +if [[ "$header" =~ $re ]] ; then |
| 77 | + sed -i '/^---8<--- This line and everything below will be ignored ---8<---$/,$d' "${RELEASE_NOTES_PATH}" |
| 78 | + cat "${RELEASE_NOTES_PATH}" |
| 79 | + cp "${RELEASE_NOTES_PATH}" "$RELEASE_ROOT/notes.md" |
| 80 | +else |
| 81 | + echo "Failed to find release notes for v$VERSION in $RELEASE_NOTES_PATH. Found this instead:" |
| 82 | + echo |
| 83 | + echo "$header" |
| 84 | + cat "${RELEASE_NOTES_PATH}" |
| 85 | + exit 1 |
| 86 | +fi |
| 87 | + |
| 88 | +if [[ -z "${PRERELEASE}" && "$DEVELOP_BRANCH" != "$RELEASE_BRANCH" ]] ; then |
| 89 | + header "Fast-forward merge develop into ${RELEASE_BRANCH}" |
| 90 | + pushd git-main &>/dev/null |
| 91 | + git config --global user.name "${GIT_NAME}" |
| 92 | + git config --global user.email "${GIT_EMAIL}" |
| 93 | + if ! git pull ../git -X theirs --no-edit --ff-only ; then |
| 94 | + # if this fails, manual intervention is required. |
| 95 | + echo >&2 \ |
| 96 | + $'\n'"'$RELEASE_BRANCH' release branch contains commits that the '$DEVELOP_BRANCH' does not have" \ |
| 97 | + $'\n'"Cannot push changes to release branch..." |
| 98 | + exit 1 |
| 99 | + fi |
| 100 | + popd &>/dev/null |
| 101 | +fi |
| 102 | + |
| 103 | +cat > "${NOTIFICATION_OUT:-notifications}/message" <<EOS |
| 104 | +New ${PROJECT} v${VERSION} released. <https://github.com/${GITHUB_OWNER}/${PROJECT}/releases/tag/v${VERSION}|Release notes>. |
| 105 | +EOS |
| 106 | + |
| 107 | +echo |
| 108 | +echo "--------------------------------------------------------------------------------" |
| 109 | +echo "SUCCESS" |
| 110 | +exit 0 |
0 commit comments