name: Cascade FROM bump description: | Bump a `FROM :` line in a target repo's Dockerfile to trigger that repo's CI. Used when a base image rebuild needs to cascade rebuilds in downstream image repos. inputs: target-repo: description: Target repo to edit (e.g. fritzlab/runner) required: true image: description: Image referenced in the target file's FROM line (e.g. code.fritzlab.net/fritzlab/base) required: true tag: description: New tag. Defaults to github.run_number when empty. required: false default: '' file: description: File path inside target-repo to edit required: false default: Dockerfile token: description: CI_BOT_TOKEN with write access to target-repo required: true host: description: Gitea host (without protocol) required: false default: code.fritzlab.net message: description: Commit message override. Defaults to "bump to #". required: false default: '' runs: using: composite steps: - name: Clone, edit, push shell: bash env: TARGET_REPO: ${{ inputs.target-repo }} IMAGE: ${{ inputs.image }} TAG_INPUT: ${{ inputs.tag }} FILE: ${{ inputs.file }} TOKEN: ${{ inputs.token }} HOST: ${{ inputs.host }} MESSAGE: ${{ inputs.message }} RUN_NUMBER: ${{ github.run_number }} run: | set -euo pipefail TAG="${TAG_INPUT:-$RUN_NUMBER}" NAME="$(basename "$IMAGE")" MSG="${MESSAGE:-bump ${NAME} to #${TAG}}" WORK="$(mktemp -d)" trap 'rm -rf "$WORK"' EXIT git clone --depth 1 "https://ci-bot:${TOKEN}@${HOST}/${TARGET_REPO}.git" "$WORK" cd "$WORK" git config user.name ci-bot git config user.email ci-bot@fritzlab.net if [ ! -f "$FILE" ]; then echo "FATAL: ${FILE} not found in ${TARGET_REPO}" exit 1 fi # Escape forward slashes for sed pattern ESC_IMAGE="${IMAGE//\//\\/}" sed -i "s|^FROM ${IMAGE}:.*|FROM ${IMAGE}:${TAG}|" "$FILE" if ! grep -q "^FROM ${IMAGE}:${TAG}\b" "$FILE"; then echo "FATAL: sed did not match a FROM line for ${IMAGE} in ${FILE}" grep "^FROM" "$FILE" || true exit 1 fi if git diff --quiet; then echo "${TARGET_REPO} already on ${NAME}:${TAG}, skipping" exit 0 fi git add "$FILE" git commit -m "$MSG" ATTEMPTS=0 until git push origin main; do ATTEMPTS=$((ATTEMPTS + 1)) if [ "$ATTEMPTS" -ge 3 ]; then echo "FATAL: push to ${TARGET_REPO} failed after ${ATTEMPTS} attempts" exit 1 fi echo "push rejected, attempt ${ATTEMPTS}; rebasing and retrying" git pull --rebase origin main sleep $((ATTEMPTS * 2)) done echo "cascaded ${NAME}:${TAG} → ${TARGET_REPO}"