Files
personal-site/.github/workflows/deploy.yml
T
Jesse EgbosionuandClaude Opus 5.5 f2c0c2716b
CI and Deploy / Build site (push) Successful in 20s
CI and Deploy / Build and push image (push) Successful in 30s
CI and Deploy / Deploy to Kubernetes (push) Failing after 2m33s
ci: silence npm audit, funding and update notices in npm ci
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-24 21:45:13 +02:00

151 lines
4.4 KiB
YAML

name: CI and Deploy
on:
workflow_dispatch:
pull_request:
branches:
- master
push:
branches:
- master
env:
REGISTRY: tea.jesseinit.dev
IMAGE_NAME: ${{ github.repository_owner }}/personal-site
NAMESPACE: personal-site
DEPLOYMENT: jesseinit-portfolio
permissions:
contents: read
concurrency:
group: deploy-${{ github.ref }}
cancel-in-progress: false
jobs:
ci:
name: Build site
runs-on: ubuntu-latest
timeout-minutes: 15
# The Gitea runner image only caches Node 24; match the Dockerfile's Node 22.
container: node:22-bookworm
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Install dependencies
run: npm ci --no-audit --no-fund --no-update-notifier
- name: Build
run: npm run build
- name: Validate Kubernetes manifests
run: |
curl -fsSL "https://dl.k8s.io/release/v1.34.3/bin/linux/amd64/kubectl" -o /usr/local/bin/kubectl
chmod +x /usr/local/bin/kubectl
kubectl kustomize k8s/ > /dev/null
build-image:
name: Build and push image
needs: ci
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
- name: Log in to Gitea Container Registry
uses: docker/login-action@v4
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.repository_owner }}
password: ${{ secrets.REGISTRY_TOKEN }}
- name: Extract image metadata
id: meta
uses: docker/metadata-action@v6
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=raw,value=latest
type=sha,format=long
- name: Build and push image
uses: docker/build-push-action@v7
with:
context: .
platforms: linux/amd64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
cache-to: type=inline
deploy:
name: Deploy to Kubernetes
needs: build-image
runs-on: ubuntu-latest
environment: production
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Set up kubectl
uses: azure/setup-kubectl@v5.1.0
with:
version: v1.34.3
- name: Configure kubectl
env:
KUBE_CONFIG_B64: ${{ secrets.KUBE_CONFIG }}
run: |
set -euo pipefail
if [ -z "${KUBE_CONFIG_B64}" ]; then
echo "::error::KUBE_CONFIG is not configured in the production environment or repository."
exit 1
fi
KUBECONFIG_PATH="${RUNNER_TEMP}/personal-site-kubeconfig"
umask 077
printf '%s' "${KUBE_CONFIG_B64}" | base64 --decode > "${KUBECONFIG_PATH}"
echo "KUBECONFIG=${KUBECONFIG_PATH}" >> "${GITHUB_ENV}"
KUBECONFIG="${KUBECONFIG_PATH}" kubectl cluster-info --request-timeout=15s
- name: Set up kustomize
env:
KUSTOMIZE_VERSION: v5.7.1
run: |
mkdir -p "${RUNNER_TEMP}/bin"
curl -fsSL "https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize%2F${KUSTOMIZE_VERSION}/kustomize_${KUSTOMIZE_VERSION}_linux_amd64.tar.gz" \
| tar -xz -C "${RUNNER_TEMP}/bin" kustomize
echo "${RUNNER_TEMP}/bin" >> "${GITHUB_PATH}"
- name: Pin image to this commit
working-directory: k8s
run: kustomize edit set image "jesseinit-portfolio=${REGISTRY}/${IMAGE_NAME}:sha-${GITHUB_SHA}"
- name: Apply manifests
run: kubectl apply -k k8s/
- name: Wait for rollout
run: |
if ! kubectl rollout status "deployment/${DEPLOYMENT}" -n "${NAMESPACE}" --timeout=5m; then
kubectl get pods -n "${NAMESPACE}" -o wide
kubectl describe pods -n "${NAMESPACE}" | tail -40
kubectl rollout undo "deployment/${DEPLOYMENT}" -n "${NAMESPACE}" || true
exit 1
fi
- name: Verify deployment
run: |
kubectl get deployments,pods,services,ingress -n "${NAMESPACE}"
echo "### Deployed sha-${GITHUB_SHA} to ${NAMESPACE}" >> "${GITHUB_STEP_SUMMARY}"