Files
plex-playlist/.gitea/workflows/cicd-base.yml
copilotcoder b1be02c4f5
Some checks failed
CICD Base Image / Registry Push Preflight (pull_request) Successful in 19s
Tests / Registry Push Preflight (pull_request) Successful in 19s
Tests / Prepare CICD Base Reference (pull_request) Failing after 10m7s
CICD Base Image / Build and Publish CICD Base Image (pull_request) Failing after 10m16s
Tests / Build and Push CICD Complete Image (pull_request) Has been cancelled
Tests / Trailing Whitespace Check (pull_request) Has been cancelled
Tests / End of File Check (pull_request) Has been cancelled
Tests / YAML Syntax Check (pull_request) Has been cancelled
Tests / TOML Syntax Check (pull_request) Has been cancelled
Tests / Mixed Line Ending Check (pull_request) Has been cancelled
Tests / TOML Formatting Check (pull_request) Has been cancelled
Tests / Ruff Linting (pull_request) Has been cancelled
Tests / Ruff Format Check (pull_request) Has been cancelled
Tests / Pyright Type Check (pull_request) Has been cancelled
Tests / Darglint Docstring Check (pull_request) Has been cancelled
Tests / No Docstring Types Check (pull_request) Has been cancelled
Tests / ESLint Check (pull_request) Has been cancelled
Tests / Prettier Format Check (pull_request) Has been cancelled
Tests / TypeScript Type Check (pull_request) Has been cancelled
Tests / TSDoc Lint Check (pull_request) Has been cancelled
Tests / Backend Tests (pull_request) Has been cancelled
Tests / Frontend Tests (pull_request) Has been cancelled
Tests / Backend Doctests (pull_request) Has been cancelled
Tests / Integration Tests (pull_request) Has been cancelled
Tests / End-to-End Tests (pull_request) Has been cancelled
Getting a separation of concerns in place for the CICD
Signed-off-by: copilotcoder <copilotcoder@darkhelm.org>
2026-05-26 16:30:56 -04:00

306 lines
11 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
name: CICD Base Image
on:
push:
branches: [ main, develop, feature/* ]
paths:
- Dockerfile.cicd-base
- .dockerignore
- scripts/compute-cicd-base-hash.sh
- .gitea/workflows/cicd-base.yml
pull_request:
branches: [ main, develop ]
paths:
- Dockerfile.cicd-base
- .dockerignore
- scripts/compute-cicd-base-hash.sh
- .gitea/workflows/cicd-base.yml
workflow_dispatch:
inputs:
force_rebuild:
description: Force a rebuild even when the immutable base tag already exists
required: false
default: "false"
env:
GITEA_SSH_HOST: kankali.darkhelm.lan
GITEA_SSH_PORT: "2222"
GITEA_REPO_SSH_URL: ssh://git@kankali.darkhelm.lan:2222/DarkHelm.org/plex-playlist.git
GITEA_REGISTRY: kankali.darkhelm.lan:3001
GITEA_REGISTRY_IP: 10.18.75.2
GITEA_REGISTRY_HOST: kankali.darkhelm.lan
jobs:
registry-preflight:
name: Registry Push Preflight
runs-on: ubuntu-act-8gb
steps:
- &write_registry_push_helpers
name: Write registry push helpers
run: |
cat > /tmp/registry-push-helpers.sh <<'EOF'
#!/bin/bash
ensure_skopeo() {
if command -v skopeo >/dev/null 2>&1; then
return 0
fi
if command -v apt-get >/dev/null 2>&1; then
apt-get update && apt-get install -y skopeo
elif command -v apk >/dev/null 2>&1; then
apk add --no-cache skopeo
fi
if ! command -v skopeo >/dev/null 2>&1; then
echo "❌ skopeo not available for fallback push"
return 1
fi
}
push_ref_with_fallback() {
ref="$1"
local_image="$2"
archive_path="$3"
registry_user="$4"
package_access_token="$5"
for i in 1 2 3; do
echo "Docker push attempt ${i}/3 for ${ref}..."
if docker push "${ref}"; then
echo "✓ Docker push succeeded for ${ref}"
return 0
fi
if [ "${i}" -lt 3 ]; then
sleep 10
fi
done
echo "⚠ Docker push failed for ${ref}; trying skopeo fallback"
if ! ensure_skopeo; then
return 1
fi
if [ ! -f "${archive_path}" ]; then
echo "Creating local image archive for fallback push..."
if ! docker save "${local_image}" -o "${archive_path}"; then
echo "❌ Failed to create docker archive for fallback push"
return 1
fi
fi
if skopeo copy \
--dest-creds "${registry_user}:${package_access_token}" \
--dest-tls-verify=false \
"docker-archive:${archive_path}" \
"docker://${ref}"; then
echo "✓ Skopeo fallback push succeeded for ${ref}"
return 0
fi
echo "❌ Skopeo fallback push failed for ${ref}"
return 1
}
EOF
chmod 700 /tmp/registry-push-helpers.sh
- name: Verify registry login and minimal push
env:
PACKAGE_ACCESS_TOKEN: ${{ secrets.PACKAGE_ACCESS_TOKEN }}
REGISTRY_USER: ${{ secrets.REGISTRY_USER || github.actor }}
GITHUB_SHA: ${{ github.sha }}
run: |
echo "=== Registry Push Preflight ==="
if ! grep -q "${GITEA_REGISTRY_HOST}" /etc/hosts; then
echo "${GITEA_REGISTRY_IP} ${GITEA_REGISTRY_HOST}" >> /etc/hosts
fi
if ! echo "${PACKAGE_ACCESS_TOKEN}" | docker login "http://${GITEA_REGISTRY}" -u "${REGISTRY_USER}" --password-stdin; then
echo "❌ Registry login failed during preflight"
exit 1
fi
PREFLIGHT_TAG="${GITHUB_SHA:-manual}"
PREFLIGHT_REF="${GITEA_REGISTRY}/darkhelm.org/plex-playlist-ci-preflight:${PREFLIGHT_TAG}"
cat <<'EOF' > /tmp/Dockerfile.preflight
FROM scratch
LABEL org.opencontainers.image.title="plex-playlist registry preflight"
LABEL org.opencontainers.image.description="Minimal image used to verify registry push access before expensive CI steps"
EOF
if ! docker build -f /tmp/Dockerfile.preflight -t registry-preflight:latest /tmp; then
echo "❌ Failed to build minimal preflight image"
exit 1
fi
docker tag registry-preflight:latest "${PREFLIGHT_REF}"
ARCHIVE_PATH="/tmp/registry-preflight.tar"
source /tmp/registry-push-helpers.sh
if push_ref_with_fallback "${PREFLIGHT_REF}" "registry-preflight:latest" "${ARCHIVE_PATH}" "${REGISTRY_USER}" "${PACKAGE_ACCESS_TOKEN}"; then
echo "✓ Registry preflight push succeeded: ${PREFLIGHT_REF}"
else
echo "❌ Registry preflight push failed: ${PREFLIGHT_REF}"
exit 1
fi
publish-base:
name: Build and Publish CICD Base Image
runs-on: ubuntu-act-8gb
needs: registry-preflight
steps:
- name: Minimal checkout for base inputs
env:
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
GITHUB_SHA: ${{ github.sha }}
run: |
umask 077
trap 'rm -f ~/.ssh/id_rsa' EXIT
echo "=== Minimal Repository Checkout for Base Inputs ==="
if ! grep -q "${GITEA_REGISTRY_HOST}" /etc/hosts; then
echo "${GITEA_REGISTRY_IP} ${GITEA_REGISTRY_HOST}" >> /etc/hosts
fi
if [ -n "${SSH_PRIVATE_KEY}" ]; then
mkdir -p ~/.ssh
echo "${SSH_PRIVATE_KEY}" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
echo "Loaded SSH key fingerprint: $(ssh-keygen -lf ~/.ssh/id_rsa | awk '{print $2}')"
ssh-keyscan -p "${GITEA_SSH_PORT}" "${GITEA_SSH_HOST}" >> ~/.ssh/known_hosts 2>/dev/null
else
echo "❌ SSH_PRIVATE_KEY is empty"
exit 1
fi
GIT_SSH_COMMAND="ssh -i ~/.ssh/id_rsa -o IdentitiesOnly=yes -o StrictHostKeyChecking=no" \
git clone --depth 1 --no-checkout \
"${GITEA_REPO_SSH_URL}" .
if [ -n "${GITHUB_SHA}" ] && \
GIT_SSH_COMMAND="ssh -i ~/.ssh/id_rsa -o IdentitiesOnly=yes -o StrictHostKeyChecking=no" \
git fetch --depth 1 origin "${GITHUB_SHA}" >/dev/null 2>&1; then
git checkout FETCH_HEAD -- Dockerfile.cicd-base .dockerignore scripts/compute-cicd-base-hash.sh
echo "✓ Checked out base inputs from commit ${GITHUB_SHA}"
else
git checkout HEAD -- Dockerfile.cicd-base .dockerignore scripts/compute-cicd-base-hash.sh
echo "⚠ Falling back to default branch HEAD for base inputs checkout"
fi
chmod +x scripts/compute-cicd-base-hash.sh
rm -f ~/.ssh/id_rsa
- name: Compute base hash and inspect registry
id: base-state
env:
PACKAGE_ACCESS_TOKEN: ${{ secrets.PACKAGE_ACCESS_TOKEN }}
REGISTRY_USER: ${{ secrets.REGISTRY_USER || github.actor }}
FORCE_REBUILD: ${{ github.event.inputs.force_rebuild || 'false' }}
run: |
echo "=== Computing CICD Base Image Hash ==="
BASE_HASH=$(./scripts/compute-cicd-base-hash.sh)
BASE_REF_HASH="${GITEA_REGISTRY}/darkhelm.org/plex-playlist-cicd-base:${BASE_HASH}"
BASE_REF_LATEST="${GITEA_REGISTRY}/darkhelm.org/plex-playlist-cicd-base:latest"
echo "Base hash: ${BASE_HASH}"
echo "base_hash=${BASE_HASH}" >> $GITHUB_OUTPUT
echo "base_ref_hash=${BASE_REF_HASH}" >> $GITHUB_OUTPUT
echo "base_ref_latest=${BASE_REF_LATEST}" >> $GITHUB_OUTPUT
if ! grep -q "${GITEA_REGISTRY_HOST}" /etc/hosts; then
echo "${GITEA_REGISTRY_IP} ${GITEA_REGISTRY_HOST}" >> /etc/hosts
fi
if ! echo "${PACKAGE_ACCESS_TOKEN}" | docker login "http://${GITEA_REGISTRY}" -u "${REGISTRY_USER}" --password-stdin >/dev/null 2>&1; then
echo "❌ Registry login failed during base inspection"
exit 1
fi
if [ "${FORCE_REBUILD}" = "true" ]; then
echo "Manual force rebuild requested"
echo "needs_build=true" >> $GITHUB_OUTPUT
exit 0
fi
if timeout 30 docker manifest inspect "${BASE_REF_HASH}" >/dev/null 2>&1; then
echo "✓ Immutable base image already exists: ${BASE_REF_HASH}"
echo "needs_build=false" >> $GITHUB_OUTPUT
else
echo " Immutable base image missing: ${BASE_REF_HASH}"
echo "needs_build=true" >> $GITHUB_OUTPUT
fi
- *write_registry_push_helpers
- name: Build and push base image
if: steps.base-state.outputs.needs_build == 'true'
env:
PACKAGE_ACCESS_TOKEN: ${{ secrets.PACKAGE_ACCESS_TOKEN }}
REGISTRY_USER: ${{ secrets.REGISTRY_USER || github.actor }}
BASE_HASH: ${{ steps.base-state.outputs.base_hash }}
BASE_REF_HASH: ${{ steps.base-state.outputs.base_ref_hash }}
BASE_REF_LATEST: ${{ steps.base-state.outputs.base_ref_latest }}
run: |
echo "=== Building CICD Base Image ==="
if ! grep -q "${GITEA_REGISTRY_HOST}" /etc/hosts; then
echo "${GITEA_REGISTRY_IP} ${GITEA_REGISTRY_HOST}" >> /etc/hosts
fi
export DOCKER_BUILDKIT=1
docker build -f Dockerfile.cicd-base \
--build-arg BASE_IMAGE_VERSION="v1.0.0-${BASE_HASH}" \
-t cicd-base:latest .
ARCHIVE_PATH="/tmp/cicd-base.tar"
source /tmp/registry-push-helpers.sh
echo "${PACKAGE_ACCESS_TOKEN}" | docker login "http://${GITEA_REGISTRY}" -u "${REGISTRY_USER}" --password-stdin
docker tag cicd-base:latest "${BASE_REF_HASH}"
docker tag cicd-base:latest "${BASE_REF_LATEST}"
push_ref_with_fallback "${BASE_REF_HASH}" "cicd-base:latest" "${ARCHIVE_PATH}" "${REGISTRY_USER}" "${PACKAGE_ACCESS_TOKEN}"
push_ref_with_fallback "${BASE_REF_LATEST}" "cicd-base:latest" "${ARCHIVE_PATH}" "${REGISTRY_USER}" "${PACKAGE_ACCESS_TOKEN}"
- name: Verify published base image
env:
PACKAGE_ACCESS_TOKEN: ${{ secrets.PACKAGE_ACCESS_TOKEN }}
REGISTRY_USER: ${{ secrets.REGISTRY_USER || github.actor }}
BASE_REF_HASH: ${{ steps.base-state.outputs.base_ref_hash }}
run: |
echo "=== Verifying Published CICD Base Image ==="
if ! grep -q "${GITEA_REGISTRY_HOST}" /etc/hosts; then
echo "${GITEA_REGISTRY_IP} ${GITEA_REGISTRY_HOST}" >> /etc/hosts
fi
echo "${PACKAGE_ACCESS_TOKEN}" | docker login "http://${GITEA_REGISTRY}" -u "${REGISTRY_USER}" --password-stdin >/dev/null 2>&1
for i in 1 2 3 4 5 6; do
echo "Verification attempt ${i}/6 for ${BASE_REF_HASH}..."
if timeout 30 docker manifest inspect "${BASE_REF_HASH}" >/dev/null 2>&1 && \
timeout 60 docker pull "${BASE_REF_HASH}" >/dev/null 2>&1; then
echo "✓ Published base image verified: ${BASE_REF_HASH}"
exit 0
fi
if [ "${i}" -lt 6 ]; then
sleep 10
fi
done
echo "❌ Published base image could not be verified: ${BASE_REF_HASH}"
exit 1