ci: 建立生产镜像与 Tag 发布流水线
新增独立仓库级 Gitea Runner,main 和 PR 执行完整质量门禁与不可变 SHA 镜像构建;只有来自 main 历史的语义版本 Tag 才调用受限生产发布助手。专属 Buildx builder 将缓存限制为 2 GB。\n\n验证:流水线结构测试、ShellCheck、Go vet/test、govulncheck、前端 lint/test/build、Compose 渲染及高危依赖审计通过。
This commit is contained in:
Executable
+61
@@ -0,0 +1,61 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
root=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
|
||||
cd "$root"
|
||||
|
||||
tag=${IMAGE_TAG:-}
|
||||
registry=${AI_GATEWAY_IMAGE_REGISTRY:-registry.cn-shanghai.aliyuncs.com/easyaigc}
|
||||
builder=${AI_GATEWAY_BUILDX_BUILDER:-easyai-gateway-ci}
|
||||
cache_limit=${AI_GATEWAY_BUILDX_CACHE_LIMIT:-2gb}
|
||||
platform=${AI_GATEWAY_PLATFORM:-linux/amd64}
|
||||
|
||||
if [[ ! $tag =~ ^[0-9a-f]{40}$ ]]; then
|
||||
echo 'IMAGE_TAG must be a full lowercase Git SHA' >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ ! $registry =~ ^[A-Za-z0-9.-]+(:[0-9]+)?(/[A-Za-z0-9._/-]+)+$ ]]; then
|
||||
echo 'AI_GATEWAY_IMAGE_REGISTRY has an invalid format' >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! docker buildx inspect "$builder" >/dev/null 2>&1; then
|
||||
docker buildx create --name "$builder" --driver docker-container --use >/dev/null
|
||||
fi
|
||||
docker buildx inspect "$builder" --bootstrap >/dev/null
|
||||
|
||||
cleanup_cache() {
|
||||
docker buildx prune --builder "$builder" --force --max-used-space "$cache_limit" >/dev/null || true
|
||||
}
|
||||
trap cleanup_cache EXIT HUP INT TERM
|
||||
|
||||
api_image="$registry/ai-gateway:$tag"
|
||||
web_image="$registry/ai-gateway-web:$tag"
|
||||
common_args=(
|
||||
--builder "$builder"
|
||||
--platform "$platform"
|
||||
--file Dockerfile
|
||||
--pull
|
||||
--load
|
||||
)
|
||||
|
||||
docker buildx build --builder "$builder" \
|
||||
"${common_args[@]:2}" \
|
||||
--target api \
|
||||
--build-arg "GO_BUILD_IMAGE=${AI_GATEWAY_GO_BUILD_IMAGE:-docker.m.daocloud.io/library/golang:1.26.5-alpine}" \
|
||||
--build-arg "API_RUNTIME_IMAGE=${AI_GATEWAY_API_RUNTIME_IMAGE:-docker.m.daocloud.io/library/alpine:3.22}" \
|
||||
--tag "$api_image" .
|
||||
|
||||
docker buildx build --builder "$builder" \
|
||||
"${common_args[@]:2}" \
|
||||
--target web \
|
||||
--build-arg "NODE_BUILD_IMAGE=${AI_GATEWAY_NODE_BUILD_IMAGE:-docker.m.daocloud.io/library/node:24-alpine}" \
|
||||
--build-arg "WEB_RUNTIME_IMAGE=${AI_GATEWAY_WEB_RUNTIME_IMAGE:-docker.m.daocloud.io/library/nginx:1.27-alpine}" \
|
||||
--tag "$web_image" .
|
||||
|
||||
for image in "$api_image" "$web_image"; do
|
||||
trivy image --scanners vuln,secret --severity HIGH,CRITICAL --ignore-unfixed \
|
||||
--exit-code 1 --timeout 15m "$image"
|
||||
done
|
||||
|
||||
printf 'gateway_images=PASS git_sha=%s api=%s web=%s\n' "$tag" "$api_image" "$web_image"
|
||||
Executable
+113
@@ -0,0 +1,113 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
ROOT=$(CDPATH='' cd -- "$(dirname -- "$0")/.." && pwd)
|
||||
PREFIX=${CI_RUNNER_PREFIX:-/opt/easyai-gateway-ci}
|
||||
RUNNER_HOME=${CI_RUNNER_HOME:-/var/lib/easyai-gateway-runner}
|
||||
RUNNER_USER=${CI_RUNNER_USER:-easyai-gateway-runner}
|
||||
GITEA_INSTANCE_URL=${GITEA_INSTANCE_URL:-https://git.51easyai.com}
|
||||
RUNNER_NAME=${RUNNER_NAME:-easyai-gateway-linux}
|
||||
RUNNER_LABEL=${RUNNER_LABEL:-easyai-gateway-linux:host}
|
||||
|
||||
GITEA_RUNNER_VERSION=2.0.0
|
||||
GITEA_RUNNER_SHA256=447156b33407ee045409f5552bd4a188a315cdd4085b4b498d8d4a9ad26c9f73
|
||||
GO_VERSION=1.26.5
|
||||
GO_SHA256=5c2c3b16caefa1d968a94c1daca04a7ca301a496d9b086e17ad77bb81393f053
|
||||
NODE_VERSION=24.16.0
|
||||
NODE_SHA256=d804845d34eddc21dc1092b519d643ef40b1f58ec5dec5c22b1f4bd8fabde6c9
|
||||
TRIVY_VERSION=0.70.0
|
||||
TRIVY_SHA256=8b4376d5d6befe5c24d503f10ff136d9e0c49f9127a4279fd110b727929a5aa9
|
||||
PNPM_VERSION=10.18.1
|
||||
|
||||
[ "$(id -u)" -eq 0 ] || { echo "run as root" >&2; exit 1; }
|
||||
[ "$(uname -s)-$(uname -m)" = "Linux-x86_64" ] || { echo "only Linux x86_64 is supported" >&2; exit 1; }
|
||||
|
||||
if ! command -v make >/dev/null 2>&1 || ! command -v gcc >/dev/null 2>&1 || \
|
||||
! command -v jq >/dev/null 2>&1 || ! command -v shellcheck >/dev/null 2>&1 || \
|
||||
! docker compose version >/dev/null 2>&1 || ! docker buildx version >/dev/null 2>&1; then
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
apt-get update
|
||||
apt-get install -y --no-install-recommends \
|
||||
build-essential ca-certificates curl docker-buildx-plugin docker-compose-plugin \
|
||||
git jq perl shellcheck unzip util-linux xz-utils
|
||||
fi
|
||||
|
||||
download_verified() {
|
||||
url=$1
|
||||
output=$2
|
||||
checksum=$3
|
||||
if [ ! -f "$output" ] || ! printf '%s %s\n' "$checksum" "$output" | sha256sum -c - >/dev/null 2>&1; then
|
||||
rm -f "$output"
|
||||
curl -fL --retry 5 --retry-delay 2 "$url" -o "$output"
|
||||
fi
|
||||
printf '%s %s\n' "$checksum" "$output" | sha256sum -c -
|
||||
}
|
||||
|
||||
if ! id "$RUNNER_USER" >/dev/null 2>&1; then
|
||||
useradd --system --home-dir "$RUNNER_HOME" --create-home --shell /usr/sbin/nologin "$RUNNER_USER"
|
||||
fi
|
||||
usermod -aG docker "$RUNNER_USER"
|
||||
|
||||
install -d -m 0755 "$PREFIX/bin" "$PREFIX/downloads" "$PREFIX/toolchains"
|
||||
install -d -o "$RUNNER_USER" -g "$RUNNER_USER" -m 0700 \
|
||||
"$RUNNER_HOME" "$RUNNER_HOME/cache" "$RUNNER_HOME/work"
|
||||
|
||||
download_verified \
|
||||
"https://gitea.com/gitea/runner/releases/download/v${GITEA_RUNNER_VERSION}/gitea-runner-${GITEA_RUNNER_VERSION}-linux-amd64" \
|
||||
"$PREFIX/downloads/gitea-runner-${GITEA_RUNNER_VERSION}-linux-amd64" \
|
||||
"$GITEA_RUNNER_SHA256"
|
||||
install -m 0755 "$PREFIX/downloads/gitea-runner-${GITEA_RUNNER_VERSION}-linux-amd64" "$PREFIX/bin/gitea-runner"
|
||||
|
||||
download_verified \
|
||||
"https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz" \
|
||||
"$PREFIX/downloads/go${GO_VERSION}.linux-amd64.tar.gz" \
|
||||
"$GO_SHA256"
|
||||
rm -rf "$PREFIX/toolchains/go"
|
||||
tar -xzf "$PREFIX/downloads/go${GO_VERSION}.linux-amd64.tar.gz" -C "$PREFIX/toolchains"
|
||||
|
||||
download_verified \
|
||||
"https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64.tar.xz" \
|
||||
"$PREFIX/downloads/node-v${NODE_VERSION}-linux-x64.tar.xz" \
|
||||
"$NODE_SHA256"
|
||||
rm -rf "$PREFIX/toolchains/node"
|
||||
mkdir -p "$PREFIX/toolchains/node"
|
||||
tar -xJf "$PREFIX/downloads/node-v${NODE_VERSION}-linux-x64.tar.xz" \
|
||||
-C "$PREFIX/toolchains/node" --strip-components=1
|
||||
"$PREFIX/toolchains/node/bin/npm" install --global --prefix "$PREFIX/toolchains/node" \
|
||||
--ignore-scripts "pnpm@${PNPM_VERSION}"
|
||||
|
||||
download_verified \
|
||||
"https://github.com/aquasecurity/trivy/releases/download/v${TRIVY_VERSION}/trivy_${TRIVY_VERSION}_Linux-64bit.tar.gz" \
|
||||
"$PREFIX/downloads/trivy_${TRIVY_VERSION}_Linux-64bit.tar.gz" \
|
||||
"$TRIVY_SHA256"
|
||||
tar -xzf "$PREFIX/downloads/trivy_${TRIVY_VERSION}_Linux-64bit.tar.gz" -C "$PREFIX/bin" trivy
|
||||
chmod 0755 "$PREFIX/bin/trivy"
|
||||
GOBIN="$PREFIX/bin" GOPROXY="${GO_MODULE_PROXY:-https://goproxy.cn,direct}" \
|
||||
"$PREFIX/toolchains/go/bin/go" install golang.org/x/vuln/cmd/govulncheck@v1.6.0
|
||||
|
||||
install -d -m 0755 /etc/easyai-gateway-runner
|
||||
install -m 0644 "$ROOT/deploy/ci/act-runner-config.yaml" /etc/easyai-gateway-runner/config.yaml
|
||||
install -m 0644 "$ROOT/deploy/ci/easyai-gateway-act-runner.service" /etc/systemd/system/easyai-gateway-act-runner.service
|
||||
|
||||
if [ ! -s "$RUNNER_HOME/.runner" ]; then
|
||||
[ -n "${RUNNER_REGISTRATION_TOKEN:-}" ] || {
|
||||
echo "RUNNER_REGISTRATION_TOKEN is required for first registration" >&2
|
||||
exit 1
|
||||
}
|
||||
runuser -u "$RUNNER_USER" -- env HOME="$RUNNER_HOME" \
|
||||
"$PREFIX/bin/gitea-runner" --config /etc/easyai-gateway-runner/config.yaml \
|
||||
register --no-interactive \
|
||||
--instance "$GITEA_INSTANCE_URL" \
|
||||
--token "$RUNNER_REGISTRATION_TOKEN" \
|
||||
--name "$RUNNER_NAME" \
|
||||
--labels "$RUNNER_LABEL"
|
||||
chmod 0600 "$RUNNER_HOME/.runner"
|
||||
fi
|
||||
|
||||
chown -R "$RUNNER_USER:$RUNNER_USER" "$RUNNER_HOME"
|
||||
systemctl daemon-reload
|
||||
systemctl enable --now easyai-gateway-act-runner.service
|
||||
systemctl --no-pager --full status easyai-gateway-act-runner.service
|
||||
|
||||
env PATH="$PREFIX/bin:$PREFIX/toolchains/go/bin:$PREFIX/toolchains/node/bin:$PATH" \
|
||||
sh -c 'gitea-runner --version && go version && node --version && pnpm --version && trivy --version && govulncheck -version'
|
||||
Reference in New Issue
Block a user