diff --git a/Dockerfile b/Dockerfile index 1d13be5..2b8fd9b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -16,6 +16,7 @@ RUN apk add --no-cache \ && helm plugin install https://github.com/chartmuseum/helm-push COPY entrypoint.sh /entrypoint.sh +COPY util /util ENTRYPOINT ["/entrypoint.sh"] diff --git a/README.md b/README.md index c4a02ca..476aa7d 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,29 @@ This is a bit of a dumping ground for scripts and automation around interacting ## Functions (`with.action:`) +### `generate-metadata` + +Generate metadata from `env.GITHUB_*` + +```yaml + - name: Generate metadata + id: metadata + uses: mobilecoinofficial/gha-k8s-toolbox@v1 + with: + action: generate-metadata +``` + +Outputs: +* `namespace`: k8s namespace derived from branch name +* `version`: base version +* `sha`: formatted commit SHA +* `tag`: Unique artifact tag. Use this to reference the Docker image +* `docker_tag`: Tags for the Docker image, in [docker/metadata-action syntax](https://github.com/docker/metadata-action#tags-input) + +| with | type | description | +| --- | --- | --- | +| `prefix` | `string` | Optional override of prefix. Defaults to the basename of the repository. | + ### fog-ingest-activate Find toolbox pod and activate defined blue/green fog-ingest and retire the "flipside" fog-ingest (if exists). diff --git a/action.yaml b/action.yaml index 2485570..c601d18 100644 --- a/action.yaml +++ b/action.yaml @@ -80,6 +80,9 @@ inputs: src: description: "File to copy into toolbox" required: false + prefix: + description: "Optional override of prefix. Defaults to the basename of the repository." + required: false runs: using: docker # Switch image to Dockerfile and push to a branch for testing changes. diff --git a/entrypoint.sh b/entrypoint.sh index f801991..d217210 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -109,6 +109,10 @@ toolbox_cmd() if [ -n "${INPUT_ACTION}" ] then case "${INPUT_ACTION}" in + generate-metadata) + ./util/metadata.sh + ;; + fog-ingest-activate) # CBB: we do a lot of copy pasta for "standard" commands, we should make functions. # Activate target blue/green fog-ingest. Retire flipside ingest if it exists. diff --git a/util/metadata.sh b/util/metadata.sh new file mode 100755 index 0000000..b93f7a6 --- /dev/null +++ b/util/metadata.sh @@ -0,0 +1,149 @@ +#!/bin/bash +# Copyright (c) 2018-2022 The MobileCoin Foundation +# +# Generate metadata for dev deploy workflows. + +set -eu + +export TMPDIR=".tmp" + +is_set() +{ + var_name="${1}" + + if [[ -z "${!var_name}" ]]; then + echo "${var_name} is not set." >&2 + exit 1 + fi +} + +normalize_ref_name() +{ + # Remove prefix, convert delimiters to dashes, and strip trailing dashes. + echo "${1}" | sed -Ee 's!^(feature|release)/!!' | sed -e 's![._/]!-!g' | sed -e 's!-*$!!' +} + +base_prefix() +{ + basename "${GITHUB_REPOSITORY:-$PWD}" +} + +# Check for github reference variables. +is_set GITHUB_REF_NAME +is_set GITHUB_REF_TYPE +is_set GITHUB_RUN_NUMBER +is_set GITHUB_SHA +is_set GITHUB_OUTPUT + +# OK if INPUT_PREFIX and GITHUB_REPOSITORY are unset. +namespace_prefix="$(normalize_ref_name ${INPUT_PREFIX:-$(base_prefix)})" +namespace_prefix="${namespace_prefix:-mc}" +# Make sure prefix is no longer than 10 chars, to leave room +# in the 63-char limit on k8s namespaces. +if [[ ${#namespace_prefix} -gt 10 ]] +then + namespace_prefix="${namespace_prefix:0:10}" +fi + +sha="sha-${GITHUB_SHA:0:8}" + +# Set branch name. Where we get this ref is different for branch, pull_request or delete event +branch="${GITHUB_REF_NAME}" + +# Override branch name with head when event is a PR +if [[ -n "${GITHUB_HEAD_REF:-}" ]] +then + branch="${GITHUB_HEAD_REF}" +fi + +# Override branch with delete ref if set. +if [[ -n "${DELETE_REF_NAME:-}" ]] +then + branch="${DELETE_REF_NAME}" +fi + +case "${GITHUB_REF_TYPE}" in + tag) + # check for valid tag and set outputs + version="${GITHUB_REF_NAME}" + if [[ ! "${version}" =~ ^v[0-9]+(\.[0-9]+)*.* ]] + then + echo "GitHub Tag ${version} is not valid semver." + exit 1 + fi + + if [[ "${version}" =~ - ]] + then + echo "Found pre-release tag." + # set artifact tag + tag="${version}" + else + echo "Found release tag." + # set artifact tag + tag="${version}-dev" + fi + + # Set docker metadata action compatible tag. Short tag + metadata tag. + docker_tag=$(cat << EOF +type=raw,value=${tag},priority=20 +type=raw,value=${tag}.${GITHUB_RUN_NUMBER}.${sha},priority=10 +EOF +) + + normalized_tag=$(normalize_ref_name "${tag}") + namespace="${namespace_prefix}-${normalized_tag}" + ;; + # Branches and pull requests will set type as branch. + # Don't filter on "valid" branches, rely on workflows to filter out their accepted events. + branch) + # All branch builds will just have a "dummy" tag. + version="v0" + + echo "Clean up branch. Remove feature|release prefix and replace ._/ with -" + normalized_branch="$(normalize_ref_name "${branch}")" + + # Check and truncate branch name if total tag length exceeds the 63 character K8s label value limit. + label_limit=63 + version_len=${#version} + sha_len=${#sha} + run_number_len=${#GITHUB_RUN_NUMBER} + # number of separators in tag + dots=3 + + cutoff=$((label_limit - version_len - sha_len - run_number_len - dots)) + + if [[ ${#normalized_branch} -gt ${cutoff} ]] + then + cut_branch=$(echo "${normalized_branch}" | cut -c -${cutoff}) + echo "Your branch name ${normalized_branch} + metadata exceeds the maximum length for K8s identifiers, truncating to ${cut_branch}" + normalized_branch="${cut_branch}" + fi + + echo "Before: '${branch}'" + echo "After: '${normalized_branch}'" + + # Set artifact tag + tag="${version}-${normalized_branch}.${GITHUB_RUN_NUMBER}.${sha}" + # Set docker metadata action compatible tag + docker_tag="type=raw,value=${tag}" + # Set namespace from normalized branch value + namespace="${namespace_prefix}-${normalized_branch}" + ;; + *) + echo "${GITHUB_REF_TYPE} is an unknown GitHub Reference Type" + exit 1 + ;; +esac + +# Set GHA output vars +cat <> "${GITHUB_OUTPUT}" +version=${version} +namespace=${namespace} +sha=${sha} +tag=${tag} +docker_tag<