All checks were successful
deploy / deploy (push) Successful in 26s
Proof: Follow-up push exercises the new label-driven release apply path so operator-dashboard no longer depends on the old PROJECT_DEPLOYMENTS rollout list. Assumptions: Forgejo Actions picks up workflow-definition changes on the next push if the current push was still handled by the prior workflow definition. Still fake: This commit exists only to force one more workflow run and should be unnecessary once the new deploy workflow has been proven live.
159 lines
6.3 KiB
YAML
159 lines
6.3 KiB
YAML
name: deploy
|
|
|
|
on:
|
|
push:
|
|
branches:
|
|
- main
|
|
workflow_dispatch:
|
|
|
|
jobs:
|
|
deploy:
|
|
runs-on: linux-amd64
|
|
env:
|
|
IMAGE_TAG: ${{ github.sha }}
|
|
REGISTRY_HOST: ${{ vars.REGISTRY_HOST }}
|
|
PROJECT_NAME: ${{ vars.PROJECT_NAME || 'unrip' }}
|
|
PROJECT_NAMESPACE: ${{ vars.PROJECT_NAMESPACE || vars.PROJECT_NAME || 'unrip' }}
|
|
PROJECT_REGISTRY_SECRET_NAME: ${{ vars.PROJECT_REGISTRY_SECRET_NAME || format('{0}-registry-creds', vars.PROJECT_NAME || 'unrip') }}
|
|
REPO_CLONE_URL: ${{ github.server_url }}/${{ github.repository }}.git
|
|
steps:
|
|
- name: Install tooling
|
|
run: |
|
|
if command -v git >/dev/null 2>&1 && command -v kubectl >/dev/null 2>&1 && command -v python3 >/dev/null 2>&1; then
|
|
exit 0
|
|
fi
|
|
|
|
if command -v apk >/dev/null 2>&1; then
|
|
apk add --no-cache git kubectl python3
|
|
exit 0
|
|
fi
|
|
|
|
if command -v apt-get >/dev/null 2>&1; then
|
|
apt-get update
|
|
apt-get install -y git curl ca-certificates python3
|
|
curl -fsSLo /usr/local/bin/kubectl "https://dl.k8s.io/release/$(curl -fsSL https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
|
|
chmod +x /usr/local/bin/kubectl
|
|
exit 0
|
|
fi
|
|
|
|
echo "missing git/kubectl/python3 and no supported package manager found" >&2
|
|
exit 1
|
|
|
|
- name: Prepare workspace
|
|
run: |
|
|
workspace_root="${RUNNER_TEMP:-/tmp}"
|
|
workspace_dir="$(mktemp -d "${workspace_root%/}/unrip-deploy-XXXXXX")"
|
|
echo "WORKSPACE_DIR=$workspace_dir" >> "$GITHUB_ENV"
|
|
echo "runner workspace: $workspace_dir"
|
|
|
|
- name: Load kubeconfig
|
|
run: |
|
|
mkdir -p "$HOME/.kube"
|
|
printf '%s' '${{ secrets.KUBECONFIG_B64 }}' | base64 -d > "$HOME/.kube/config"
|
|
kubectl get ns
|
|
|
|
- name: Checkout repo
|
|
env:
|
|
REPO_TOKEN: ${{ github.token }}
|
|
run: |
|
|
git -c credential.username=oauth2 -c http.extraHeader="Authorization: Bearer ${REPO_TOKEN}" clone --depth=1 "${REPO_CLONE_URL}" "$WORKSPACE_DIR"
|
|
cd "$WORKSPACE_DIR"
|
|
current_sha="$(git rev-parse HEAD)"
|
|
if [ "$current_sha" != "$GITHUB_SHA" ]; then
|
|
git -c credential.username=oauth2 -c http.extraHeader="Authorization: Bearer ${REPO_TOKEN}" fetch --depth=1 origin "${GITHUB_SHA}"
|
|
git checkout --detach "${GITHUB_SHA}"
|
|
else
|
|
git checkout --detach "$current_sha"
|
|
fi
|
|
git rev-parse HEAD
|
|
|
|
- name: Resolve deployment settings
|
|
run: |
|
|
IMAGE="$REGISTRY_HOST/$PROJECT_NAME:$IMAGE_TAG"
|
|
BUILD_JOB="image-build-$(printf '%s' "$GITHUB_SHA" | cut -c1-12)"
|
|
{
|
|
echo "IMAGE=$IMAGE"
|
|
echo "BUILD_JOB=$BUILD_JOB"
|
|
} >> "$GITHUB_ENV"
|
|
|
|
- name: Ensure namespace exists
|
|
run: |
|
|
kubectl apply -f "$WORKSPACE_DIR/deploy/k8s/base/namespace.yaml"
|
|
|
|
- name: Build and push image in-cluster
|
|
env:
|
|
REPO_TOKEN: ${{ github.token }}
|
|
run: |
|
|
kubectl -n "$PROJECT_NAMESPACE" delete job "$BUILD_JOB" --ignore-not-found=true
|
|
cat <<EOF | kubectl apply -f -
|
|
apiVersion: batch/v1
|
|
kind: Job
|
|
metadata:
|
|
name: ${BUILD_JOB}
|
|
namespace: ${PROJECT_NAMESPACE}
|
|
spec:
|
|
backoffLimit: 0
|
|
ttlSecondsAfterFinished: 3600
|
|
template:
|
|
spec:
|
|
restartPolicy: Never
|
|
volumes:
|
|
- name: workspace
|
|
emptyDir: {}
|
|
- name: registry-creds
|
|
secret:
|
|
secretName: ${PROJECT_REGISTRY_SECRET_NAME}
|
|
items:
|
|
- key: .dockerconfigjson
|
|
path: config.json
|
|
initContainers:
|
|
- name: checkout
|
|
image: alpine/git:2.47.2
|
|
env:
|
|
- name: REPO_TOKEN
|
|
value: ${REPO_TOKEN}
|
|
- name: REPO_CLONE_URL
|
|
value: ${REPO_CLONE_URL}
|
|
- name: GITHUB_SHA
|
|
value: ${GITHUB_SHA}
|
|
command: ["/bin/sh", "-lc"]
|
|
args:
|
|
- >-
|
|
git -c credential.username=oauth2 -c http.extraHeader="Authorization: Bearer ${REPO_TOKEN}" clone --depth=1 "${REPO_CLONE_URL}" /workspace &&
|
|
cd /workspace &&
|
|
git -c credential.username=oauth2 -c http.extraHeader="Authorization: Bearer ${REPO_TOKEN}" fetch --depth=1 origin "${GITHUB_SHA}" &&
|
|
git checkout --detach "${GITHUB_SHA}"
|
|
volumeMounts:
|
|
- name: workspace
|
|
mountPath: /workspace
|
|
containers:
|
|
- name: kaniko
|
|
image: gcr.io/kaniko-project/executor:v1.23.2-debug
|
|
args:
|
|
- --context=/workspace
|
|
- --dockerfile=/workspace/Dockerfile
|
|
- --destination=${IMAGE}
|
|
- --cache=false
|
|
volumeMounts:
|
|
- name: workspace
|
|
mountPath: /workspace
|
|
- name: registry-creds
|
|
mountPath: /kaniko/.docker
|
|
EOF
|
|
kubectl -n "$PROJECT_NAMESPACE" wait --for=condition=Complete --timeout=20m "job/$BUILD_JOB"
|
|
kubectl -n "$PROJECT_NAMESPACE" logs "job/$BUILD_JOB"
|
|
|
|
- name: Apply release manifests and wait for rollout
|
|
run: |
|
|
# Apply the rendered image after the build so no deployment ever falls back to bootstrap placeholders.
|
|
kubectl kustomize "$WORKSPACE_DIR/deploy/k8s/base" \
|
|
| python3 "$WORKSPACE_DIR/scripts/deploy/render_release_manifest.py" --image "$IMAGE" \
|
|
| kubectl apply -f -
|
|
|
|
kubectl -n "$PROJECT_NAMESPACE" get deployment \
|
|
-l "app.kubernetes.io/part-of=$PROJECT_NAME" \
|
|
-o name \
|
|
| while IFS= read -r deployment; do
|
|
[ -n "$deployment" ] || continue
|
|
kubectl -n "$PROJECT_NAMESPACE" rollout status "$deployment" --timeout=180s
|
|
done
|