88 lines
2.8 KiB
YAML
88 lines
2.8 KiB
YAML
|
|
name: Deploy Image (kustomize image-pin in apps repo)
|
||
|
|
description: |
|
||
|
|
Pin an image tag in fritzlab/apps via `kustomize edit set image`, validate the
|
||
|
|
rendered manifests, and push to apps-repo main. Retries on push conflict.
|
||
|
|
inputs:
|
||
|
|
image:
|
||
|
|
description: Full image name without tag (must match an entry in the target kustomization.yaml `images:` block)
|
||
|
|
required: true
|
||
|
|
tag:
|
||
|
|
description: Tag to pin. Defaults to github.run_number when empty.
|
||
|
|
required: false
|
||
|
|
default: ''
|
||
|
|
path:
|
||
|
|
description: Path inside fritzlab/apps to the manifests dir (e.g. sjc001/infra/chrony/manifests)
|
||
|
|
required: true
|
||
|
|
token:
|
||
|
|
description: CI_BOT_TOKEN with write access to fritzlab/apps
|
||
|
|
required: true
|
||
|
|
apps-repo:
|
||
|
|
description: Apps repo URL (without protocol)
|
||
|
|
required: false
|
||
|
|
default: code.fritzlab.net/fritzlab/apps
|
||
|
|
message:
|
||
|
|
description: Commit message. Defaults to "deploy <name> #<tag>".
|
||
|
|
required: false
|
||
|
|
default: ''
|
||
|
|
runs:
|
||
|
|
using: composite
|
||
|
|
steps:
|
||
|
|
- name: Pin image and push
|
||
|
|
shell: bash
|
||
|
|
env:
|
||
|
|
IMAGE: ${{ inputs.image }}
|
||
|
|
TAG_INPUT: ${{ inputs.tag }}
|
||
|
|
PATH_IN_REPO: ${{ inputs.path }}
|
||
|
|
TOKEN: ${{ inputs.token }}
|
||
|
|
APPS_REPO: ${{ inputs.apps-repo }}
|
||
|
|
MESSAGE: ${{ inputs.message }}
|
||
|
|
RUN_NUMBER: ${{ github.run_number }}
|
||
|
|
run: |
|
||
|
|
set -euo pipefail
|
||
|
|
|
||
|
|
TAG="${TAG_INPUT:-$RUN_NUMBER}"
|
||
|
|
NAME="$(basename "$IMAGE")"
|
||
|
|
MSG="${MESSAGE:-deploy ${NAME} #${TAG}}"
|
||
|
|
|
||
|
|
WORK="$(mktemp -d)"
|
||
|
|
trap 'rm -rf "$WORK"' EXIT
|
||
|
|
|
||
|
|
git clone --depth 1 "https://ci-bot:${TOKEN}@${APPS_REPO}.git" "$WORK"
|
||
|
|
cd "$WORK"
|
||
|
|
git config user.name ci-bot
|
||
|
|
git config user.email ci-bot@fritzlab.net
|
||
|
|
|
||
|
|
cd "$PATH_IN_REPO"
|
||
|
|
kustomize edit set image "${IMAGE}=${IMAGE}:${TAG}"
|
||
|
|
|
||
|
|
# Validate the kustomization renders cleanly before we push.
|
||
|
|
if ! kustomize build . > /dev/null; then
|
||
|
|
echo "FATAL: kustomize build failed after image pin"
|
||
|
|
git --no-pager diff
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
if git -C "$WORK" diff --quiet; then
|
||
|
|
echo "apps repo already on ${NAME}:${TAG}, skipping"
|
||
|
|
exit 0
|
||
|
|
fi
|
||
|
|
|
||
|
|
git -C "$WORK" add "${PATH_IN_REPO}/kustomization.yaml"
|
||
|
|
git -C "$WORK" commit -m "$MSG"
|
||
|
|
|
||
|
|
# Push with rebase-on-conflict retry: concurrent CI from another image
|
||
|
|
# repo could have pushed since our clone.
|
||
|
|
ATTEMPTS=0
|
||
|
|
until git -C "$WORK" push origin main; do
|
||
|
|
ATTEMPTS=$((ATTEMPTS + 1))
|
||
|
|
if [ "$ATTEMPTS" -ge 3 ]; then
|
||
|
|
echo "FATAL: push to apps repo failed after ${ATTEMPTS} attempts"
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
echo "push rejected, attempt ${ATTEMPTS}; rebasing and retrying"
|
||
|
|
git -C "$WORK" pull --rebase origin main
|
||
|
|
sleep $((ATTEMPTS * 2))
|
||
|
|
done
|
||
|
|
|
||
|
|
echo "deployed ${NAME}:${TAG}"
|