Enhance release workflow and add local testing script for registry images
Build and Test / verify (push) Successful in 33s
Build and Test / verify (push) Successful in 33s
- Update release.yaml to publish :latest and :prerelease-tag for stable and pre-release tags respectively. - Add README section for local testing of registry images with a new script. - Introduce scripts/test-registry-image.sh for end-to-end testing of published images.
This commit is contained in:
@@ -48,18 +48,20 @@ jobs:
|
|||||||
|
|
||||||
# Note: This repository only builds and pushes images.
|
# Note: This repository only builds and pushes images.
|
||||||
# FluxCD Image Automation in another repository performs deployment.
|
# FluxCD Image Automation in another repository performs deployment.
|
||||||
# Stable tags (vX.Y.Z) may become :latest. Pre-release tags never do.
|
# Stable tags (vX.Y.Z) also publish :latest.
|
||||||
if [[ "$TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
# Pre-release tags (e.g. vX.Y.Z-rc1) also publish :prerelease-tag.
|
||||||
|
if printf '%s' "$TAG" | grep -Eq '^v[0-9]+\.[0-9]+\.[0-9]+$'; then
|
||||||
docker buildx build \
|
docker buildx build \
|
||||||
--platform linux/amd64 \
|
--platform linux/amd64 \
|
||||||
--push \
|
--push \
|
||||||
--tag $REGISTRY/$IMAGE_NAME:$TAG \
|
--tag "$REGISTRY/$IMAGE_NAME:$TAG" \
|
||||||
--tag $REGISTRY/$IMAGE_NAME:latest \
|
--tag "$REGISTRY/$IMAGE_NAME:latest" \
|
||||||
.
|
.
|
||||||
else
|
else
|
||||||
docker buildx build \
|
docker buildx build \
|
||||||
--platform linux/amd64 \
|
--platform linux/amd64 \
|
||||||
--push \
|
--push \
|
||||||
--tag $REGISTRY/$IMAGE_NAME:$TAG \
|
--tag "$REGISTRY/$IMAGE_NAME:$TAG" \
|
||||||
|
--tag "$REGISTRY/$IMAGE_NAME:prerelease-tag" \
|
||||||
.
|
.
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -157,6 +157,47 @@ docker run --rm -p 8080:8080 \
|
|||||||
gitea-mcp-auth-proxy:dev
|
gitea-mcp-auth-proxy:dev
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Registry-Image lokal testen
|
||||||
|
|
||||||
|
Fuer einen End-to-End-Test gegen die veroeffentlichte Gitea-Container-Registry gibt es das Script `scripts/test-registry-image.sh`.
|
||||||
|
|
||||||
|
Es orientiert sich am Gitea-Flow aus der Container-Registry-Doku:
|
||||||
|
|
||||||
|
- Login gegen `gitea.nehmer.net`
|
||||||
|
- Pull von `gitea.nehmer.net/torben/gitea-mcp-auth-proxy:<tag>`
|
||||||
|
- lokaler Start des gezogenen Images mit den eingecheckten Demo-Hashes
|
||||||
|
- HTTP-Pruefungen fuer `200` und `401`
|
||||||
|
|
||||||
|
Default-Verhalten:
|
||||||
|
|
||||||
|
- User: `torben`
|
||||||
|
- Tag: `latest`
|
||||||
|
- Runtime: automatisch `docker`, sonst `podman`
|
||||||
|
|
||||||
|
Der Registry-Login fragt das Passwort oder einen PAT interaktiv und unsichtbar ab.
|
||||||
|
|
||||||
|
Beispiel:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./scripts/test-registry-image.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Bestimmten Tag testen:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./scripts/test-registry-image.sh --tag v1.2.3
|
||||||
|
```
|
||||||
|
|
||||||
|
Optional auf vorhandene Image-Labels pruefen:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./scripts/test-registry-image.sh \
|
||||||
|
--require-label org.opencontainers.image.source \
|
||||||
|
--require-label org.opencontainers.image.title=gitea-mcp-auth-proxy
|
||||||
|
```
|
||||||
|
|
||||||
|
Hinweis: Das Script validiert optionale Labels erst nach dem Pull. Aktuell definiert dieses Repo selbst noch keine OCI-Image-Labels im Build.
|
||||||
|
|
||||||
## CI/CD (Gitea Actions)
|
## CI/CD (Gitea Actions)
|
||||||
|
|
||||||
- Build-Workflow: `.gitea/workflows/build.yaml`
|
- Build-Workflow: `.gitea/workflows/build.yaml`
|
||||||
|
|||||||
Executable
+206
@@ -0,0 +1,206 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
REGISTRY_HOST="gitea.nehmer.net"
|
||||||
|
OWNER="torben"
|
||||||
|
IMAGE_NAME="gitea-mcp-auth-proxy"
|
||||||
|
TAG="latest"
|
||||||
|
USERNAME="torben"
|
||||||
|
RUNTIME=""
|
||||||
|
REQUIRED_LABELS=()
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<'EOF'
|
||||||
|
Usage: scripts/test-registry-image.sh [options]
|
||||||
|
|
||||||
|
Pulls the published container image from the Gitea registry, starts it locally
|
||||||
|
with the committed demo hashes, and verifies expected HTTP responses.
|
||||||
|
|
||||||
|
Options:
|
||||||
|
--tag <tag> Image tag to test (default: latest)
|
||||||
|
--runtime <docker|podman> Container runtime to use (auto-detect by default)
|
||||||
|
--username <user> Registry username (default: torben)
|
||||||
|
--require-label <key> Require image label to exist
|
||||||
|
--require-label <k=v> Require image label to equal a specific value
|
||||||
|
-h, --help Show this help
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
scripts/test-registry-image.sh
|
||||||
|
scripts/test-registry-image.sh --tag v1.2.3
|
||||||
|
scripts/test-registry-image.sh --require-label org.opencontainers.image.source
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case "$1" in
|
||||||
|
--tag)
|
||||||
|
TAG="${2:-}"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
--runtime)
|
||||||
|
RUNTIME="${2:-}"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
--username)
|
||||||
|
USERNAME="${2:-}"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
--require-label)
|
||||||
|
REQUIRED_LABELS+=("${2:-}")
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
-h|--help)
|
||||||
|
usage
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Unknown argument: $1" >&2
|
||||||
|
usage >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ -z "$TAG" ]]; then
|
||||||
|
echo "Tag must not be empty" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "$RUNTIME" ]]; then
|
||||||
|
if command -v docker >/dev/null 2>&1; then
|
||||||
|
RUNTIME="docker"
|
||||||
|
elif command -v podman >/dev/null 2>&1; then
|
||||||
|
RUNTIME="podman"
|
||||||
|
else
|
||||||
|
echo "Neither docker nor podman is available" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! command -v "$RUNTIME" >/dev/null 2>&1; then
|
||||||
|
echo "Container runtime not found: $RUNTIME" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! command -v curl >/dev/null 2>&1; then
|
||||||
|
echo "curl is required" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
repo_root="$(cd "$script_dir/.." && pwd)"
|
||||||
|
hash_dir="$repo_root/demo/token-hashes"
|
||||||
|
|
||||||
|
if [[ ! -d "$hash_dir" ]]; then
|
||||||
|
echo "Demo hash directory not found: $hash_dir" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
image_ref="$REGISTRY_HOST/$OWNER/$IMAGE_NAME:$TAG"
|
||||||
|
container_name="authproxy-registry-test-$$"
|
||||||
|
container_id=""
|
||||||
|
host_port=""
|
||||||
|
|
||||||
|
cleanup() {
|
||||||
|
local exit_code=$?
|
||||||
|
if [[ -n "$container_id" ]]; then
|
||||||
|
"$RUNTIME" rm -f "$container_id" >/dev/null 2>&1 || true
|
||||||
|
fi
|
||||||
|
exit "$exit_code"
|
||||||
|
}
|
||||||
|
trap cleanup EXIT
|
||||||
|
|
||||||
|
printf 'Registry password for %s@%s: ' "$USERNAME" "$REGISTRY_HOST" >&2
|
||||||
|
stty -echo
|
||||||
|
IFS= read -r registry_password
|
||||||
|
stty echo
|
||||||
|
printf '\n' >&2
|
||||||
|
|
||||||
|
if [[ -z "$registry_password" ]]; then
|
||||||
|
echo "Empty password/token is not allowed" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf '%s' "$registry_password" | "$RUNTIME" login "$REGISTRY_HOST" --username "$USERNAME" --password-stdin >/dev/null
|
||||||
|
unset registry_password
|
||||||
|
|
||||||
|
echo "Pulling $image_ref"
|
||||||
|
"$RUNTIME" pull "$image_ref" >/dev/null
|
||||||
|
|
||||||
|
for required_label in "${REQUIRED_LABELS[@]}"; do
|
||||||
|
label_key="$required_label"
|
||||||
|
label_expected=""
|
||||||
|
if [[ "$required_label" == *=* ]]; then
|
||||||
|
label_key="${required_label%%=*}"
|
||||||
|
label_expected="${required_label#*=}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
label_value="$("$RUNTIME" image inspect "$image_ref" --format "{{ index .Config.Labels \"$label_key\" }}" 2>/dev/null || true)"
|
||||||
|
if [[ -z "$label_value" || "$label_value" == "<no value>" ]]; then
|
||||||
|
echo "Required image label missing: $label_key" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [[ -n "$label_expected" && "$label_value" != "$label_expected" ]]; then
|
||||||
|
echo "Image label mismatch for $label_key: expected $label_expected, got $label_value" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "Starting container from $image_ref"
|
||||||
|
container_id="$($RUNTIME run -d \
|
||||||
|
--name "$container_name" \
|
||||||
|
-p 127.0.0.1::8080 \
|
||||||
|
-e AUTH_PROXY_LISTEN_ADDR=:8080 \
|
||||||
|
-e AUTH_PROXY_TOKEN_HASHES_DIR=/token-hashes \
|
||||||
|
-e AUTH_PROXY_LOG_LEVEL=debug \
|
||||||
|
-v "$hash_dir:/token-hashes:ro" \
|
||||||
|
"$image_ref")"
|
||||||
|
|
||||||
|
host_port="$($RUNTIME port "$container_id" 8080/tcp | awk -F: 'NR==1 {print $NF}')"
|
||||||
|
if [[ -z "$host_port" ]]; then
|
||||||
|
echo "Failed to determine mapped host port" >&2
|
||||||
|
"$RUNTIME" logs "$container_id" >&2 || true
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
base_url="http://127.0.0.1:$host_port"
|
||||||
|
|
||||||
|
wait_for_health() {
|
||||||
|
local attempt http_code
|
||||||
|
for attempt in $(seq 1 30); do
|
||||||
|
http_code="$(curl -s -o /dev/null -w '%{http_code}' "$base_url/healthz" || true)"
|
||||||
|
if [[ "$http_code" == "200" ]]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_status() {
|
||||||
|
local expected=$1
|
||||||
|
local description=$2
|
||||||
|
shift 2
|
||||||
|
local http_code
|
||||||
|
http_code="$(curl -s -o /dev/null -w '%{http_code}' "$@")"
|
||||||
|
if [[ "$http_code" != "$expected" ]]; then
|
||||||
|
echo "FAIL: $description expected $expected, got $http_code" >&2
|
||||||
|
"$RUNTIME" logs "$container_id" >&2 || true
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "OK: $description -> $http_code"
|
||||||
|
}
|
||||||
|
|
||||||
|
if ! wait_for_health; then
|
||||||
|
echo "Container did not become healthy: $image_ref" >&2
|
||||||
|
"$RUNTIME" logs "$container_id" >&2 || true
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
assert_status 200 "healthz" "$base_url/healthz"
|
||||||
|
assert_status 401 "missing token" "$base_url/"
|
||||||
|
assert_status 401 "wrong token" -H "Authorization: Bearer wrong" "$base_url/"
|
||||||
|
assert_status 200 "demo-token-1" -H "Authorization: Bearer demo-token-1" "$base_url/"
|
||||||
|
|
||||||
|
echo "Registry image test succeeded: $image_ref"
|
||||||
Reference in New Issue
Block a user