Initial: flux-deploy composite action for K8s GitOps deployments

This commit is contained in:
2026-06-16 23:46:32 -07:00
commit c11d34400e
2 changed files with 172 additions and 0 deletions
+100
View File
@@ -0,0 +1,100 @@
name: Flux GitOps Deploy
description: Update a Flux HelmRelease image tag in a GitOps repo to trigger a Kubernetes deployment
author: eric
inputs:
image-repository:
description: Full image repository (e.g. git.ericxliu.me/eric/workout)
required: true
image-tag:
description: Image tag to deploy (e.g. 2026-06-17-abc1234)
required: true
gitops-repo:
description: SSH URL of the GitOps repo
default: git@github.com:eric-x-liu/k8s-flux.git
required: false
gitops-file:
description: Path to the release YAML in the GitOps repo (e.g. apps/myapp/workout/release.yaml)
required: true
deploy-key:
description: SSH private key with push access to the GitOps repo
required: true
git-user-name:
description: Git commit author name
default: gitops-ci
required: false
git-user-email:
description: Git commit author email
default: gitops-ci@users.noreply.git.ericxliu.me
required: false
commit-message:
description: "Custom commit message. Supports {app} and {tag} placeholders."
default: ""
required: false
runs:
using: composite
steps:
- name: Update GitOps image tag
shell: bash
env:
IMAGE_REPOSITORY: ${{ inputs.image-repository }}
IMAGE_TAG: ${{ inputs.image-tag }}
GITOPS_REPO: ${{ inputs.gitops-repo }}
GITOPS_FILE: ${{ inputs.gitops-file }}
DEPLOY_KEY: ${{ inputs.deploy-key }}
GIT_USER_NAME: ${{ inputs.git-user-name }}
GIT_USER_EMAIL: ${{ inputs.git-user-email }}
COMMIT_MESSAGE: ${{ inputs.commit-message }}
run: |
set -euo pipefail
# ── SSH setup ──────────────────────────────────────────────
mkdir -p "$HOME/.ssh"
printf '%s\n' "$DEPLOY_KEY" > "$HOME/.ssh/flux_deploy_key"
chmod 600 "$HOME/.ssh/flux_deploy_key"
ssh-keyscan -H github.com >> "$HOME/.ssh/known_hosts" 2>/dev/null
export GIT_SSH_COMMAND="ssh -i $HOME/.ssh/flux_deploy_key -o IdentitiesOnly=yes -o StrictHostKeyChecking=yes"
# ── Clone GitOps repo ──────────────────────────────────────
workdir="$(mktemp -d)"
git clone "$GITOPS_REPO" "$workdir/gitops"
cd "$workdir/gitops"
# ── Update image repository + tag via regex ────────────────
python3 -c '
import os, pathlib, re
path = pathlib.Path(os.environ["GITOPS_FILE"])
repo = os.environ["IMAGE_REPOSITORY"]
tag = os.environ["IMAGE_TAG"]
text = path.read_text()
text = re.sub(r"(repository:\s*)\S+", lambda m: m.group(1) + repo, text, count=1)
text = re.sub(r"(tag:\s*)\S+", lambda m: m.group(1) + tag, text, count=1)
path.write_text(text)
'
# ── Commit + push (idempotent) ────────────────────────────
if git diff --quiet -- "$GITOPS_FILE"; then
echo "✅ GitOps already points to $IMAGE_REPOSITORY:$IMAGE_TAG — nothing to do"
exit 0
fi
# Derive app name from the gitops file path for the default commit message
APP_NAME="$(basename "$(dirname "$GITOPS_FILE")")"
if [ -z "$COMMIT_MESSAGE" ]; then
COMMIT_MESSAGE="Update ${APP_NAME} image to ${IMAGE_TAG}"
else
COMMIT_MESSAGE="${COMMIT_MESSAGE//\{app\}/$APP_NAME}"
COMMIT_MESSAGE="${COMMIT_MESSAGE//\{tag\}/$IMAGE_TAG}"
fi
git config user.name "$GIT_USER_NAME"
git config user.email "$GIT_USER_EMAIL"
git add "$GITOPS_FILE"
git commit -m "$COMMIT_MESSAGE"
git push origin main
echo "🚀 Pushed: $IMAGE_REPOSITORY:$IMAGE_TAG → $GITOPS_FILE"