Add Gitea build, container tests and registry publication
All checks were successful
Build, test and publish / verify (push) Successful in 1m41s
All checks were successful
Build, test and publish / verify (push) Successful in 1m41s
This commit is contained in:
76
ci/publish.sh
Normal file
76
ci/publish.sh
Normal file
@@ -0,0 +1,76 @@
|
||||
#!/usr/bin/env bash
|
||||
source "$(dirname -- "$0")/common.sh"
|
||||
# Also enforce this inside the script, independently of the workflow expression.
|
||||
[[ "${CI_REF:-}" == refs/heads/main ]] || { echo 'Branch is not main; no publication'; exit 0; }
|
||||
[[ -f "$ARTIFACTS/verified-commit" && "$(cat "$ARTIFACTS/verified-commit")" == "$CI_COMMIT" ]] || {
|
||||
echo 'This commit has not passed all verification steps' >&2; exit 1;
|
||||
}
|
||||
: "${REGISTRY_USER:?Missing REGISTRY_USER secret}"
|
||||
: "${REGISTRY_TOKEN:?Missing REGISTRY_TOKEN secret}"
|
||||
: "${GITEA_SERVER_URL:?Missing Gitea server URL}"
|
||||
: "${CI_REPOSITORY:?Missing repository}"
|
||||
require_platform
|
||||
exec > >(tee "$ARTIFACTS/publish.log") 2>&1
|
||||
REGISTRY=${GITEA_SERVER_URL#http://}
|
||||
REGISTRY=${REGISTRY#https://}
|
||||
REGISTRY=${REGISTRY%/}
|
||||
[[ "$REGISTRY" != */* ]] || { echo 'Registry must be hosted at the Gitea server root'; exit 1; }
|
||||
OWNER=${CI_REPOSITORY%%/*}
|
||||
OWNER=${OWNER,,}
|
||||
[[ "$OWNER" =~ ^[a-z0-9][a-z0-9_.-]*$ ]] || { echo 'Invalid registry namespace'; exit 1; }
|
||||
# Gitea 1.25 ignores workflow concurrency. All publications on the sole runner
|
||||
# share this lock, outside checkout directories and across workflow attempts.
|
||||
lock_dir=${CI_PUBLISH_LOCK_DIR:-${XDG_STATE_HOME:-$HOME/.local/state}/agiledancers-ci}
|
||||
mkdir -p "$lock_dir"
|
||||
exec 9>"$lock_dir/publish.lock"
|
||||
flock -w 600 9
|
||||
# Preserve the selected daemon and isolate credentials from the developer's config.
|
||||
isolate_docker_config
|
||||
trap 'rm -rf -- "$DOCKER_CONFIG"' EXIT
|
||||
trap 'exit 143' TERM
|
||||
trap 'exit 130' INT
|
||||
printf '%s' "$REGISTRY_TOKEN" | docker login "$REGISTRY" --username "$REGISTRY_USER" --password-stdin
|
||||
|
||||
ensure_commit_image() {
|
||||
local role=$1 source=$2 repository="$REGISTRY/$OWNER/agiledancers-$1" ref error
|
||||
ref="$repository:$CI_COMMIT"
|
||||
error=$(mktemp)
|
||||
if docker manifest inspect --insecure "$ref" > /dev/null 2>"$error"; then
|
||||
echo "Preserving existing $ref"
|
||||
elif grep -Eqi 'manifest unknown|no such manifest' "$error"; then
|
||||
docker tag "$source" "$ref"
|
||||
docker push "$ref"
|
||||
else
|
||||
# Authentication/network/server errors are never treated as missing tags.
|
||||
cat "$error" >&2
|
||||
rm -f "$error"
|
||||
return 1
|
||||
fi
|
||||
rm -f "$error"
|
||||
docker pull --platform "$TARGET_PLATFORM" "$ref"
|
||||
[[ "$(docker image inspect --format '{{index .Config.Labels "org.opencontainers.image.revision"}}' "$ref")" == "$CI_COMMIT" ]] || {
|
||||
echo "Existing $role image has an unexpected source revision" >&2; return 1;
|
||||
}
|
||||
docker image inspect --format '{{range .RepoDigests}}{{println .}}{{end}}' "$ref" \
|
||||
> "$ARTIFACTS/$role-digests.txt"
|
||||
grep -Fq "$repository@sha256:" "$ARTIFACTS/$role-digests.txt" || { echo 'Missing registry digest'; return 1; }
|
||||
}
|
||||
ensure_commit_image backend "$BACKEND_IMAGE"
|
||||
ensure_commit_image frontend "$FRONTEND_IMAGE"
|
||||
# Both immutable images are now pull-verified. Only current main may move aliases.
|
||||
head=$(python3 ci/main-head.py)
|
||||
if [[ "$head" != "$CI_COMMIT" ]]; then
|
||||
echo 'A newer main commit exists; leaving moving tags unchanged.'
|
||||
exit 0
|
||||
fi
|
||||
for role in backend frontend; do
|
||||
repository="$REGISTRY/$OWNER/agiledancers-$role"
|
||||
# Recheck under the publication lock before each moving-tag write.
|
||||
[[ "$(python3 ci/main-head.py)" == "$CI_COMMIT" ]] || {
|
||||
echo 'Main advanced during publication; leaving remaining moving tags unchanged.'
|
||||
exit 0
|
||||
}
|
||||
docker tag "$repository:$CI_COMMIT" "$repository:main"
|
||||
docker push "$repository:main"
|
||||
docker pull --platform "$TARGET_PLATFORM" "$repository:main"
|
||||
done
|
||||
Reference in New Issue
Block a user