-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #4 from climatepolicyradar/merge-shared-actions-co…
…de-into-repo - Pull common github actions code into separate shared repo - Separate tag and release into two reusable workflow files
- Loading branch information
Showing
10 changed files
with
817 additions
and
59 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
############################################################################### | ||
# GitHub Code-owner Configuration for Reusable Workflows | ||
# | ||
# Each line is a file pattern followed by one or more owners. See this link: | ||
# https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners#example-of-a-codeowners-file | ||
# for more information on configuring GitHub code owners, including examples. | ||
############################################################################### | ||
|
||
# These owners will be the default owners for everything in | ||
# the repo. Unless a later match takes precedence, members | ||
# of @climatepolicyradar/tech-devs will be requested for | ||
# review when someone opens a pull request. Teams should | ||
# be identified in the format @org/team-name. Teams must have | ||
# explicit write access to the repository. | ||
* @climatepolicyradar/tech-devs |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
#!/bin/bash | ||
set -euo pipefail | ||
|
||
script_folder=$(dirname "${BASH_SOURCE[0]}") | ||
source "${script_folder}"/funcs.sh | ||
|
||
# Get the latest Git tag. | ||
latest_tag=$(get_latest_tag) | ||
if [[ -z ${latest_tag} ]]; then | ||
echo "No tags found. Please create first tag manually to enable auto-tagging." | ||
exit 1 | ||
fi | ||
echo "Latest tag: ${latest_tag}" | ||
|
||
pr_body="$1" | ||
|
||
# Get selected versioning checkboxes. | ||
is_patch=$(is_patch_selected "${pr_body}") | ||
is_minor=$(is_minor_selected "${pr_body}") | ||
is_major=$(is_major_selected "${pr_body}") | ||
|
||
pr_number="$2" | ||
|
||
if { [[ ${is_minor} == true ]] && [[ ${is_patch} == true ]]; } || | ||
{ [[ ${is_minor} == true ]] && [[ ${is_major} == true ]]; } || | ||
{ [[ ${is_patch} == true ]] && [[ ${is_major} == true ]]; }; then | ||
echo "Ambiguous tag information in body of pull request #${pr_number}. Auto-tagging will use most senior version option selected." | ||
fi | ||
|
||
# Extract the version numbers from the tag | ||
version_numbers=${latest_tag#v} # Remove the leading 'v' | ||
version_numbers=${version_numbers%-*} # Remove the trailing '-beta' | ||
major_version=$(get_major "${version_numbers}") | ||
minor_version=$(get_minor "${version_numbers}") | ||
patch_version=$(get_patch "${version_numbers}") | ||
maturity=$(get_maturity "${latest_tag}") | ||
if [[ -n ${maturity} ]]; then | ||
maturity="-${maturity}" | ||
fi | ||
|
||
# Auto-tag based on most senior version selected. | ||
if [[ ${is_major} == true ]]; then | ||
new_major_version=$(increment "${major_version}") | ||
new_tag=v${new_major_version}.0.0${maturity} | ||
echo "Tagging as new major version ${new_tag}..." | ||
elif [[ ${is_minor} == true ]]; then | ||
new_minor_version=$(increment "${minor_version}") | ||
new_tag="v${major_version}.${new_minor_version}.0${maturity}" | ||
echo "Tagging as new minor version ${new_tag}..." | ||
else | ||
new_patch_version=$(increment "${patch_version}") | ||
new_tag=v${major_version}.${minor_version}.${new_patch_version}${maturity} | ||
echo "Tagging as new patch ${new_tag}..." | ||
fi | ||
|
||
# If multiple have been checked or none have been checked, don't auto tag. | ||
if { [[ ${is_minor} == false ]] && [[ ${is_patch} == false ]] && [[ ${is_major} == false ]]; }; then | ||
echo "No tag information found in body of pull request #${pr_number}. Auto-tagging failed..." | ||
exit 1 | ||
fi | ||
|
||
echo "${new_tag}" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
# | ||
# This is the core functionality taken out so it can be tested | ||
# | ||
# Core funcs. | ||
increment() { | ||
echo $(($1 + 1)) | ||
} | ||
|
||
clean_string() { | ||
echo "${1}" | tr -d '\n' | tr -d ' ' | ||
} | ||
|
||
get_major() { | ||
echo "${1}" | cut -d'.' -f1 | ||
} | ||
|
||
get_minor() { | ||
echo "${1}" | cut -d'.' -f2 | ||
} | ||
|
||
get_patch() { | ||
if [[ ${1} == *"-"* ]]; then | ||
echo "${1}" | cut -d'.' -f3 | cut -d'-' -f1 | ||
else | ||
echo "${1}" | cut -d'.' -f3 | ||
fi | ||
} | ||
|
||
get_maturity() { | ||
if [[ ${1} == *"-"* ]]; then | ||
echo "${1}" | cut -d'.' -f3 | cut -d'-' -f2 | ||
else | ||
echo "" | ||
fi | ||
} | ||
|
||
# Docker funcs. | ||
is_tagged_version() { | ||
if [[ $1 =~ refs/tags/v(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*) ]]; then | ||
return 0 | ||
else | ||
return 1 | ||
fi | ||
} | ||
|
||
get_docker_tags() { | ||
# Arguments: | ||
# - Name reference for the array | ||
# - Name of the docker image | ||
# - The semver we are using to create the tags | ||
|
||
local -n arr=$1 # use nameref to create values | ||
name=$2 | ||
semver=$3 | ||
|
||
major=$(get_major "${semver}") | ||
minor=$(get_minor "${semver}") | ||
patch=$(get_patch "${semver}") | ||
maturity=$(get_maturity "${semver}") | ||
|
||
if [ -z ${maturity} ]; then | ||
echo "Detected Version: ${major} . ${minor} . ${patch}" | ||
full_tag="${name}:${major}.${minor}.${patch}" | ||
minor_tag="${name}:${major}.${minor}" | ||
major_tag="${name}:${major}" | ||
else | ||
echo "Detected Version: ${major} . ${minor} . ${patch} [${maturity}]" | ||
full_tag="${name}:${major}.${minor}.${patch}-${maturity}" | ||
minor_tag="${name}:${major}.${minor}-${maturity}" | ||
major_tag="${name}:${major}-${maturity}" | ||
fi | ||
arr=($full_tag $minor_tag $major_tag) | ||
} | ||
|
||
# Auto-tag funcs. | ||
is_valid_tag_name() { | ||
if [[ $1 =~ v(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*) ]]; then | ||
return 0 | ||
else | ||
return 1 | ||
fi | ||
} | ||
|
||
is_selected() { | ||
body=$1 | ||
phrase=$2 | ||
if [ $(echo "${body}" | grep -c "\[x\] ${phrase}") -gt 0 ]; then | ||
echo true | ||
else | ||
echo false | ||
fi | ||
} | ||
|
||
is_patch_selected() { | ||
local phrase=Patch | ||
is_selected "$1" "${phrase}" | ||
} | ||
|
||
is_minor_selected() { | ||
local phrase="Minor version" | ||
is_selected "$1" "${phrase}" | ||
} | ||
|
||
is_major_selected() { | ||
local phrase="Major version" | ||
is_selected "$1" "${phrase}" | ||
} | ||
|
||
get_latest_tag() { | ||
git fetch --prune --unshallow --tags --force # This is needed - without it no tags are found. | ||
latest_tag=$(git tag --list 'v*' --sort=-v:refname | head -n1) | ||
echo "${latest_tag}" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
# Description | ||
|
||
Please include: | ||
|
||
- a summary of the changes | ||
- links to any related issue/ticket | ||
- any additional relevant motivation and context | ||
- details of any dependency updates that are required for this change | ||
|
||
## Proposed version | ||
|
||
Please select the option below that is most relevant from the list below. This | ||
will be used to generate the next tag version name during auto-tagging. | ||
|
||
- [ ] Patch | ||
- [ ] Minor version | ||
- [ ] Major version | ||
|
||
Visit the [Semver website](https://semver.org/#summary) to understand the | ||
difference between `MAJOR`, `MINOR`, and `PATCH` versions. | ||
|
||
Notes: | ||
|
||
- If none of these options are selected, auto-tagging will fail | ||
- Where multiple options are selected, the most senior option ticked will be | ||
used -- e.g. Major > Minor > Patch | ||
- If you are selecting the version in the list above using the textbox, make | ||
sure your selected option is marked `[x]` with no spaces in between the | ||
brackets and the `x` | ||
|
||
## Type of change | ||
|
||
Please select the option(s) below that are most relevant: | ||
|
||
- [ ] Bug fix | ||
- [ ] New feature | ||
- [ ] Breaking change | ||
|
||
## How Has This Been Tested? | ||
|
||
Please describe the tests that you added to verify your changes. | ||
|
||
## Reviewer Checklist | ||
|
||
- [ ] The PR represents a single feature (small drive-by fixes are also ok) | ||
- [ ] The PR includes tests that are sufficient for the level of risk | ||
- [ ] The code is sufficiently commented, particularly in hard-to-understand areas | ||
- [ ] Any required documentation updates have been made | ||
- [ ] Any TODOs added are captured in future tickets | ||
- [ ] No FIXMEs remain |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
#!/bin/bash | ||
set -e | ||
|
||
script_folder=$(dirname "${BASH_SOURCE[0]}") | ||
source $script_folder/funcs.sh | ||
|
||
if [ "$#" -ne 2 ]; then | ||
echo "Pushes a container image to ECR with tags" | ||
echo | ||
echo "Usage: $0 project input_tag" | ||
echo "Example: $0 container-name 6cd9d7ebad4f16ef7273a7a831d79d5d5caf4164" | ||
echo "Relies on the following environment variables:" | ||
echo "- GITHUB_HEAD_REF, GITHUB_REF, GITHUB_SHA (GH Action default)" | ||
echo "- DOCKER_REGISTRY" | ||
exit 1 | ||
fi | ||
|
||
[ "${DOCKER_REGISTRY}" == "" ] && (echo "DOCKER_REGISTRY is not set" ; exit 1) | ||
|
||
project="$1" | ||
image_tag="$2" | ||
|
||
docker_tag() { | ||
echo "Re-tagging $1 -> $2" | ||
docker tag $1 $2 | ||
} | ||
|
||
process_tagged_version() { | ||
local tag_array | ||
semver=$1 | ||
get_docker_tags tag_array ${name} ${semver} | ||
|
||
for tag in "${tag_array[@]}" ; do | ||
docker_tag "${input_image}" ${tag} | ||
docker push "${tag}" | ||
done | ||
} | ||
|
||
name=$(clean_string "${DOCKER_REGISTRY}/${project}") | ||
input_image="${project}:${image_tag}" | ||
|
||
if [[ -n "${NEW_TAG}" ]]; then | ||
if is_valid_tag_name ${NEW_TAG} ; then | ||
# push `semver` tagged image | ||
semver="${NEW_TAG/v/}" | ||
echo "Detected Tag: ${semver}" | ||
process_tagged_version ${semver} | ||
exit 0 | ||
else | ||
echo "New tag ${NEW_TAG} is not a valid tag name" | ||
exit 1 | ||
fi | ||
fi | ||
|
||
# login | ||
# This should now be performed as a GA | ||
# See: https://docs.docker.com/build/ci/github-actions/#step-three-define-the-workflow-steps | ||
|
||
echo "-------------" | ||
echo "Input : ${project}:${image_tag}" | ||
echo "Output : ${name}" | ||
echo "GitRef : ${GITHUB_REF}" | ||
echo "GitHeadRef : ${GITHUB_HEAD_REF}" | ||
echo "Branch : ${GITHUB_REF/refs\/heads\//}" | ||
echo "Repo Tag : ${name}" | ||
echo "-------------" | ||
|
||
timestamp=$(date --utc -Iseconds | cut -c1-19 | tr -c '[0-9]T\n' '-') | ||
short_sha=${GITHUB_SHA:0:8} | ||
|
||
if [[ "${GITHUB_REF}" == "refs/heads"* ]]; then | ||
# push `branch-sha` tagged image | ||
|
||
# NOTE: Looks like the behaviour has changed for GITHHUB_REF | ||
# See: https://github.com/semantic-release/env-ci/issues/157 | ||
# ... branches will no longer be handled here but in the 'else' statement below. | ||
|
||
branch="${GITHUB_REF/refs\/heads\//}" | ||
echo "Detected Branch: ${branch}" | ||
|
||
# Only update latest if on main | ||
if [[ "${branch}" = "main" ]]; then | ||
# push `latest` tag | ||
docker_tag "${input_image}" "${name}:latest" | ||
docker push "${name}:latest" | ||
# Also tag for any versioning that might get done | ||
docker_tag "${input_image}" "${name}:${branch}-${timestamp}-${short_sha}" | ||
docker push "${name}:${branch}-${timestamp}-${short_sha}" | ||
# Also tag for any versioning that might get done | ||
docker_tag "${input_image}" "${name}:${branch}-${short_sha}" | ||
docker push "${name}:${branch}-${short_sha}" | ||
fi | ||
|
||
elif is_tagged_version ${GITHUB_REF} ; then | ||
# push `semver` tagged image | ||
semver="${GITHUB_REF/refs\/tags\/v/}" | ||
echo "Detected Tag: ${semver}" | ||
process_tagged_version ${semver} | ||
|
||
else | ||
echo "${GITHUB_REF} is neither a branch head nor valid semver tag" | ||
echo "Assuming '${GITHUB_HEAD_REF}' is a branch" | ||
if [[ -n "${GITHUB_HEAD_REF}" ]]; then | ||
branch="$(echo ${GITHUB_HEAD_REF}| tr -c '[0-9,A-Z,a-z]' '-')" | ||
docker_tag "${input_image}" "${name}:${branch}-${timestamp}-${short_sha}" | ||
docker push "${name}:${branch}-${timestamp}-${short_sha}" | ||
else | ||
echo "No branch found, not a PR so not publishing." | ||
fi | ||
fi |
Oops, something went wrong.