artifacts/.github/workflows/offline-package-nginx-ingress.yaml
2025-09-14 19:03:13 +08:00

290 lines
10 KiB
YAML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

name: Build Offline Nginx Ingress Installer
on:
push:
paths:
- 'scripts/ingress-installer.sh'
- 'scripts/resolve_nginx_ingress_versions.sh'
- '.github/workflows/offline-package-nginx-ingress.yaml'
workflow_dispatch:
inputs:
tag:
description: "Release tag to use/sync (e.g., v0.133.0). Leave empty to use offline-nginx-ingress-<run_number>"
required: false
type: string
image_tag:
description: "Override image tag for nginx/nginx-ingress (e.g., 5.1.1). Leave empty to auto-resolve"
required: false
type: string
chart_version:
description: "Override helm chart version for nginx-stable/nginx-ingress (e.g., 1.2.3). Leave empty to auto-resolve"
required: false
type: string
major_whitelist:
description: "Allowed major versions for image tag (regex alternation). Default: 5 (i.e., ^5\\.)"
required: false
type: string
default: "5"
permissions:
contents: write # 需要创建/上传 Release 资产
concurrency:
group: build-offline-nginx-ingress
cancel-in-progress: false
jobs:
build-offline-installer:
strategy:
matrix:
arch: [amd64, arm64]
runs-on: ubuntu-latest
outputs:
image_tag: ${{ steps.resolve.outputs.image_tag }}
chart_version: ${{ steps.resolve.outputs.chart_version }}
artifact-name: ${{ steps.upload-artifact.outputs.artifact-name }}
steps:
- uses: actions/checkout@v4
- name: Install deps (curl, jq, helm)
run: |
set -euo pipefail
sudo apt-get update -y
sudo apt-get install -y curl jq
curl -fsSL https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
helm version
- name: Add helm repo
run: |
set -euo pipefail
helm repo add nginx-stable https://helm.nginx.com/stable
helm repo update
- name: Resolve latest versions
id: resolve
env:
OVERRIDE_IMAGE_TAG: ${{ github.event.inputs.image_tag }}
OVERRIDE_CHART_VERSION: ${{ github.event.inputs.chart_version }}
MAJOR_WHITELIST: ${{ github.event.inputs.major_whitelist }}
run: |
set -euo pipefail
bash scripts/resolve_nginx_ingress_versions.sh
- name: Prepare directories
run: |
set -euo pipefail
mkdir -p offline-installer/{images,charts,scripts,bin}
# 复制并“盖章”版本号到安装脚本
- name: Stage installer script and stamp resolved image tag
env:
IMG_TAG: ${{ steps.resolve.outputs.image_tag }}
run: |
set -euo pipefail
cp scripts/ingress-installer.sh offline-installer/scripts/
# 替换默认的 NGINX_IC_IMAGE 与 OCI_NGINX_REF 中的 2.4.0 为解析到的 ${IMG_TAG}
sed -i -E "s|(NGINX_IC_IMAGE:=nginx/nginx-ingress:)[0-9]+\.[0-9]+\.[0-9]+|\1${IMG_TAG}|" offline-installer/scripts/ingress-installer.sh
sed -i -E "s|(OCI_NGINX_REF:=nginx-ingress-)[0-9]+\.[0-9]+\.[0-9]+|\1${IMG_TAG}|" offline-installer/scripts/ingress-installer.sh
chmod +x offline-installer/scripts/ingress-installer.sh
- name: Download nerdctl binary for ${{ matrix.arch }}
run: |
set -euo pipefail
wget https://github.com/containerd/nerdctl/releases/download/v2.0.3/nerdctl-2.0.3-linux-${{ matrix.arch }}.tar.gz \
-O offline-installer/nerdctl.tar.gz
- name: Pull & export required images (nginx/nginx-ingress:${{ steps.resolve.outputs.image_tag }})
env:
IMG_TAG: ${{ steps.resolve.outputs.image_tag }}
run: |
set -euo pipefail
docker pull "nginx/nginx-ingress:${IMG_TAG}"
docker pull "registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20230407"
docker save "nginx/nginx-ingress:${IMG_TAG}" \
-o offline-installer/images/nginx-ingress.tar
docker save "registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20230407" \
-o offline-installer/images/kube-webhook-certgen.tar
- name: Download Helm Chart (nginx-stable/nginx-ingress ${{ steps.resolve.outputs.chart_version }})
env:
CHART_VERSION: ${{ steps.resolve.outputs.chart_version }}
run: |
set -euo pipefail
helm pull nginx-stable/nginx-ingress --version="${CHART_VERSION}" --untar --untardir offline-installer/charts
- name: Package offline installer
run: |
set -euo pipefail
cd offline-installer
tar czvf ../offline-setup-nginx-ingress-${{ matrix.arch }}.tar.gz ./
cd ..
- name: Upload artifact
id: upload-artifact
uses: actions/upload-artifact@v4
with:
name: offline-setup-nginx-ingress-${{ matrix.arch }}
path: offline-setup-nginx-ingress-${{ matrix.arch }}.tar.gz
test-offline-installer:
needs: build-offline-installer
strategy:
matrix:
arch: [amd64]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Download offline installer artifact for ${{ matrix.arch }}
uses: actions/download-artifact@v4
with:
name: offline-setup-nginx-ingress-${{ matrix.arch }}
path: offline-test
- name: Setup K3s and KUBECONFIG for user
run: |
set -euo pipefail
curl -sfL https://get.k3s.io | sudo sh -
mkdir -p $HOME/.kube
sudo cp /etc/rancher/k3s/k3s.yaml $HOME/.kube/config
sudo chown $USER:$USER $HOME/.kube/config
sudo mkdir -p /root/.kube
sudo cp /etc/rancher/k3s/k3s.yaml /root/.kube/config
kubectl get nodes
kubectl version --client=true
- name: Install Helm
run: |
set -euo pipefail
curl -fsSL https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
- name: Load offline installer package
run: |
set -euo pipefail
cd offline-test
tar -xzvf offline-setup-nginx-ingress-${{ matrix.arch }}.tar.gz
sudo tar xzvf nerdctl.tar.gz -C /usr/local/bin/
docker load -i images/nginx-ingress.tar
docker load -i images/kube-webhook-certgen.tar
cd ..
- name: Run offline installer in K3S cluster
run: |
set -euo pipefail
cd offline-test
sudo bash scripts/ingress-installer.sh
sleep 10
sudo helm list -A
sudo kubectl -n ingress get pods
publish-release:
needs: test-offline-installer
runs-on: ubuntu-latest
env:
TAG_NAME: ${{ github.event.inputs.tag != '' && github.event.inputs.tag || format('offline-nginx-ingress-{0}', github.run_number) }}
RSYNC_SSH_KEY: ${{ secrets.RSYNC_SSH_KEY }}
RSYNC_SSH_USER: ${{ secrets.RSYNC_SSH_USER }}
VPS_HOST: ${{ secrets.VPS_HOST }}
REMOTE_ROOT: /data/update-server/nginx-ingress
steps:
- uses: actions/checkout@v4
- name: Create Release
id: create_release
uses: actions/create-release@v1
with:
tag_name: ${{ env.TAG_NAME }}
release_name: Build ${{ env.TAG_NAME }}
draft: false
prerelease: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Download amd64 artifact
uses: actions/download-artifact@v4
with:
name: offline-setup-nginx-ingress-amd64
path: release-artifacts
- name: Download arm64 artifact
uses: actions/download-artifact@v4
with:
name: offline-setup-nginx-ingress-arm64
path: release-artifacts
- name: Upload offline installers to GitHub Release
uses: softprops/action-gh-release@v1
with:
tag_name: ${{ env.TAG_NAME }}
files: |
release-artifacts/offline-setup-nginx-ingress-amd64.tar.gz
release-artifacts/offline-setup-nginx-ingress-arm64.tar.gz
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# === Rsync 到远端 ===
- name: Ensure deps (rsync, ssh)
run: |
set -euo pipefail
sudo apt-get update -y
sudo apt-get install -y rsync openssh-client
- name: Init SSH
run: |
set -euo pipefail
mkdir -p ~/.ssh
echo "$RSYNC_SSH_KEY" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan -H "$VPS_HOST" >> ~/.ssh/known_hosts
- name: Rsync release assets to remote
run: |
set -euo pipefail
REMOTE_DIR="${REMOTE_ROOT}/${TAG_NAME}"
ssh -i ~/.ssh/id_rsa "${RSYNC_SSH_USER}@${VPS_HOST}" "mkdir -p '${REMOTE_DIR}'"
echo "Rsync -> ${VPS_HOST}:${REMOTE_DIR}/"
rsync -av -e "ssh -i ~/.ssh/id_rsa" \
release-artifacts/offline-setup-nginx-ingress-amd64.tar.gz \
release-artifacts/offline-setup-nginx-ingress-arm64.tar.gz \
"${RSYNC_SSH_USER}@${VPS_HOST}:${REMOTE_DIR}/"
retention:
name: Remote retention (keep latest 3)
needs: publish-release
runs-on: ubuntu-latest
env:
RSYNC_SSH_KEY: ${{ secrets.RSYNC_SSH_KEY }}
RSYNC_SSH_USER: ${{ secrets.RSYNC_SSH_USER }}
VPS_HOST: ${{ secrets.VPS_HOST }}
REMOTE_ROOT: /data/update-server/nginx-ingress
steps:
- name: Init SSH
run: |
set -euo pipefail
mkdir -p ~/.ssh
echo "$RSYNC_SSH_KEY" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan -H "$VPS_HOST" >> ~/.ssh/known_hosts
- name: Prune old versions on remote (keep 3)
run: |
set -euo pipefail
ssh -i ~/.ssh/id_rsa "${RSYNC_SSH_USER}@${VPS_HOST}" bash -lc '
set -euo pipefail
cd "'"${REMOTE_ROOT}"'" || exit 0
keep=3
# 同时兼容两类目录命名offline-nginx-ingress-* 和 v<semver>
mapfile -t all < <(ls -1 | grep -E "^(offline-nginx-ingress-|v[0-9]+\.)" | sort -V -r || true)
if [ "${#all[@]}" -le "$keep" ]; then
echo "Nothing to prune. Count=${#all[@]}"
exit 0
fi
to_delete=("${all[@]:keep}")
echo "Pruning old versions: ${to_delete[*]}"
for d in "${to_delete[@]}"; do
rm -rf -- "$d"
done
'