#!/bin/bash set -euo pipefail SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) REPO_ROOT=$(cd "${SCRIPT_DIR}/.." && pwd) # shellcheck source=/dev/null source "${REPO_ROOT}/.gitea/ci/bootstrap_workspace.sh" assert_eq() { local expected=$1 local actual=$2 local message=$3 if [ "${expected}" != "${actual}" ]; then echo "FAIL: ${message}" >&2 echo " expected: ${expected}" >&2 echo " actual: ${actual}" >&2 exit 1 fi } test_repo_path_layout() { local owner repo_name mirror_dir workspace_root mirror_path workspace_root_path repo_dir owner="csh" repo_name="actions-template" mirror_dir="/data/git-mirrors" workspace_root="/home/workspace/jobs" mirror_path=$(build_mirror_path "${mirror_dir}" "${owner}" "${repo_name}") workspace_root_path=$(build_job_workspace_root "${workspace_root}" "${owner}" "${repo_name}" "123456-1-release") repo_dir=$(build_job_repo_dir "${workspace_root}" "${owner}" "${repo_name}" "123456-1-release") assert_eq "/data/git-mirrors/csh/actions-template.git" "${mirror_path}" "mirror path should include owner and bare repo suffix" assert_eq "/home/workspace/jobs/csh/actions-template/123456-1-release" "${workspace_root_path}" "workspace root should include owner repo and job identity" assert_eq "/home/workspace/jobs/csh/actions-template/123456-1-release/repo" "${repo_dir}" "repo dir should live under isolated workspace root" } test_job_identity_prefers_run_metadata() { local actual actual=$(build_job_identity "123456" "2" "release-job") assert_eq "123456-2-release-job" "${actual}" "job identity should include run id attempt and job name" } test_sanitize_job_name() { local actual actual=$(sanitize_job_name "release notes/job") assert_eq "release-notes-job" "${actual}" "job names should be filesystem-safe" } test_build_lock_path() { local actual actual=$(build_mirror_lock_path "/data/git-mirrors" "csh" "actions-template") assert_eq "/data/git-mirrors/csh/actions-template.git.lock" "${actual}" "lock path should sit beside the bare mirror" } test_repo_owner_and_name_parsing() { local actual actual=$(split_repository_slug "csh/actions-template") assert_eq $'csh\nactions-template' "${actual}" "repository slug should split into owner and repo lines" } test_prepare_and_cleanup_workspace() { local temp_root remote_repo seed_repo mirror_root workspace_root env_file local repo_dir mirror_path job_workspace origin_url alternates_file alternates_target temp_root=$(mktemp -d) remote_repo="${temp_root}/remote.git" seed_repo="${temp_root}/seed" mirror_root="${temp_root}/mirrors" workspace_root="${temp_root}/jobs" env_file="${temp_root}/prepared.env" git init -b main "${seed_repo}" >/dev/null git -C "${seed_repo}" config user.name "Test User" git -C "${seed_repo}" config user.email "test@example.com" printf 'hello\n' > "${seed_repo}/README.md" git -C "${seed_repo}" add README.md git -C "${seed_repo}" commit -m "Initial commit" >/dev/null git clone --bare "${seed_repo}" "${remote_repo}" >/dev/null prepare_job_workspace \ "csh/actions-template" \ "${remote_repo}" \ "${mirror_root}" \ "${workspace_root}" \ "123456" \ "2" \ "release job" > "${env_file}" # shellcheck source=/dev/null source "${env_file}" repo_dir="${REPO_DIR}" mirror_path="${MIRROR_PATH}" job_workspace="${JOB_WORKSPACE}" if [ ! -d "${mirror_path}" ]; then echo "FAIL: mirror path should exist after preparation" >&2 exit 1 fi if [ ! -d "${repo_dir}/.git" ]; then echo "FAIL: prepared repo dir should contain a git checkout" >&2 exit 1 fi origin_url=$(git -C "${repo_dir}" remote get-url origin) assert_eq "${remote_repo}" "${origin_url}" "prepared repo should point origin to the requested remote" alternates_file="${repo_dir}/.git/objects/info/alternates" if [ ! -f "${alternates_file}" ]; then echo "FAIL: prepared repo should use shared mirror objects via alternates" >&2 exit 1 fi alternates_target=$(cat "${alternates_file}") assert_eq "${mirror_path}/objects" "${alternates_target}" "prepared repo should borrow objects from the bare mirror" cleanup_job_workspace "${job_workspace}" if [ -e "${job_workspace}" ]; then echo "FAIL: cleanup should remove the job workspace" >&2 exit 1 fi rm -rf "${temp_root}" } test_register_default_capacity_is_four() { if ! grep -q "config\['runner'\]\['capacity'\] = 4" "${REPO_ROOT}/docker-runner/common/register.sh"; then echo "FAIL: register.sh should default new runner capacity to 4" >&2 exit 1 fi } test_changelog_workflow_uses_workspace_helper() { if ! grep -q ".gitea/ci/bootstrap_workspace.sh" "${REPO_ROOT}/.gitea/workflows/changelog_and_release.yml"; then echo "FAIL: changelog workflow should fetch repo-owned bootstrap helper" >&2 exit 1 fi } test_stats_workflow_uses_workspace_helper() { if ! grep -q ".gitea/ci/bootstrap_workspace.sh" "${REPO_ROOT}/.gitea/workflows/update_stats_badge.yaml"; then echo "FAIL: stats workflow should fetch repo-owned bootstrap helper" >&2 exit 1 fi } test_presets_do_not_mount_workspace_helper() { if rg -q "workspace\.sh:/data/workspace\.sh" "${REPO_ROOT}/docker-runner/presets"; then echo "FAIL: preset compose files should not mount workspace helper from runner common" >&2 exit 1 fi } test_docs_mention_git_mirrors() { if ! grep -q "/data/git-mirrors" "${REPO_ROOT}/DEPLOYMENT.md"; then echo "FAIL: deployment docs should describe persistent git mirrors" >&2 exit 1 fi } test_repo_path_layout test_job_identity_prefers_run_metadata test_sanitize_job_name test_build_lock_path test_repo_owner_and_name_parsing test_prepare_and_cleanup_workspace test_register_default_capacity_is_four test_changelog_workflow_uses_workspace_helper test_stats_workflow_uses_workspace_helper test_presets_do_not_mount_workspace_helper test_docs_mention_git_mirrors echo "workspace_helper_test.sh: PASS"