ci: support sudo docker on build node

This commit is contained in:
2026-08-21 22:51:30 +08:00
parent 613a278505
commit b15fed5b6a
+35 -21
View File
@@ -50,6 +50,20 @@ pipeline {
env.SMOKE_NETWORK = "jizhi-smoke-net-${env.BUILD_NUMBER}"
env.SMOKE_MYSQL = "jizhi-smoke-mysql-${env.BUILD_NUMBER}"
env.SMOKE_APP = "jizhi-smoke-app-${env.BUILD_NUMBER}"
env.DOCKER_CMD = sh(
script: '''
set +x
if docker version >/dev/null 2>&1; then
printf 'docker'
elif sudo -n docker version >/dev/null 2>&1; then
printf 'sudo -n docker'
else
echo 'Jenkins 用户无法访问 Docker;请加入 docker 组或配置免密 sudo docker。' >&2
exit 1
fi
''',
returnStdout: true,
).trim()
currentBuild.displayName = "#${env.BUILD_NUMBER} ${env.IMMUTABLE_TAG}"
currentBuild.description = 'linux/amd64 · Admin Web + ASP.NET API'
}
@@ -59,8 +73,8 @@ pipeline {
for command_name in git docker curl gzip sha256sum python3; do
command -v "$command_name" >/dev/null
done
docker version >/dev/null
docker buildx version
$DOCKER_CMD version >/dev/null
$DOCKER_CMD buildx version
test -f Dockerfile.backend
test -f admin-web/package-lock.json
mkdir -p artifacts
@@ -75,7 +89,7 @@ pipeline {
retry(2) {
sh '''
set -euo pipefail
docker buildx build \
$DOCKER_CMD buildx build \
--platform linux/amd64 \
--load \
--file Dockerfile.backend \
@@ -88,9 +102,9 @@ pipeline {
}
sh '''
set -euo pipefail
test "$(docker image inspect "$IMAGE_REF" --format '{{.Os}}/{{.Architecture}}')" = 'linux/amd64'
test "$(docker image inspect "$IMAGE_REF" --format '{{index .Config.Labels "org.opencontainers.image.revision"}}')" = "$FULL_SHA"
docker run --rm --entrypoint /bin/sh "$IMAGE_REF" -c \
test "$($DOCKER_CMD image inspect "$IMAGE_REF" --format '{{.Os}}/{{.Architecture}}')" = 'linux/amd64'
test "$($DOCKER_CMD image inspect "$IMAGE_REF" --format '{{index .Config.Labels "org.opencontainers.image.revision"}}')" = "$FULL_SHA"
$DOCKER_CMD run --rm --entrypoint /bin/sh "$IMAGE_REF" -c \
'test -s /app/MiaoJiZhang.Api.dll && test -s /app/wwwroot/index.html'
'''
}
@@ -100,8 +114,8 @@ pipeline {
steps {
sh '''
set -euo pipefail
docker network create "$SMOKE_NETWORK" >/dev/null
docker run --detach \
$DOCKER_CMD network create "$SMOKE_NETWORK" >/dev/null
$DOCKER_CMD run --detach \
--name "$SMOKE_MYSQL" \
--network "$SMOKE_NETWORK" \
--env MYSQL_DATABASE=jizhi_smoke \
@@ -112,7 +126,7 @@ pipeline {
mysql_ready=0
for attempt in $(seq 1 60); do
if docker exec "$SMOKE_MYSQL" mysqladmin ping \
if $DOCKER_CMD exec "$SMOKE_MYSQL" mysqladmin ping \
--user=jizhi --password=jizhi-smoke-password --silent; then
mysql_ready=1
break
@@ -120,11 +134,11 @@ pipeline {
sleep 2
done
if [ "$mysql_ready" != 1 ]; then
docker logs "$SMOKE_MYSQL" >&2
$DOCKER_CMD logs "$SMOKE_MYSQL" >&2
exit 1
fi
docker run --detach \
$DOCKER_CMD run --detach \
--name "$SMOKE_APP" \
--network "$SMOKE_NETWORK" \
--publish 127.0.0.1::8080 \
@@ -139,7 +153,7 @@ pipeline {
--env "Build__Version=$IMMUTABLE_TAG" \
"$IMAGE_REF" >/dev/null
host_port=$(docker port "$SMOKE_APP" 8080/tcp | sed -n 's/.*://p' | head -n 1)
host_port=$($DOCKER_CMD port "$SMOKE_APP" 8080/tcp | sed -n 's/.*://p' | head -n 1)
test -n "$host_port"
app_ready=0
for attempt in $(seq 1 90); do
@@ -148,14 +162,14 @@ pipeline {
app_ready=1
break
fi
if ! docker inspect "$SMOKE_APP" --format '{{.State.Running}}' | grep -qx true; then
docker logs "$SMOKE_APP" >&2
if ! $DOCKER_CMD inspect "$SMOKE_APP" --format '{{.State.Running}}' | grep -qx true; then
$DOCKER_CMD logs "$SMOKE_APP" >&2
exit 1
fi
sleep 2
done
if [ "$app_ready" != 1 ]; then
docker logs "$SMOKE_APP" >&2
$DOCKER_CMD logs "$SMOKE_APP" >&2
exit 1
fi
grep -Fq "\"version\":\"$IMMUTABLE_TAG\"" artifacts/smoke-ping.json
@@ -169,11 +183,11 @@ pipeline {
steps {
sh '''
set -euo pipefail
docker save "$IMAGE_REF" | gzip -1 >"$ARCHIVE_PATH"
$DOCKER_CMD save "$IMAGE_REF" | gzip -1 >"$ARCHIVE_PATH"
gzip -t "$ARCHIVE_PATH"
gzip -dc "$ARCHIVE_PATH" | tar -tf - | grep -q '^manifest.json$'
sha256sum "$ARCHIVE_PATH" >"$ARCHIVE_PATH.sha256"
image_id=$(docker image inspect "$IMAGE_REF" --format '{{.Id}}')
image_id=$($DOCKER_CMD image inspect "$IMAGE_REF" --format '{{.Id}}')
archive_sha=$(awk '{print $1}' "$ARCHIVE_PATH.sha256")
export image_id archive_sha
python3 - <<'PY'
@@ -221,12 +235,12 @@ PY
post {
always {
script {
if (env.NODE_NAME?.trim()) {
if (env.NODE_NAME?.trim() && env.DOCKER_CMD?.trim()) {
sh(
script: '''
docker rm --force "$SMOKE_APP" "$SMOKE_MYSQL" >/dev/null 2>&1 || true
docker network rm "$SMOKE_NETWORK" >/dev/null 2>&1 || true
docker image rm "$IMAGE_REF" >/dev/null 2>&1 || true
$DOCKER_CMD rm --force "$SMOKE_APP" "$SMOKE_MYSQL" >/dev/null 2>&1 || true
$DOCKER_CMD network rm "$SMOKE_NETWORK" >/dev/null 2>&1 || true
$DOCKER_CMD image rm "$IMAGE_REF" >/dev/null 2>&1 || true
''',
returnStatus: true,
)