name: Deploy Hugo Blog to k3s on: push: branches: [main] workflow_dispatch: env: REGISTRY: git.luochen570.cn IMAGE: luochen570/hugo-blog K8S_NAMESPACE: hugo K8S_DEPLOYMENT: hugo-blog K8S_CONTAINER: nginx K8S_INGRESS: hugo-blog TEST_HOST: hugo.test.luochen570.cn PROD_HOST: hugo.luochen570.cn DOCKER_HOST: unix:///run/user/1000/docker.sock jobs: build-and-deploy: runs-on: ubuntu-latest permissions: contents: read steps: - name: Checkout uses: actions/checkout@v4 - name: Setup Hugo env: HTTP_PROXY: http://10.0.2.2:7890 HTTPS_PROXY: http://10.0.2.2:7890 ALL_PROXY: socks5://10.0.2.2:7891 NO_PROXY: localhost,127.0.0.1,.svc,.cluster.local,gitea-http.gitea.svc.cluster.local,git.luochen570.cn,docker.gitea.com run: | set -euo pipefail HUGO_VERSION="0.161.1" HUGO_DEB="hugo_extended_${HUGO_VERSION}_linux-amd64.deb" HUGO_URL="https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/${HUGO_DEB}" if command -v hugo >/dev/null 2>&1 && hugo version | grep -F "v${HUGO_VERSION}" >/dev/null; then hugo version exit 0 fi curl -fsSLo "/tmp/${HUGO_DEB}" "$HUGO_URL" apt-get update apt-get install -y --no-install-recommends "/tmp/${HUGO_DEB}" hugo version - name: Hugo Build run: hugo --minify - name: Build and Push Docker Image env: REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }} run: | set -euo pipefail # k3s dind-rootless runner: use rootless Docker Unix socket. export DOCKER_HOST="${DOCKER_HOST}" unset DOCKER_TLS_VERIFY DOCKER_CERT_PATH DOCKER_CONTEXT # Avoid proxy pollution in the container/rootless Docker path; proxy envs # can break image pulls through the slirp4netns namespace. unset HTTP_PROXY HTTPS_PROXY ALL_PROXY http_proxy https_proxy all_proxy if [ -z "${REGISTRY_TOKEN:-}" ]; then echo "REGISTRY_TOKEN secret is required" >&2 exit 1 fi IMAGE_TAG="${GITHUB_SHA}" docker version echo "$REGISTRY_TOKEN" | docker login "$REGISTRY" -u luochen570 --password-stdin docker build \ -t "$REGISTRY/$IMAGE:$IMAGE_TAG" \ -t "$REGISTRY/$IMAGE:latest" \ . docker push "$REGISTRY/$IMAGE:$IMAGE_TAG" docker push "$REGISTRY/$IMAGE:latest" - name: Deploy to k3s env: KUBECONFIG_B64: ${{ secrets.KUBECONFIG_B64 }} run: | set -euo pipefail if [ -z "${KUBECONFIG_B64:-}" ]; then echo "KUBECONFIG_B64 secret is required" >&2 exit 1 fi KUBECONFIG_FILE="$(mktemp)" trap 'rm -f "$KUBECONFIG_FILE" /tmp/kubectl' EXIT echo "$KUBECONFIG_B64" | base64 -d > "$KUBECONFIG_FILE" chmod 600 "$KUBECONFIG_FILE" KUBECTL_VERSION="v1.32.0" curl -fsSLo /tmp/kubectl "https://dl.k8s.io/release/${KUBECTL_VERSION}/bin/linux/amd64/kubectl" chmod +x /tmp/kubectl if /tmp/kubectl --kubeconfig "$KUBECONFIG_FILE" \ auth can-i get ingresses -n "$K8S_NAMESPACE" >/dev/null 2>&1; then ingress_hosts="$(/tmp/kubectl --kubeconfig "$KUBECONFIG_FILE" \ get ingress "$K8S_INGRESS" -n "$K8S_NAMESPACE" \ --ignore-not-found \ -o jsonpath='{range .spec.rules[*]}{.host}{"\n"}{end}{range .spec.tls[*].hosts[*]}{.}{"\n"}{end}')" printf '%s\n' "$ingress_hosts" | grep -Fx "$PROD_HOST" >/dev/null if printf '%s\n' "$ingress_hosts" | grep -Fx "$TEST_HOST" >/dev/null; then echo "Ingress also contains test host $TEST_HOST; continuing because production host $PROD_HOST is present" fi else echo "Kubeconfig cannot read ingresses; relying on K8S_NAMESPACE/K8S_DEPLOYMENT scope: $K8S_NAMESPACE/$K8S_DEPLOYMENT" fi IMAGE_REF="$REGISTRY/$IMAGE:${GITHUB_SHA}" /tmp/kubectl --kubeconfig "$KUBECONFIG_FILE" \ set image "deployment/$K8S_DEPLOYMENT" -n "$K8S_NAMESPACE" \ "$K8S_CONTAINER=$IMAGE_REF" /tmp/kubectl --kubeconfig "$KUBECONFIG_FILE" \ annotate "deployment/$K8S_DEPLOYMENT" -n "$K8S_NAMESPACE" \ "hugo.luochen570.cn/git-sha=${GITHUB_SHA}" \ "hugo.luochen570.cn/image=$IMAGE_REF" \ --overwrite /tmp/kubectl --kubeconfig "$KUBECONFIG_FILE" \ rollout status "deployment/$K8S_DEPLOYMENT" -n "$K8S_NAMESPACE" --timeout=120s