Skip to content

Commit

Permalink
feat: Implement build artifact creation script for GitLab CI
Browse files Browse the repository at this point in the history
Signed-off-by: 林博仁(Buo-ren Lin) <Buo.Ren.Lin@gmail.com>
  • Loading branch information
brlin-tw committed Oct 15, 2023
1 parent 0518539 commit 3473926
Show file tree
Hide file tree
Showing 3 changed files with 283 additions and 2 deletions.
6 changes: 4 additions & 2 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@ static-analysis:

generate-build-artifacts:
stage: deploy
image: ubuntu:22.04
artifacts:
paths:
- '*'
- ${CI_PROJECT_NAME}-*.tar*
script:
- "printf 'Info: Generating build artifacts...'"
- ./continuous-integration/generate-build-artifacts.install-system-deps.sh
- ./continuous-integration/generate-build-artifacts.sh
200 changes: 200 additions & 0 deletions continuous-integration/generate-build-artifacts.install-system-deps.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
#!/usr/bin/env bash
# Install system dependencies required for generating the project
# build artifacts
#
# Copyright 2023 林博仁(Buo-ren, Lin) <buo.ren.lin@gmail.com>
# SPDX-License-Identifier: CC-BY-SA-4.0

set \
-o errexit \
-o errtrace \
-o nounset

required_commands=(
realpath
)
flag_dependency_check_failed=false
for required_command in "${required_commands[@]}"; do
if ! command -v "${required_command}" >/dev/null; then
flag_dependency_check_failed=true
printf \
'Error: Unable to locate the "%s" command in the command search PATHs.\n' \
"${required_command}" \
1>&2
fi
done
if test "${flag_dependency_check_failed}" == true; then
printf \
'Error: Dependency check failed, please check your installation.\n' \
1>&2
fi

if test -v BASH_SOURCE; then
# Convenience variables
# shellcheck disable=SC2034
{
script="$(
realpath \
--strip \
"${BASH_SOURCE[0]}"
)"
script_dir="${script%/*}"
script_filename="${script##*/}"
script_name="${script_filename%%.*}"
}
fi

if test "${EUID}" -ne 0; then
printf \
'Error: This program should be run as the superuser(root) user.\n' \
1>&2
exit 1
fi

apt_archive_cache_mtime_epoch="$(
stat \
--format=%Y \
/var/cache/apt/archives
)"
current_time_epoch="$(
date +%s
)"
if test "$((current_time_epoch - apt_archive_cache_mtime_epoch))" -ge 86400; then
printf \
'Info: Refreshing the APT local package cache...\n'
if ! apt-get update; then
printf \
'Error: Unable to refresh the APT local package cache.\n' \
1>&2
fi
fi

# Silence warnings regarding unavailable debconf frontends
export DEBIAN_FRONTEND=noninteractive

if ! test -v CI; then
base_runtime_dependency_pkgs=(
curl
grep
sed
)
if ! dpkg -s "${base_runtime_dependency_pkgs[@]}" &>/dev/null; then
printf \
'Info: Installing base runtime dependency packages...\n'
if ! \
apt-get install \
-y \
"${base_runtime_dependency_pkgs[@]}"; then
printf \
'Error: Unable to install the base runtime dependency packages.\n' \
1>&2
exit 2
fi
fi

printf \
'Info: Detecting local region code...\n'
curl_opts=(
# Don't output debug messages
--silent
--show-error
)
if ip_reverse_lookup_service_response="$(
curl \
"${curl_opts[@]}" \
https://ipinfo.io/json
)"; then
grep_opts=(
--perl-regexp
--only-matching
)
if ! region_code="$(
grep \
"${grep_opts[@]}" \
'(?<="country": ")[[:alpha:]]+' \
<<<"${ip_reverse_lookup_service_response}"
)"; then
printf \
'Warning: Unable to query the local region code, falling back to default.\n' \
1>&2
region_code=
else
printf \
'Info: Local region code determined to be "%s"\n' \
"${region_code}"
fi
else
printf \
'Warning: Unable to detect the local region code(IP address reverse lookup service not available), falling back to default.\n' \
1>&2
region_code=
fi

if test -n "${region_code}"; then
# The returned region code is capitalized, fixing it.
region_code="${region_code,,*}"

printf \
'Info: Checking whether the local Ubuntu archive mirror exists...\n'
if ! \
getent hosts \
"${region_code}.archive.ubuntu.com" \
>/dev/null; then
printf \
"Warning: The local Ubuntu archive mirror doesn't seem to exist, falling back to default...\\n"
region_code=
fi
fi

if test -n "${region_code}" \
&& ! grep -q "${region_code}.archive.u" /etc/apt/sources.list; then
printf \
'Info: Switching to use the local APT software repository mirror...\n'
if ! \
sed \
--in-place \
"s@//archive.u@//${region_code}.archive.u@g" \
/etc/apt/sources.list; then
printf \
'Error: Unable to switch to use the local APT software repository mirror.\n' \
1>&2
exit 2
fi

printf \
'Info: Refreshing the local APT software archive cache...\n'
if ! apt-get update; then
printf \
'Error: Unable to refresh the local APT software archive cache.\n' \
1>&2
exit 2
fi
fi
fi

runtime_dependency_pkgs=(
# project archive compression dependencies
#bzip2
gzip
#xz

git

python3-minimal
python3-pip
python3-venv
)
if ! dpkg -s "${runtime_dependency_pkgs[@]}" &>/dev/null; then
printf \
'Info: Installing the runtime dependency packages...\n'
if ! apt-get install -y \
"${runtime_dependency_pkgs[@]}"; then
printf \
'Error: Unable to install the runtime dependency packages.\n' \
1>&2
exit 2
fi
fi

printf \
'Info: Operation completed without errors.\n'
79 changes: 79 additions & 0 deletions continuous-integration/generate-build-artifacts.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#!/usr/bin/env bash
# Generate the project build artifacts
#
# Copyright 2023 林博仁(Buo-ren, Lin) <buo.ren.lin@gmail.com>
# SPDX-License-Identifier: CC-BY-SA-4.0
set \
-o errexit \
-o nounset

if ! test -e "${script_dir}/venv"; then
printf \
'Info: Initializing the Python virtual environment...\n'
if ! python3 -m venv "${script_dir}/venv"; then
printf \
'Error: Unable to initialize the Python virtual environment.\n' \
1>&2
exit 2
fi
fi

printf \
'Info: Activating the Python virtual environment...\n'
# Out of scope
# shellcheck source=/dev/null
if ! source "${script_dir}/venv/bin/activate"; then
printf \
'Error: Unable to activate the Python virtual environment.\n' \
1>&2
exit 2
fi

printf \
'Info: Installing git-archive-all...\n'
if ! pip show git-archive-all &>/dev/null; then
if ! pip install git-archive-all; then
printf \
'Error: Unable to install git-archive-all.\n' \
1>&2
exit 2
fi
fi

printf \
'Info: Determining the project version...\n'
git_describe_opts=(
--always
--dirty
--tags
)
if ! project_version="$(
git describe \
"${git_describe_opts[@]}"
)"; then
printf \
'Error: Unable to determine the project version.\n' \
1>&2
exit 2
fi

printf \
'Info: Generating the project archive...\n'
project_id="${CI_ENVIRONMENT_NAME}-${project_version}"
git_archive_all_opts=(
# Add an additional layer of folder for containing the archive
# contents
--prefix="${project_id}/"
)
if ! \
git-archive-all \
"${git_archive_all_opts[@]}" \
"${project_id}.tar.gz"; then
printf \
'Error: Unable to generate the project archive.\n' \
1>&2
exit 2
fi

printf \
'Info: Operation completed without errors.\n'

0 comments on commit 3473926

Please sign in to comment.