♻️ refactor(ci): use fixed workflow slots
This commit is contained in:
@@ -1,207 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
workspace_fail() {
|
||||
echo "bootstrap_workspace.sh: $*" >&2
|
||||
return 1
|
||||
}
|
||||
|
||||
split_repository_slug() {
|
||||
local repo_slug=$1
|
||||
local owner repo_name
|
||||
|
||||
if [[ "${repo_slug}" != */* ]]; then
|
||||
workspace_fail "repository slug must look like owner/repo: ${repo_slug}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
owner=${repo_slug%%/*}
|
||||
repo_name=${repo_slug#*/}
|
||||
|
||||
printf '%s\n%s\n' "${owner}" "${repo_name}"
|
||||
}
|
||||
|
||||
sanitize_job_name() {
|
||||
local value=${1:-job}
|
||||
|
||||
value=$(printf '%s' "${value}" | tr ' /:@' '-----')
|
||||
value=$(printf '%s' "${value}" | tr -cd '[:alnum:]._-')
|
||||
value=$(printf '%s' "${value}" | sed -E 's/-+/-/g; s/^-//; s/-$//')
|
||||
|
||||
if [ -z "${value}" ]; then
|
||||
value="job"
|
||||
fi
|
||||
|
||||
printf '%s\n' "${value}"
|
||||
}
|
||||
|
||||
build_job_identity() {
|
||||
local run_id=${1:-0}
|
||||
local run_attempt=${2:-1}
|
||||
local job_name=${3:-job}
|
||||
|
||||
printf '%s-%s-%s\n' "${run_id}" "${run_attempt}" "${job_name}"
|
||||
}
|
||||
|
||||
build_mirror_path() {
|
||||
local mirror_root=$1
|
||||
local owner=$2
|
||||
local repo_name=$3
|
||||
|
||||
printf '%s/%s/%s.git\n' "${mirror_root}" "${owner}" "${repo_name}"
|
||||
}
|
||||
|
||||
build_job_workspace_root() {
|
||||
local workspace_root=$1
|
||||
local owner=$2
|
||||
local repo_name=$3
|
||||
local job_identity=$4
|
||||
|
||||
printf '%s/%s/%s/%s\n' "${workspace_root}" "${owner}" "${repo_name}" "${job_identity}"
|
||||
}
|
||||
|
||||
build_job_repo_dir() {
|
||||
local workspace_root=$1
|
||||
local owner=$2
|
||||
local repo_name=$3
|
||||
local job_identity=$4
|
||||
|
||||
printf '%s/repo\n' "$(build_job_workspace_root "${workspace_root}" "${owner}" "${repo_name}" "${job_identity}")"
|
||||
}
|
||||
|
||||
with_repo_lock() {
|
||||
local lock_path=$1
|
||||
shift
|
||||
|
||||
mkdir -p "$(dirname "${lock_path}")"
|
||||
|
||||
if ! command -v flock >/dev/null 2>&1; then
|
||||
workspace_fail "flock is required for mirror synchronization"
|
||||
return 1
|
||||
fi
|
||||
|
||||
exec {lock_fd}>"${lock_path}"
|
||||
flock "${lock_fd}"
|
||||
"$@"
|
||||
local status=$?
|
||||
flock -u "${lock_fd}"
|
||||
eval "exec ${lock_fd}>&-"
|
||||
|
||||
return "${status}"
|
||||
}
|
||||
|
||||
ensure_bare_mirror_unlocked() {
|
||||
local remote_url=$1
|
||||
local mirror_path=$2
|
||||
|
||||
mkdir -p "$(dirname "${mirror_path}")"
|
||||
|
||||
if [ -d "${mirror_path}" ]; then
|
||||
git -C "${mirror_path}" remote set-url origin "${remote_url}"
|
||||
git -C "${mirror_path}" fetch --prune --prune-tags --tags origin
|
||||
else
|
||||
git clone --mirror "${remote_url}" "${mirror_path}" >/dev/null
|
||||
fi
|
||||
}
|
||||
|
||||
ensure_bare_mirror() {
|
||||
local remote_url=$1
|
||||
local mirror_path=$2
|
||||
local lock_path
|
||||
|
||||
lock_path="${mirror_path}.lock"
|
||||
with_repo_lock "${lock_path}" ensure_bare_mirror_unlocked "${remote_url}" "${mirror_path}"
|
||||
}
|
||||
|
||||
create_job_workspace_from_mirror() {
|
||||
local remote_url=$1
|
||||
local mirror_path=$2
|
||||
local job_workspace=$3
|
||||
local repo_dir=$4
|
||||
|
||||
rm -rf "${job_workspace}"
|
||||
mkdir -p "${job_workspace}"
|
||||
git clone --shared "${mirror_path}" "${repo_dir}" >/dev/null
|
||||
git -C "${repo_dir}" remote set-url origin "${remote_url}"
|
||||
}
|
||||
|
||||
cleanup_job_workspace() {
|
||||
local job_workspace=$1
|
||||
|
||||
if [ -z "${job_workspace}" ] || [ "${job_workspace}" = "/" ]; then
|
||||
workspace_fail "refusing to remove invalid workspace path: ${job_workspace}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
rm -rf "${job_workspace}"
|
||||
}
|
||||
|
||||
prepare_job_workspace() {
|
||||
local repo_slug=$1
|
||||
local remote_url=$2
|
||||
local mirror_root=$3
|
||||
local workspace_root=$4
|
||||
local run_id=$5
|
||||
local run_attempt=${6:-1}
|
||||
local job_name=${7:-job}
|
||||
local owner repo_name safe_job_name job_identity mirror_path job_workspace repo_dir
|
||||
local slug_parts
|
||||
|
||||
mapfile -t slug_parts < <(split_repository_slug "${repo_slug}")
|
||||
owner=${slug_parts[0]}
|
||||
repo_name=${slug_parts[1]}
|
||||
safe_job_name=$(sanitize_job_name "${job_name}")
|
||||
job_identity=$(build_job_identity "${run_id}" "${run_attempt}" "${safe_job_name}")
|
||||
mirror_path=$(build_mirror_path "${mirror_root}" "${owner}" "${repo_name}")
|
||||
job_workspace=$(build_job_workspace_root "${workspace_root}" "${owner}" "${repo_name}" "${job_identity}")
|
||||
repo_dir=$(build_job_repo_dir "${workspace_root}" "${owner}" "${repo_name}" "${job_identity}")
|
||||
|
||||
ensure_bare_mirror "${remote_url}" "${mirror_path}"
|
||||
create_job_workspace_from_mirror "${remote_url}" "${mirror_path}" "${job_workspace}" "${repo_dir}"
|
||||
|
||||
printf 'REPO_OWNER=%s\n' "${owner}"
|
||||
printf 'REPO_NAME=%s\n' "${repo_name}"
|
||||
printf 'JOB_IDENTITY=%s\n' "${job_identity}"
|
||||
printf 'MIRROR_PATH=%s\n' "${mirror_path}"
|
||||
printf 'JOB_WORKSPACE=%s\n' "${job_workspace}"
|
||||
printf 'REPO_DIR=%s\n' "${repo_dir}"
|
||||
}
|
||||
|
||||
print_usage() {
|
||||
cat <<'EOF'
|
||||
Usage:
|
||||
bootstrap_workspace.sh prepare-job-workspace <repo-slug> <remote-url> <mirror-root> <workspace-root> <run-id> <run-attempt> <job-name>
|
||||
bootstrap_workspace.sh cleanup-job-workspace <job-workspace>
|
||||
EOF
|
||||
}
|
||||
|
||||
main() {
|
||||
local command=${1:-}
|
||||
|
||||
case "${command}" in
|
||||
prepare-job-workspace)
|
||||
[ $# -eq 8 ] || {
|
||||
print_usage
|
||||
return 1
|
||||
}
|
||||
shift
|
||||
prepare_job_workspace "$@"
|
||||
;;
|
||||
cleanup-job-workspace)
|
||||
[ $# -eq 2 ] || {
|
||||
print_usage
|
||||
return 1
|
||||
}
|
||||
shift
|
||||
cleanup_job_workspace "$1"
|
||||
;;
|
||||
*)
|
||||
print_usage
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
||||
set -euo pipefail
|
||||
main "$@"
|
||||
fi
|
||||
Reference in New Issue
Block a user