Last active
November 26, 2021 09:57
-
-
Save allex/3bed8534d89fa58ff47b9d98752e3fef to your computer and use it in GitHub Desktop.
This file contains hidden or 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
#!/bin/bash | |
# By allex_wang | |
# GistID: 3bed8534d89fa58ff47b9d98752e3fef | |
# Last Modified: Fri Sep 24, 2021 10:51 | |
set -e | |
PROG=$(basename "$0") | |
error() { echo >&2 "[$PROG]: ${*}"; } | |
[ "${CI-}" != true ] && { error "Runner context invalid"; exit 1; } | |
[ "${CI_DEBUG_TRACE-}" = "true" ] && set -x | |
# CI_X_DOCKER_IMAGE_NAME, docker image name, use project name instead." | |
# add image name with registry additionally | |
release_name=${CI_X_DOCKER_IMAGE_NAME:-${CI_PROJECT_NAME}} | |
registry="${CI_X_DOCKER_HUB:-}" | |
if [ "$registry" ]; then | |
release_name="$registry/${release_name#$registry/}" | |
fi | |
# CI_PROJECT_RELEASE_TAG, docker image tag name | |
release_tag="${CI_PROJECT_RELEASE_TAG:?Release Tag Invalid}" | |
# Build the final docker image name. eg: hub.tidu.io/test/test-ci:1.5.0 | |
release_image="${release_name}:${release_tag}" | |
upload_mirror_registry () | |
{ | |
local opts=${CI_X_DOCKER_MIRROR_OPTS:-} | |
# Evalute simple VAR-Template substitute, %{tag} -> ${release_tag} | |
opts=${opts//%\{tag\}/${release_tag}} | |
echo "Upload docker image to mirror registry ..." | |
docker pull "$release_image" >/dev/null | |
eval "(set -x; pushimage.sh -t $release_image ${opts})" | |
docker rmi -f "$release_image" >/dev/null | |
} | |
cat <<-__DOCKER_BUILD_ARGS__ >./.dockerargs | |
BUILD_GIT_HEAD=${CI_BUILD_REF} | |
BUILD_VERSION=${CI_BUILD_VERSION} | |
VERBOSE=${CI_DEBUG_TRACE:-0} | |
__DOCKER_BUILD_ARGS__ | |
awk '/^(CI_COMMIT|CI_BUILD|CI_PROJECT).*=/' env > ./.dockerenv | |
docker_file="${CI_BUILD_SPECS_DIR%/}/Dockerfile" | |
docker-build.sh \ | |
-t "$release_image" \ | |
-f "$docker_file" . \ | |
--env ./.dockerenv \ | |
--build-arg-file ./.dockerargs \ | |
--push \ | |
${CI_X_DOCKER_ARCHS:+--platform "${CI_X_DOCKER_ARCHS}"} \ | |
${CI_X_DOCKER_BASE_IMAGE:+--base-image ${CI_X_DOCKER_BASE_IMAGE}} \ | |
${CI_X_DOCKER_PATCH_IMAGE:+--patch-image ${CI_X_DOCKER_PATCH_IMAGE}} | |
if [ "${CI_X_DOCKER_MIRROR:-false}" = "true" ]; then | |
upload_mirror_registry | |
fi |
This file contains hidden or 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
#!/bin/bash | |
# vim: set ft=sh fdm=marker ts=2 sw=2 sts=2 tw=85 et: | |
set -eEu -o pipefail | |
[ "${CI-}" != true ] && exit 1 | |
# ================================================ | |
# Description: ci helper for deploy static distributes | |
# | |
# Last Modified: Fri Nov 26, 2021 17:33 | |
# Author: Allex Wang ([email protected]) | |
# | |
# Usage: | |
# ./git-deploy-bundle --proj-name cmp-ui [ ... ] | |
# (based on and forward `git-deploy` parameters) | |
# | |
# GistID: 3bed8534d89fa58ff47b9d98752e3fef | |
# GistURL: https://gist.github.com/allex/3bed8534d89fa58ff47b9d98752e3fef | |
# ================================================ | |
[ "${CI_DEBUG_TRACE-}" = "true" ] && set -x | |
PROG=$(basename "$0") | |
SH_DIR=$(cd -P -- "$(dirname -- "$(readlink -f "$0")")" && pwd -P) | |
CI_PROJECT_DIR=${CI_PROJECT_DIR-} | |
git_ref_name () { | |
local r=$1 | |
local s | |
s=$(git describe --all "$r" --candidates=0 2>/dev/null | sed "s#^.*/##") | |
echo "${s:-$(git rev-parse --short "$r")}" | |
} | |
proj_name=${CI_PROJECT_DIR##*/} | |
ref_id=${CI_BUILD_REF-$(git rev-parse HEAD)} | |
ref_name=${CI_BUILD_REF_NAME-$(git_ref_name HEAD)} | |
dest_dir=${CI_BUILD_DEST:-dist} | |
dist_tar_prefix= | |
bump_file="package.json" | |
short_refid=$(git rev-parse --short "$ref_id") | |
def_ci_specs_dir=".ci/" # default ci specs dir => `.ci` (relative project dir) | |
deploy_cmd="" # cache the deploy command for remote executions | |
### Helper & ARGS {{{ | |
die () { | |
[ "${1-}" ] && echo >&2 "fatal: ${1}" | |
exit "${2-1}" | |
} | |
error () { | |
echo >&2 "Error: ${*}" | |
} | |
assert () { | |
[ -n "$1" ] || die "${2?assert message required}" | |
} | |
# cache some parameters forward to `git deploy` | |
ARGS=() | |
while [ $# -gt 0 ]; do | |
argval=${2-} | |
case "$1" in | |
--proj-name | -n) | |
proj_name="$argval" | |
shift | |
;; | |
--bump-file) | |
bump_file=$argval | |
shift | |
;; | |
--dist-tar-prefix) | |
# Ensure the prefix path is cleanup (strip tail `/`) | |
dist_tar_prefix=${argval%/} | |
shift | |
;; | |
-c | --command) | |
deploy_cmd=$argval | |
shift | |
;; | |
*) | |
ARGS+=("$(printf '%q' "$1")") | |
;; | |
esac | |
shift | |
done | |
# }}} | |
assert "$proj_name" "project name is required" | |
WORKDIR=$(mktemp -d) | |
handle_exit () { | |
local ec=$? | |
if [ -d "$WORKDIR" ]; then rm -rf "$WORKDIR"; fi | |
trap - INT TERM EXIT | |
# declare -F on_exit, not avaiable in alipine/sh | |
if type on_exit >/dev/null 2>&1; then on_exit; fi | |
exit $ec | |
} | |
trap handle_exit 0 1 2 3 6 15 | |
# Check the specific refs are same commit | |
# $1: the reference commit id (full sha1) | |
is_ref_eq () { | |
test "$(git merge-base "$@" 2>/dev/null)" = "$1" | |
} | |
# | |
# Build deployment shell source, to be executed in remote `spush -c <CMD>` | |
# | |
gen_cd_main () { | |
local name=./deploy | |
cat <<-'__CD_MAIN__' | sed "/^ *$/d" >"$name" | |
#!/bin/sh | |
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. | |
set -eu | |
PROG=$(basename "$0") | |
info () { echo "[${PROG}] ${*}"; } | |
export CI_DEBUG_TRACE=true | |
[ "${CI-}" != true ] && exit 1 | |
[ "${CI_DEBUG_TRACE-}" = "true" ] && set -x | |
ci_dir=${CI_BUILD_SPECS_DIR:-.ci} | |
resolve_plugin () { | |
if [ -x "${ci_dir%/}/$1" ]; then | |
# resolve x file by current .ci specs (for custom cli) | |
echo ${ci_dir%/}/$p | |
return 0 | |
elif [ -n "${p#git-ci-plugin*}" ]; then | |
# ensure suffix: git-ci-plugin-xxx | |
p="git-ci-plugin-$1" | |
if [ "$(type -t "$p")" ]; then | |
echo "$p" | |
return 0 | |
fi | |
echo >&2 "error: resolve plugin '$1' failed" | |
return 127 | |
fi | |
} | |
cd_plugins=${CI_DEPLOY_PLUGINS-} | |
info "Processing CI plugins: ${cd_plugins} ..." | |
if [ -n "$cd_plugins" ]; then | |
echo "$cd_plugins" | tr ',' '\n' | while read -r p; do | |
[ -z "$p" ] && continue | |
info ">>> stage of '$p'" | |
cmd=$(resolve_plugin "$p") | |
info "resolving plugin '$p' => '$cmd'" | |
if [ "$cmd" != "x${cmd}" ]; then | |
$cmd | |
echo | |
fi | |
done | |
else | |
info "CD plugin list is empty." | |
fi | |
__CD_MAIN__ | |
echo $name | |
} | |
git_describe () { | |
# strip serial num | |
git describe --tags "$1" 2>/dev/null | awk '{sub(/-[0-9]+-g.{7,}/,"");print}' | |
} | |
# | |
# Automate get the build tag and release_tag | |
# | |
get_release_tag () { | |
local ref_id="$1" | |
local tag=${CI_BUILD_TAG:-"$(git_describe "$ref_id")"} | |
local suffix="${CI_BUILD_TAG_SUFFIX:-}" | |
# auto detect tag name | |
if [ -z "${CI_BUILD_TAG:-}" ]; then | |
if [[ "${CI_BUILD_REF_NAME}" =~ ^[0-9]+(.[0-9]+)*.[0-9x]+ ]]; then | |
tag=${CI_BUILD_REF_NAME} | |
elif [ "${bump_file}" ]; then | |
# fix closure tag name by bump_file | |
bump_tag=$(git show "${ref_id}:${bump_file}" | awk -F'"' '/"version": ".+"/{print $4;exit;}') || exit $? | |
if printf %s "$tag" | grep -Eqv '^v?[0-9]' || | |
printf '%s\n%s\n' "$tag" "$bump_tag" | sort -V -C; then | |
tag=$bump_tag | |
fi | |
suffix=${suffix:--preview} | |
fi | |
fi | |
printf '%s' "${tag}${suffix:+${suffix}}" | |
} | |
build_dist_tar () { | |
local in="${1?input dir invalid}" | |
local of=${2?output file invalid} | |
if [ -f yarn.lock ]; then | |
gzip -c yarn.lock > "${in}/yarn.lock.gz" | |
fi | |
# Build tar with optional prefix | |
# NOT use tar --transform because BSD compatible issue | |
(if [ "$dist_tar_prefix" ]; then | |
abs_in=$(cd "$in"; pwd) | |
cd "$WORKDIR" | |
dirname=$(dirname "$dist_tar_prefix") | |
if [ "$dirname" != "." ]; then | |
mkdir -p "$dirname" | |
fi | |
ln -sf "$abs_in" "$dist_tar_prefix" \ | |
&& tar -chzf "$of" "$dist_tar_prefix" \ | |
&& rm -rf "$dist_tar_prefix" | |
else | |
tar -C "$in" -czf "$of" . | |
fi) | |
} | |
build_tag=$(get_release_tag "$ref_id") | |
assert "$build_tag" "detect tag failed" | |
ref_tag="${build_tag}.${short_refid}" | |
echo "$ref_tag" > "$dest_dir/.version" | |
# Prepare build stuffs & ENVS | |
# build tarball of the dest directory `dist` | |
build_dist_tar "$dest_dir" "$WORKDIR/dist.tgz" | |
# patch key env vars | |
export CI_PROJECT_NAME="${CI_PROJECT_NAME:-$proj_name}" | |
export CI_PROJECT_RELEASE_TAG="$build_tag" | |
export CI_BUILD_VERSION="$ref_tag" | |
export CI_BUILD_SPECS_DIR="${CI_BUILD_SPECS_DIR:-${def_ci_specs_dir}}" # relative path | |
# lock the key env variables by specific patterns, | |
# for more variables @see https://docs.gitlab.com/ee/ci/variables/predefined_variables.html | |
env | | |
grep -E "^(CI_|CD_).*=" | | |
grep -Ev "^(CI_BUILD_TOKEN|CI_PROJECT_DIR|CI_BUILD_REPO|CI_SERVER)" | | |
awk -F= '{print $1}' | | |
sort | | |
xargs -r -I{} sh -c "typeset -p {} | sed 's#^declare -x ##'" > "$WORKDIR/env" | |
# sync ci specs dir (is relative to current workdir, eg, .ci) | |
ci_specs_home="${CI_BUILD_SPECS_DIR%/}" | |
if [ -d "$ci_specs_home" ]; then | |
cp -af "$ci_specs_home" "$WORKDIR/" | |
fi | |
# Add default rpc commands based on ci specs. (.ci/deploy.sh) | |
if [ -z "$deploy_cmd" ] && [ "${CI_DEPLOY-}" != "false" ]; then | |
drpc_sh="$ci_specs_home/deploy.sh" | |
# add builtin dispatcher based on CD plugins | |
if [ ! -f "$drpc_sh" ]; then | |
drpc_sh="$(cd "$WORKDIR" && gen_cd_main)" | |
echo "Preparing deploy context ... done!" | |
fi | |
deploy_cmd="if [ -f \"$drpc_sh\" ]; then sh \"$drpc_sh\"; fi" | |
fi | |
# Export and inject context variables for remote commands | |
ARGS+=('-e "^(CI|CD).*="') | |
ARGS+=("$(printf -- '--command %q' "$deploy_cmd")") | |
if [ "${CI_DEBUG_TRACE:-}" = "true" ]; then | |
ARGS+=('-v') | |
fi | |
eval set -- "${ARGS[@]}" | |
spush -s "${WORKDIR}" -t "/var/ci_build/${proj_name}/${ref_name}/${short_refid}" "$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment