Merge GitLab integration

# Conflicts:
#	CHANGELOG.md
#	Dockerfile
#	README.md
#	psu
This commit is contained in:
Tortue Torche
2019-12-04 15:23:08 +01:00
committed by Tortue Torche
parent edde3e86c7
commit aca3e69669
27 changed files with 1831 additions and 111 deletions

134
scripts/helpers.sh Normal file
View File

@ -0,0 +1,134 @@
#!/usr/bin/env bash
set -e
[[ "$TRACE" ]] && set -x
function registry_login() {
if [[ -n "$CI_REGISTRY_USER" ]]; then
echo "Logging to GitLab Container Registry with CI credentials..."
docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY"
echo ""
fi
}
function external_registry_login() {
if [[ -n "$DOCKER_USER" ]]; then
echo "Logging to External Registry..."
docker login -u "$DOCKER_USER" -p "$DOCKER_PASSWORD" "$DOCKER_REGISTRY"
echo ""
fi
}
function setup_docker() {
if ! docker info &>/dev/null; then
if [ -z "$DOCKER_HOST" -a "$KUBERNETES_PORT" ]; then
export DOCKER_HOST='tcp://localhost:2375'
fi
fi
}
function git_tag_on_success() {
local git_tag="${1:-dev}"
local target_branch="${2:-master}"
if (
[ "$CI_COMMIT_REF_NAME" == "$target_branch" ] &&
[ -n "$GITLAB_API_TOKEN" ] &&
[ -z "$GIT_RESET_TAG" ]
); then
# (re)write Protected Tag
# TODO: rewrite these 'wget' commands with 'curl' commands
wget -Y off -O response.txt --header='Accept-Charset: UTF-8' --header "PRIVATE-TOKEN: $GITLAB_API_TOKEN" --post-data '_method=delete' $CI_API_V4_URL/projects/$CI_PROJECT_ID/protected_tags/$git_tag || true
wget -Y off -O response.txt --header='Accept-Charset: UTF-8' --header "PRIVATE-TOKEN: $GITLAB_API_TOKEN" --post-data '_method=delete' $CI_API_V4_URL/projects/$CI_PROJECT_ID/repository/tags/$git_tag || true
wget -Y off -O response.txt --header='Accept-Charset: UTF-8' --header "PRIVATE-TOKEN: $GITLAB_API_TOKEN" --post-data "tag_name=$git_tag&ref=$CI_COMMIT_SHA" $CI_API_V4_URL/projects/$CI_PROJECT_ID/repository/tags
wget -Y off -O response.txt --header='Accept-Charset: UTF-8' --header "PRIVATE-TOKEN: $GITLAB_API_TOKEN" --post-data "name=$git_tag&create_access_level=0" $CI_API_V4_URL/projects/$CI_PROJECT_ID/protected_tags
else
echo WARNING: \$GITLAB_API_TOKEN variable is missing
fi
}
function registry_tag_on_success() {
local current_registry_tag="${1:-$CI_COMMIT_SHA}"
local target_registry_tag="${2:-dev}"
local target_branch="${3:-master}"
local current_registry_image="${4:-$CI_REGISTRY_IMAGE/builds}"
local target_registry_image="${5:-$CI_REGISTRY_IMAGE}"
local target_external_registry_image="${6:-$DOCKER_REGISTRY_IMAGE}"
if [ "$CI_COMMIT_REF_NAME" == "$target_branch" ]; then
docker pull "$current_registry_image:$current_registry_tag"
docker tag "$current_registry_image:$current_registry_tag" "$target_registry_image:$target_registry_tag"
docker push "$target_registry_image:$target_registry_tag"
if [ -n "$target_external_registry_image" ]; then
docker tag "$current_registry_image:$current_registry_tag" "$target_external_registry_image:$target_registry_tag"
docker push "$target_external_registry_image:$target_registry_tag"
fi
fi
}
# Reset the git repository to the target tag
#
# First argument pass to this function or the `GIT_RESET_TAG` CI variable
# must be set
# git_reset_from_tag dev
# or:
# GIT_RESET_TAG=dev
# git_reset_from_tag
function git_reset_from_tag() {
local git_target_tag="${1:-$GIT_RESET_TAG}"
if (
[ "$CI_PIPELINE_SOURCE" == "schedule" ] &&
[ -n "$git_target_tag" ] && [ "$GIT_STRATEGY" != "none" ] &&
[ -z "$CI_COMMIT_TAG" ]
); then
# Get specific tag
git reset --hard $git_target_tag
export CI_COMMIT_SHA=$(git rev-parse HEAD)
export CI_COMMIT_SHORT_SHA=$(git rev-parse --short HEAD)
else
echo NOTICE: Not a Scheduling Pipeline, skip the git tag reset stuff... # debug
fi
}
# Get latest stable semantic versioning git tag
# from a specific git branch
#
# First argument pass to this function or the `CI_COMMIT_REF_NAME` CI variable
# must be set
# get_git_last_stable_tag 1-0-stable
# -> "v1.0.3"
# or:
# CI_COMMIT_REF_NAME=1-0-stable
# get_git_last_stable_tag
# -> "v1.0.3"
#
# see: https://semver.org
function get_git_last_stable_tag() {
local target_branch="${1:-$CI_COMMIT_REF_NAME}"
git fetch origin $target_branch
git checkout -f -q $target_branch
echo "$(git tag --merged $target_branch | grep -w '^v[0-9]\+\.[0-9]\+\.[0-9]\+$' | sort -r -V | head -n 1)"
}
# Useful for updating Docker images, on release/stable branches, but not the psu code
# See: https://docs.gitlab.com/ce/workflow/gitlab_flow.html#release-branches-with-gitlab-flow
# You can create a scheduled pipeline with a targeted git branch ("master", "1-0-stable", ...)
# and the CI variables below:
# "GIT_RESET_LAST_STABLE_TAG=true"
# "DOCKER_CACHE_DISABLED=true"
# "TEST_DISABLED=" # no value to unset this variable
# See: https://gitlab.com/help/user/project/pipelines/schedules
function git_reset_from_last_stable_tag() {
if [ "$GIT_RESET_LAST_STABLE_TAG" == "true" ]; then
git_last_stable_tag="$(get_git_last_stable_tag)"
if [ -n "$git_last_stable_tag" ]; then
export CI_COMMIT_REF_PROTECTED="true"
export CI_COMMIT_TAG="$git_last_stable_tag"
export GIT_RESET_TAG="$git_last_stable_tag"
git_reset_from_tag
else
echo WARNING: Last stable git tag not found
fi
fi
}

View File

@ -0,0 +1,63 @@
#!/usr/bin/env bash
# Usage:
# bash push-to-gitlab-pages.sh <target_branch_name> <path_to_push_in_the_branch>
# bash push-to-gitlab-pages.sh
# bash push-to-gitlab-pages.sh "gitlab-pages" "public"
set -e
[[ "$TRACE" ]] && set -x
if [ -z "$GITLAB_WRITE_REPO_USER" ] || [ -z "$GITLAB_WRITE_REPO_TOKEN" ]; then
echo "ERROR: \$GITLAB_WRITE_REPO_USER and/or \$GITLAB_WRITE_REPO_TOKEN CI variables must be set!"
exit 1
fi
current_path=$PWD
project_path=$CI_PROJECT_DIR
# GitLab Pages branch name
branch=${1:-gitlab-pages}
# Path of the folder to push in GitLab Pages branch
source_path=${2:-$project_path/public}
repository_path=$project_path/$branch
# Path of the files to publish in GitLab Pages
pages_path=$repository_path/public
repository_url_path=$(echo $CI_PROJECT_URL | sed -E 's/^https?:\/\/(.+)$/\1/')
repository_url_protocol=$(echo $CI_PROJECT_URL | sed -E 's/^(https?:\/\/).+$/\1/')
repository_user=$GITLAB_WRITE_REPO_USER
repository_password=$GITLAB_WRITE_REPO_TOKEN
repository_url=${repository_url_protocol}${repository_user}:${repository_password}@${repository_url_path}
last_commit_message=$(git log -1 -z --format="%s%n%ncommit %H%nAuthor: %an <%ae>%nDate: %ad" HEAD)
if ! $(git clone --quiet --branch=$branch --single-branch $repository_url $repository_path); then
# Create $branch if needed
git clone --quiet --depth=1 --single-branch $repository_url $repository_path
cd $repository_path
git config user.name "$repository_user"
git config user.email "${repository_user}@users.noreply.gitlab.com"
git checkout --orphan $branch
git rm --quiet -rf .
cp -pa $project_path/.gitlab-ci.yml .gitlab-ci.yml
echo "Git branch dedicated to [GitLab Pages](https://docs.gitlab.com/ce/user/project/pages/).
DO NOT EDIT THIS BRANCH BY HAND PLEASE" > README.md
git add README.md .gitlab-ci.yml
git commit -m "Git branch dedicated to GitLab Pages (https://docs.gitlab.com/ce/user/project/pages/)."
fi
cd $current_path
if [ -d $source_path ]; then
cp -Rpa $source_path/. $pages_path
cd $repository_path
git config user.name "$repository_user"
git config user.email "${repository_user}@users.noreply.gitlab.com"
# Update git '$branch' and push changes to the current repository
git add --all
git diff-index --quiet HEAD || git commit -m "$last_commit_message"
git push --quiet origin $branch | true
fi
cd $current_path

113
scripts/release.sh Normal file
View File

@ -0,0 +1,113 @@
#!/usr/bin/env bash
set -e
[[ "$TRACE" ]] && set -x
source "$(dirname "$0")/helpers.sh"
# First argument is the variant(s) of the Docker image to be tagged
# e.g. "core"
# or "core debian debian-core" for multiple variants
variant_input="$1"
# Split space (" ") character to new line "\n"
variants="$(echo "$variant_input" | tr ' ' '\n')"
if [ "$GIT_RESET_LAST_STABLE_TAG" != "true" ]; then
git_tag_on_success "dev"
registry_tag_on_success $CI_COMMIT_SHA "dev"
for variant in $variants; do
registry_tag_on_success "${variant}-${CI_COMMIT_SHA}" "dev-${variant}"
done
fi
# Write current git tag to the Docker registry
# if it starts with the 'v' character, followed by a number, e.g 'v1.0.2'
# see: https://semver.org
# You should set a 'v*' protected tags, in your GitLab project
# see: https://gitlab.com/help/user/project/protected_tags#configuring-protected-tags
if (
[[ "$CI_COMMIT_TAG" =~ ^v[0-9][0-9a-z.\-]*$ ]] &&
[ "$CI_COMMIT_REF_PROTECTED" == "true" ]
); then
# Remove the first letter ('v' character), for tagging Docker images
target_registry_tag="${CI_COMMIT_TAG:1}"
registry_tag_on_success $CI_COMMIT_SHA $target_registry_tag $CI_COMMIT_REF_NAME
for variant in $variants; do
registry_tag_on_success "${variant}-${CI_COMMIT_SHA}" "${target_registry_tag}-${variant}" $CI_COMMIT_REF_NAME
done
# If current git tag is a stable semantic version.
# see: https://semver.org
if [[ "$target_registry_tag" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
git fetch --all
# e.g. " origin/master"
master_branch="$(git branch --no-color --remotes --list 'origin/master')"
# e.g. " origin/1-0-stable
# > origin/1-1-stable
# > origin/2-0-stable
# > origin/master"
commit_in_branches="$(git branch --no-color --remotes --contains $CI_COMMIT_SHA | grep -w ' origin/master\| origin/.*-stable')"
# e.g. " origin/2-0-stable
# > origin/1-1-stable
# > origin/1-0-stable"
stable_branches="$(echo "$commit_in_branches" | grep -vw ' origin/master' | sort -rV)"
# Extract the MAJOR and MAJOR.MINOR versions
# Then tag and push them to Docker registry.
# e.g. the "v1.3.7" git tag, will create/update "1" and "1.3" registry tags
# For MAJOR tag on git stable branches, we use the latest stable branch
# e.g. when there is 2 stable branches "1-0-stable" and "1-1-stable"
# If there is a new minor git tag "v1.0.3", only on the "1-0-stable".
# We don't have to update the registry tag "1".
# Because only git tags on the "1-1-stable" git branch can do it.
major_registry_tag=$(echo $target_registry_tag | sed -E 's/^([0-9]+)\.[0-9]+\.[0-9]+$/\1/')
minor_registry_tag=$(echo $target_registry_tag | sed -E 's/^[0-9]+\.([0-9]+)\.[0-9]+$/\1/')
major_minor_registry_tag=$major_registry_tag.$minor_registry_tag
target_stable_branch="${major_registry_tag}-${minor_registry_tag}-stable"
# e.g. "1-1-stable"
latest_major_branch="$(echo "$stable_branches"| grep -E "^ origin/$major_registry_tag-[0-9]+-stable$" | head -n 1 | sed -E 's/^ origin\/(.+)$/\1/')"
# If the git tag is only contained in master branch
# or if it's contained in the latest stable branch who has the same MAJOR version
# e.g. when there is 2 stable branches "1-0-stable" and "1-1-stable".
# If git tag is "v1.0.1", the MAJOR registry tag "1" is NOT written.
# Because the lastet stable branch is "1-1-stable".
#
# If git tag is "v1.1.3", the MAJOR registry tag "1" is written.
# Because the lastet stable branch is "1-1-stable".
if (
([ -n "$master_branch" ] && [ "$master_branch" == "$commit_in_branches" ]) ||
[ "$latest_major_branch" == "$target_stable_branch" ]
); then
registry_tag_on_success $CI_COMMIT_SHA $major_registry_tag $CI_COMMIT_REF_NAME
fi
registry_tag_on_success $CI_COMMIT_SHA $major_minor_registry_tag $CI_COMMIT_REF_NAME
for variant in $variants; do
if (
([ -n "$master_branch" ] && [ "$master_branch" == "$commit_in_branches" ]) ||
[ "$latest_major_branch" == "$target_stable_branch" ]
); then
registry_tag_on_success "${variant}-${CI_COMMIT_SHA}" "${major_registry_tag}-${variant}" $CI_COMMIT_REF_NAME
fi
registry_tag_on_success "${variant}-${CI_COMMIT_SHA}" "${major_minor_registry_tag}-${variant}" $CI_COMMIT_REF_NAME
done
# The latest stable semantic versioning git tag on the "master" branch
# is considered as the "latest" registry tag.
# Check if the current git commit is only present in the "master" branch
# and not in stable branches (e.g. "1-0-stable").
# Non stable branches are skipped (e.g. "feature-better-performance").
if [ -n "$master_branch" ] && [ "$master_branch" == "$commit_in_branches" ]; then
registry_tag_on_success $CI_COMMIT_SHA "latest" $CI_COMMIT_REF_NAME
for variant in $variants; do
registry_tag_on_success "${variant}-${CI_COMMIT_SHA}" "${variant}" $CI_COMMIT_REF_NAME
done
fi
fi
fi

5
scripts/test.sh Normal file
View File

@ -0,0 +1,5 @@
#!/usr/bin/env bash
set -e
[[ "$TRACE" ]] && set -x
bash "$(dirname "$0")/../tests/run.sh"