-
Pierre Smeyers authoredPierre Smeyers authored
gitlab-ci-semrel.yml 22.75 KiB
# =========================================================================================
# Copyright (C) 2021 Orange & contributors
#
# This program is free software; you can redistribute it and/or modify it under the terms
# of the GNU Lesser General Public License as published by the Free Software Foundation;
# either version 3 of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License along with this
# program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
# Floor, Boston, MA 02110-1301, USA.
# =========================================================================================
# default workflow rules: Merge Request pipelines
workflow:
rules:
# prevent branch pipeline when an MR is open (prefer MR pipeline)
- if: '$CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS'
when: never
- if: '$CI_COMMIT_MESSAGE =~ "/\[(ci skip|skip ci) on ([^],]*,)*tag(,[^],]*)*\]/" && $CI_COMMIT_TAG'
when: never
- if: '$CI_COMMIT_MESSAGE =~ "/\[(ci skip|skip ci) on ([^],]*,)*branch(,[^],]*)*\]/" && $CI_COMMIT_BRANCH'
when: never
- if: '$CI_COMMIT_MESSAGE =~ "/\[(ci skip|skip ci) on ([^],]*,)*mr(,[^],]*)*\]/" && $CI_MERGE_REQUEST_ID'
when: never
- if: '$CI_COMMIT_MESSAGE =~ "/\[(ci skip|skip ci) on ([^],]*,)*default(,[^],]*)*\]/" && $CI_COMMIT_REF_NAME =~ $CI_DEFAULT_BRANCH'
when: never
- if: '$CI_COMMIT_MESSAGE =~ "/\[(ci skip|skip ci) on ([^],]*,)*prod(,[^],]*)*\]/" && $CI_COMMIT_REF_NAME =~ $PROD_REF'
when: never
- if: '$CI_COMMIT_MESSAGE =~ "/\[(ci skip|skip ci) on ([^],]*,)*integ(,[^],]*)*\]/" && $CI_COMMIT_REF_NAME =~ $INTEG_REF'
when: never
- if: '$CI_COMMIT_MESSAGE =~ "/\[(ci skip|skip ci) on ([^],]*,)*dev(,[^],]*)*\]/" && $CI_COMMIT_REF_NAME !~ $PROD_REF && $CI_COMMIT_REF_NAME !~ $INTEG_REF'
when: never
- when: always
variables:
# variabilized tracking image
TBC_TRACKING_IMAGE: "$CI_REGISTRY/to-be-continuous/tools/tracking:master"
# Default Docker image (use a public image - can be overridden)
SEMREL_IMAGE: "registry.hub.docker.com/library/node:latest"
SEMREL_HOOKS_DIR: "."
SEMREL_TAG_FORMAT: "$${version}"
# default production ref name (pattern)
PROD_REF: '/^(master|main)$/'
SEMREL_REQUIRED_PLUGINS_FILE: "semrel-required-plugins.txt"
# undocumented (for internal use only)
SEMREL_VERIFY_CONDITIONS_CMD: "verify-conditions.sh"
SEMREL_VERIFY_RELEASE_CMD: "verify-release.sh"
SEMREL_PREPARE_CMD: "prepare.sh"
SEMREL_PUBLISH_CMD: "publish.sh"
SEMREL_SUCCESS_CMD: "success.sh"
SEMREL_FAIL_CMD: "fail.sh"
SEMREL_VERSION: latest
SEMREL_EXEC_VERSION: latest
SEMREL_CONFIG_DIR: "."
stages:
- publish
.semrel-scripts: &semrel-scripts |
# BEGSCRIPT
set -e
function log_info() {
echo -e "[\\e[1;94mINFO\\e[0m] $*"
}
function log_warn() {
echo -e "[\\e[1;93mWARN\\e[0m] $*"
}
function log_error() {
echo -e "[\\e[1;91mERROR\\e[0m] $*"
}
function fail() {
log_error "$*"
exit 1
}
function assert_defined() {
if [[ -z "$1" ]]
then
log_error "$2"
exit 1
fi
}
function install_ca_certs() {
certs=$1
if [[ -z "$certs" ]]
then
return
fi
# import in system
if echo "$certs" >> /etc/ssl/certs/ca-certificates.crt
then
log_info "CA certificates imported in \\e[33;1m/etc/ssl/certs/ca-certificates.crt\\e[0m"
fi
if echo "$certs" >> /etc/ssl/cert.pem
then
log_info "CA certificates imported in \\e[33;1m/etc/ssl/cert.pem\\e[0m"
fi
# configure for npm
echo "$certs" > /tmp/custom-ca.pem
export NODE_EXTRA_CA_CERTS=/tmp/custom-ca.pem
# import in Java keystore (if keytool command found)
if command -v keytool > /dev/null
then
# shellcheck disable=SC2046
javahome=${JAVA_HOME:-$(dirname $(readlink -f $(command -v java)))/..}
# shellcheck disable=SC2086
keystore=${JAVA_KEYSTORE_PATH:-$(ls -1 $javahome/jre/lib/security/cacerts 2>/dev/null || ls -1 $javahome/lib/security/cacerts 2>/dev/null || echo "")}
if [[ -f "$keystore" ]]
then
storepass=${JAVA_KEYSTORE_PASSWORD:-changeit}
nb_certs=$(echo "$certs" | grep -c 'END CERTIFICATE')
log_info "importing $nb_certs certificates in Java keystore \\e[33;1m$keystore\\e[0m..."
for idx in $(seq 0 $((nb_certs - 1)))
do
# TODO: use keytool option -trustcacerts ?
if echo "$certs" | awk "n==$idx { print }; /END CERTIFICATE/ { n++ }" | keytool -noprompt -import -alias "imported CA Cert $idx" -keystore "$keystore" -storepass "$storepass"
then
log_info "... CA certificate [$idx] successfully imported"
else
log_warn "... Failed importing CA certificate [$idx]: abort"
return
fi
done
else
log_warn "Java keystore \\e[33;1m$keystore\\e[0m not found: could not import CA certificates"
fi
fi
}
function unscope_variables() {
_scoped_vars=$(env | awk -F '=' "/^scoped__[a-zA-Z0-9_]+=/ {print \$1}" | sort)
if [[ -z "$_scoped_vars" ]]; then return; fi
log_info "Processing scoped variables..."
for _scoped_var in $_scoped_vars
do
_fields=${_scoped_var//__/:}
_condition=$(echo "$_fields" | cut -d: -f3)
case "$_condition" in
if) _not="";;
ifnot) _not=1;;
*)
log_warn "... unrecognized condition \\e[1;91m$_condition\\e[0m in \\e[33;1m${_scoped_var}\\e[0m"
continue
;;
esac
_target_var=$(echo "$_fields" | cut -d: -f2)
_cond_var=$(echo "$_fields" | cut -d: -f4)
_cond_val=$(eval echo "\$${_cond_var}")
_test_op=$(echo "$_fields" | cut -d: -f5)
case "$_test_op" in
defined)
if [[ -z "$_not" ]] && [[ -z "$_cond_val" ]]; then continue;
elif [[ "$_not" ]] && [[ "$_cond_val" ]]; then continue;
fi
;;
equals|startswith|endswith|contains|in|equals_ic|startswith_ic|endswith_ic|contains_ic|in_ic)
# comparison operator
# sluggify actual value
_cond_val=$(echo "$_cond_val" | tr '[:punct:]' '_')
# retrieve comparison value
_cmp_val_prefix="scoped__${_target_var}__${_condition}__${_cond_var}__${_test_op}__"
_cmp_val=${_scoped_var#"$_cmp_val_prefix"}
# manage 'ignore case'
if [[ "$_test_op" == *_ic ]]
then
# lowercase everything
_cond_val=$(echo "$_cond_val" | tr '[:upper:]' '[:lower:]')
_cmp_val=$(echo "$_cmp_val" | tr '[:upper:]' '[:lower:]')
fi
case "$_test_op" in
equals*)
if [[ -z "$_not" ]] && [[ "$_cond_val" != "$_cmp_val" ]]; then continue;
elif [[ "$_not" ]] && [[ "$_cond_val" == "$_cmp_val" ]]; then continue;
fi
;;
startswith*)
if [[ -z "$_not" ]] && [[ "$_cond_val" != "$_cmp_val"* ]]; then continue;
elif [[ "$_not" ]] && [[ "$_cond_val" == "$_cmp_val"* ]]; then continue;
fi
;;
endswith*)
if [[ -z "$_not" ]] && [[ "$_cond_val" != *"$_cmp_val" ]]; then continue;
elif [[ "$_not" ]] && [[ "$_cond_val" == *"$_cmp_val" ]]; then continue;
fi
;;
contains*)
if [[ -z "$_not" ]] && [[ "$_cond_val" != *"$_cmp_val"* ]]; then continue;
elif [[ "$_not" ]] && [[ "$_cond_val" == *"$_cmp_val"* ]]; then continue;
fi
;;
in*)
if [[ -z "$_not" ]] && [[ "__${_cmp_val}__" != *"__${_cond_val}__"* ]]; then continue;
elif [[ "$_not" ]] && [[ "__${_cmp_val}__" == *"__${_cond_val}__"* ]]; then continue;
fi
;;
esac
;;
*)
log_warn "... unrecognized test operator \\e[1;91m${_test_op}\\e[0m in \\e[33;1m${_scoped_var}\\e[0m"
continue
;;
esac
# matches
_val=$(eval echo "\$${_target_var}")
log_info "... apply \\e[32m${_target_var}\\e[0m from \\e[32m\$${_scoped_var}\\e[0m${_val:+ (\\e[33;1moverwrite\\e[0m)}"
_val=$(eval echo "\$${_scoped_var}")
export "${_target_var}"="${_val}"
done
log_info "... done"
}
# evaluate and export a secret
# - $1: secret variable name
function eval_secret() {
name=$1
value=$(eval echo "\$${name}")
case "$value" in
@b64@*)
decoded=$(mktemp)
errors=$(mktemp)
if echo "$value" | cut -c6- | base64 -d > "${decoded}" 2> "${errors}"
then
# shellcheck disable=SC2086
export ${name}="$(cat ${decoded})"
log_info "Successfully decoded base64 secret \\e[33;1m${name}\\e[0m"
else
fail "Failed decoding base64 secret \\e[33;1m${name}\\e[0m:\\n$(sed 's/^/... /g' "${errors}")"
fi
;;
@hex@*)
decoded=$(mktemp)
errors=$(mktemp)
if echo "$value" | cut -c6- | sed 's/\([0-9A-F]\{2\}\)/\\\\x\1/gI' | xargs printf > "${decoded}" 2> "${errors}"
then
# shellcheck disable=SC2086
export ${name}="$(cat ${decoded})"
log_info "Successfully decoded hexadecimal secret \\e[33;1m${name}\\e[0m"
else
fail "Failed decoding hexadecimal secret \\e[33;1m${name}\\e[0m:\\n$(sed 's/^/... /g' "${errors}")"
fi
;;
@url@*)
url=$(echo "$value" | cut -c6-)
if command -v curl > /dev/null
then
decoded=$(mktemp)
errors=$(mktemp)
if curl -s -S -f --connect-timeout 5 -o "${decoded}" "$url" 2> "${errors}"
then
# shellcheck disable=SC2086
export ${name}="$(cat ${decoded})"
log_info "Successfully curl'd secret \\e[33;1m${name}\\e[0m"
else
log_warn "Failed getting secret \\e[33;1m${name}\\e[0m:\\n$(sed 's/^/... /g' "${errors}")"
fi
elif command -v wget > /dev/null
then
decoded=$(mktemp)
errors=$(mktemp)
if wget -T 5 -O "${decoded}" "$url" 2> "${errors}"
then
# shellcheck disable=SC2086
export ${name}="$(cat ${decoded})"
log_info "Successfully wget'd secret \\e[33;1m${name}\\e[0m"
else
log_warn "Failed getting secret \\e[33;1m${name}\\e[0m:\\n$(sed 's/^/... /g' "${errors}")"
fi
else
log_warn "Couldn't get secret \\e[33;1m${name}\\e[0m: no http client found"
fi
;;
esac
}
function eval_all_secrets() {
encoded_vars=$(env | grep -v '^scoped__' | awk -F '=' '/^[a-zA-Z0-9_]*=@(b64|hex|url)@/ {print $1}')
for var in $encoded_vars
do
eval_secret "$var"
done
}
function extract_release_config_from_package_json() {
package_json="./package.json"
if [[ -f "${package_json}" ]]; then
release_config=$(node -pe "JSON.stringify(require('${package_json}').release, null, 2)")
case "$release_config" in
"undefined"|"null") release_config="" ;;
esac
echo "$release_config"
fi
}
function prepare_semantic_release() {
git config --global --add safe.directory "$(pwd)"
if [[ -f ".releaserc" ]]; then
log_info "\\e[33;1m.releaserc\\e[0m file found"
semrelConfigFile=".releaserc"
elif [[ -f ".releaserc.yml" ]]; then
log_info "\\e[33;1m.releaserc.yml\\e[0m file found"
semrelConfigFile=".releaserc.yml"
elif [[ -f ".releaserc.yaml" ]]; then
log_info "\\e[33;1m.releaserc.yaml\\e[0m file found"
semrelConfigFile=".releaserc.yaml"
elif [[ -f ".releaserc.json" ]]; then
log_info "\\e[33;1m.releaserc.json\\e[0m file found"
semrelConfigFile=".releaserc.json"
elif [[ -f ".releaserc.js" ]]; then
log_info "\\e[33;1m.releaserc.js\\e[0m file found"
semrelConfigFile=".releaserc.js"
else
releaseConfig="$(extract_release_config_from_package_json)"
if [[ -n "${releaseConfig}" ]]; then
log_info "release configuration found in \\e[33;1mpackage.json\\e[0m file"
# exporting release configuration in dedicated file for required plugins installation
semrelConfigFile=".release_config_from_package_json"
echo "${releaseConfig}" > "${semrelConfigFile}"
else
log_info "semantic release configuration file not found, generating default \\e[33;1m.releaserc\\e[0m"
semrelConfigFile=".releaserc"
if [[ -n "$TRACE" ]]; then
debug="true"
else
debug="false"
fi
changelogPluginConfig=$(generate_changelog_plugin_conf)
execPluginConfig=$(generate_exec_plugin_conf)
gitPluginConfig=$(generate_git_plugin_conf)
{
echo "debug: ${debug}"
echo ""
echo "tagFormat: '${SEMREL_TAG_FORMAT}'"
echo ""
echo "plugins: "
echo " - '@semantic-release/commit-analyzer'"
echo " - '@semantic-release/release-notes-generator'"
echo " - '@semantic-release/gitlab'"
echo "${changelogPluginConfig}"
echo "${execPluginConfig}"
echo "${gitPluginConfig}"
echo ""
echo "branches:"
echo " - 'master'"
echo " - 'main'"
} > "${semrelConfigFile}"
cat "${semrelConfigFile}"
fi
fi
}
function install_semantic_release_plugins() {
log_info "installing required plugins"
# shellcheck disable=SC2046
if [[ -f "${SEMREL_REQUIRED_PLUGINS_FILE}" ]]; then
while IFS= read -r line || [[ -n "$line" ]]
do
required_plugins="${required_plugins} $line"
done <<< $(cat "${SEMREL_REQUIRED_PLUGINS_FILE}")
fi
# shellcheck disable=SC2046
while IFS= read -r line || [[ -n "$line" ]]
do
plugin=$(echo "$line" | cut -d\" -f2)
required_plugins="${required_plugins} $plugin"
done <<< $(yq eval ".plugins[]" "${semrelConfigFile}" -o=json --indent 0)
# shellcheck disable=SC2086
npm install -g "semantic-release@${SEMREL_VERSION}" ${required_plugins}
}
# this script console output is inserted in generated file: DO NOT ADD LOGS
function generate_changelog_plugin_conf() {
if [[ "${SEMREL_CHANGELOG_ENABLED}" = "true" ]]; then
if [[ -n "${SEMREL_CHANGELOG_FILE}" ]] || [[ -n "${SEMREL_CHANGELOG_TITLE}" ]]; then
if [[ -n "${SEMREL_CHANGELOG_FILE}" ]]; then
changeLogConfig="changelogFile: '${SEMREL_CHANGELOG_FILE}'"
fi
if [[ -n "${SEMREL_CHANGELOG_TITLE}" ]]; then
changeLogConfig=$(echo -e "${changeLogConfig:+${changeLogConfig}\n }changelogTitle: '${SEMREL_CHANGELOG_TITLE}'")
fi
echo " - - '@semantic-release/changelog'"
echo " - ${changeLogConfig}"
else
echo " - '@semantic-release/changelog'"
fi
else
echo ""
fi
}
# this script console output is inserted in generated file: DO NOT ADD LOGS
function generate_git_plugin_conf() {
# git plugin has default changelog file as asset by default so
# we need to add it explicitly if the user configured a custom changelogFile
if [[ "${SEMREL_CHANGELOG_ENABLED}" = "true" ]] && [[ -n "${SEMREL_CHANGELOG_FILE}" ]]; then
echo " - - '@semantic-release/git'"
echo " - assets:"
echo " - '${SEMREL_CHANGELOG_FILE}'"
echo " - 'package.json'"
echo " - 'package-lock.json'"
echo " - 'npm-shrinkwrap.json'"
else
echo " - '@semantic-release/git'"
fi
}
# this script console output is inserted in generated file: DO NOT ADD LOGS
function generate_exec_plugin_conf() {
scriptsConfig=""
tabs=" - "
scriptPath=${SEMREL_HOOKS_DIR}/${SEMREL_VERIFY_CONDITIONS_CMD}
if [[ -f "${scriptPath}" ]]; then
chmod +x "${scriptPath}"
scriptsConfig="${tabs}verifyConditionsCmd: '${scriptPath}'"
tabs=" "
fi
scriptPath=${SEMREL_HOOKS_DIR}/${SEMREL_VERIFY_RELEASE_CMD}
if [[ -f "${scriptPath}" ]]; then
chmod +x "${scriptPath}"
scriptsConfig=$(echo -e "${scriptsConfig}\n${tabs}verifyReleaseCmd: '\"${scriptPath}\" \"\${lastRelease.version}\" \"\${nextRelease.version}\" \"\${nextRelease.type}\"'")
tabs=" "
fi
scriptPath=${SEMREL_HOOKS_DIR}/${SEMREL_PREPARE_CMD}
if [[ -f "${scriptPath}" ]]; then
chmod +x "${scriptPath}"
scriptsConfig=$(echo -e "${scriptsConfig}\n${tabs}prepareCmd: '\"${scriptPath}\" \"\${lastRelease.version}\" \"\${nextRelease.version}\" \"\${nextRelease.type}\"'")
tabs=" "
fi
scriptPath=${SEMREL_HOOKS_DIR}/${SEMREL_PUBLISH_CMD}
if [[ -f "${scriptPath}" ]]; then
chmod +x "${scriptPath}"
scriptsConfig=$(echo -e "${scriptsConfig}\n${tabs}publishCmd: '\"${scriptPath}\" \"\${nextRelease.version}\" \"\${options.branch}\" \"\${commits.length}\" \"\${Date.now()}\"'")
tabs=" "
fi
scriptPath=${SEMREL_HOOKS_DIR}/${SEMREL_SUCCESS_CMD}
if [[ -f "${scriptPath}" ]]; then
chmod +x "${scriptPath}"
scriptsConfig=$(echo -e "${scriptsConfig}\n${tabs}successCmd: '\"${scriptPath}\" \"\${lastRelease.version}\" \"\${nextRelease.version}\"'")
tabs=" "
fi
scriptPath=${SEMREL_HOOKS_DIR}/${SEMREL_FAIL_CMD}
if [[ -f "${scriptPath}" ]]; then
chmod +x "${scriptPath}"
scriptsConfig=$(echo -e "${scriptsConfig}\n${tabs}failCmd: '\"${scriptPath}\" \"\${lastRelease.version}\" \"\${nextRelease.version}\"'")
tabs=" "
fi
if [[ -n "${scriptsConfig}" ]]; then
echo " - - '@semantic-release/exec'"
echo "${scriptsConfig}"
else
echo ""
fi
}
function install_yq() {
if ! command -v yq > /dev/null
then
yq_binary=$1
yq_version=$2
yq_url="https://github.com/mikefarah/yq/releases/download/${yq_version}/${yq_binary}.tar.gz"
wget "${yq_url}" -O - | tar xz && mv "${yq_binary}" /usr/bin/yq
fi
}
function dotenv_semrel_info() {
# removing user conf as we need to override it temporarily (git reset will put things back to normal)
# see https://www.npmjs.com/package/cosmiconfig for configuration files resolution order (we will use .releaserc)
releaserc_file="${semrelConfigFile}"
rm -f "package.json"
yq eval -P 'with_entries(select((.key | . != "plugins") and (.key | . != "verifyConditions")))' "${releaserc_file}" > "${releaserc_file}.new"
# Generating the hook scripts that will generate the dotenv file
# The dotenv file is generated in $TMPDIR so it will survive the git reset
dotenv_tmp="$(mktemp -t semrel-info-XXXXXXXXXX.dotenv)"
export_last_version_hook_script="./export-last-version.sh"
{
echo "#!/bin/bash"
echo "{"
echo "echo \"SEMREL_INFO_LAST_VERSION=\$1\""
echo "} > \"${dotenv_tmp}\""
} > "${export_last_version_hook_script}"
chmod +x ${export_last_version_hook_script}
export_next_version_hook_script="./export-next-version.sh"
{
echo "#!/bin/bash"
echo "{"
echo "echo \"SEMREL_INFO_NEXT_VERSION=\$1\""
echo "echo \"SEMREL_INFO_NEXT_VERSION_TYPE=\$2\""
echo "} >> \"${dotenv_tmp}\""
} > "${export_next_version_hook_script}"
chmod +x ${export_next_version_hook_script}
if [[ -n "$TRACE" ]]; then
echo "generated analyzeCommits hook script:"
cat "${export_last_version_hook_script}"
echo "generated verifyRelease hook script:"
cat "${export_next_version_hook_script}"
fi
# Generating temporary semantic-release config
{
echo ""
echo "# injected (replace your plugins) plugins by the template to generate dotenv"
echo ""
echo "plugins: ["
echo " \"@semantic-release/commit-analyzer\","
echo " ["
echo " \"@semantic-release/exec\","
echo " {"
echo " \"analyzeCommitsCmd\": \"${export_last_version_hook_script} \\\"\${lastRelease.version}\\\"\"",
echo " \"verifyReleaseCmd\": \"${export_next_version_hook_script} \\\"\${nextRelease.version}\\\" \\\"\${nextRelease.type}\\\"\""
echo " }"
echo " ],"
echo "]"
} >> "${releaserc_file}.new"
mv -f "${releaserc_file}.new" ".releaserc"
if [[ -n "$TRACE" ]]; then
log_info "--- generated .releaserc:"
cat ".releaserc"
fi
npm install -g "semantic-release@${SEMREL_VERSION}" "@semantic-release/exec@${SEMREL_EXEC_VERSION}"
semantic-release --dry-run
# Rollback temporary semantic-release configuration
git reset --hard
mv "${dotenv_tmp}" ./semrel.out.env
log_info "--- semrel dotenv artifact:"
cat ./semrel.out.env
}
function configure_commit_signing() {
if [[ -z "${SEMREL_GPG_SIGNKEY}" ]]; then
log_info "No GPG key provided."
return
fi
log_info "Setting commit signing up."
if [[ ! -f "${SEMREL_GPG_SIGNKEY}" ]]; then
fail "SEMREL_GPG_SIGNKEY is not a file."
fi
if ! gpg --batch --dry-run --yes --import "${SEMREL_GPG_SIGNKEY}"; then
fail "Could not import GPG key."
fi
# import the key and extract its ID from the command output
_GPG_KEY_ID=$(gpg --batch --yes --import "${SEMREL_GPG_SIGNKEY}" 2>&1 | grep "key [A-F0-9]" | head -n 1 | sed -e 's/^.*key \([A-F0-9]*\): .*$/\1/g')
if [[ -z "${_GPG_KEY_ID}" ]]; then
fail "Could not extract key ID from gpg --import command."
fi
git config --global commit.gpgsign true
git config --global user.signingkey "${_GPG_KEY_ID}"
log_info "Commit signing setup complete."
}
unscope_variables
eval_all_secrets
# ENDSCRIPT
.semrel-base:
image: $SEMREL_IMAGE
services:
- name: "$TBC_TRACKING_IMAGE"
command: ["--service", "semrel", "3.3.1" ]
before_script:
- *semrel-scripts
- install_ca_certs "${CUSTOM_CA_CERTS:-$DEFAULT_CA_CERTS}"
- cd "${SEMREL_CONFIG_DIR}"
- install_yq "yq_linux_amd64" "v4.21.1"
- prepare_semantic_release
cache:
# cache shall be per branch per template
key: "$CI_COMMIT_REF_SLUG-SEMREL"
paths:
- .npm/
semantic-release-info:
extends: .semrel-base
stage: .pre
script:
- dotenv_semrel_info
artifacts:
reports:
dotenv: "${SEMREL_CONFIG_DIR}/semrel.out.env"
rules:
- if: $CI_COMMIT_TAG
when: never
- if: '$SEMREL_INFO_ON == "prod" && $CI_COMMIT_REF_NAME =~ $PROD_REF'
- if: '$SEMREL_INFO_ON == "protected" && $CI_COMMIT_REF_PROTECTED == "true"'
- if: '$SEMREL_INFO_ON == "all"'
semantic-release:
extends: .semrel-base
stage: publish
script:
- configure_commit_signing
- install_semantic_release_plugins
- semantic-release --ci ${SEMREL_DRY_RUN+-d}
dependencies: []
rules:
- if: '$SEMREL_RELEASE_DISABLED == "true"'
when: never
- if: $CI_COMMIT_TAG
when: never
# on production branch(es): auto if SEMREL_AUTO_RELEASE_ENABLED
- if: '$SEMREL_AUTO_RELEASE_ENABLED == "true" && $CI_COMMIT_REF_NAME =~ $PROD_REF'
# on production branch(es): manual by default
- if: '$CI_COMMIT_REF_NAME =~ $PROD_REF'
when: manual
allow_failure: true