新增通知中心构建机部署流程
This commit is contained in:
parent
d42c4cce84
commit
97e380b138
158
scripts/git-build-deploy.ps1
Normal file
158
scripts/git-build-deploy.ps1
Normal file
@ -0,0 +1,158 @@
|
||||
#Requires -Version 5.1
|
||||
|
||||
param(
|
||||
[string]$RepoUrl = 'http://git.1080p.hk/WuYongJie/YouYiDianNotificationCenter.git',
|
||||
[string]$Branch = 'main',
|
||||
[string]$Commit = '',
|
||||
[string]$BuildServer = 'root@192.168.40.206',
|
||||
[string]$ProductionServer = 'root@192.168.58.20',
|
||||
[string]$RemoteBuildDir = '/root/youyidian-notification-center-build',
|
||||
[string]$RegistryHost = '192.168.40.206:5000',
|
||||
[string]$ImageName = 'youyidian-notification-center',
|
||||
[switch]$DryRun
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
function ConvertTo-ShellSingleQuoted([string]$Value) {
|
||||
return "'" + $Value.Replace("'", "'\''") + "'"
|
||||
}
|
||||
|
||||
$remoteScript = @'
|
||||
set -Eeuo pipefail
|
||||
|
||||
REPO_URL=__REPO_URL__
|
||||
BRANCH=__BRANCH__
|
||||
COMMIT_INPUT=__COMMIT__
|
||||
BUILD_DIR=__BUILD_DIR__
|
||||
PRODUCTION_SERVER=__PRODUCTION_SERVER__
|
||||
REGISTRY_HOST=__REGISTRY_HOST__
|
||||
IMAGE_NAME=__IMAGE_NAME__
|
||||
DRY_RUN=__DRY_RUN__
|
||||
|
||||
log() { printf '[INFO] %s\n' "$*"; }
|
||||
ok() { printf '[OK] %s\n' "$*"; }
|
||||
fail() { printf '[ERR] %s\n' "$*" >&2; exit 1; }
|
||||
|
||||
for command in git docker curl ssh; do
|
||||
command -v "$command" >/dev/null 2>&1 || fail "构建机缺少命令: $command"
|
||||
done
|
||||
curl -fsS "http://127.0.0.1:${REGISTRY_HOST##*:}/v2/" >/dev/null \
|
||||
|| fail '构建机内部镜像仓库不可用'
|
||||
ssh -o BatchMode=yes -o ConnectTimeout=10 "$PRODUCTION_SERVER" 'true' \
|
||||
|| fail '构建机无法连接生产机'
|
||||
|
||||
if [ ! -d "$BUILD_DIR/.git" ]; then
|
||||
rm -rf "$BUILD_DIR"
|
||||
git clone "$REPO_URL" "$BUILD_DIR"
|
||||
fi
|
||||
|
||||
cd "$BUILD_DIR"
|
||||
git remote set-url origin "$REPO_URL"
|
||||
git fetch --prune origin "$BRANCH"
|
||||
target="origin/$BRANCH"
|
||||
if [ -n "$COMMIT_INPUT" ]; then
|
||||
target="$COMMIT_INPUT"
|
||||
fi
|
||||
git rev-parse --verify "${target}^{commit}" >/dev/null
|
||||
if [ "$DRY_RUN" = 1 ]; then
|
||||
ok "预检通过,目标提交: $(git rev-parse "${target}^{commit}")"
|
||||
exit 0
|
||||
fi
|
||||
git checkout --detach "$target"
|
||||
git reset --hard "$target"
|
||||
git clean -fdx
|
||||
|
||||
commit_sha="$(git rev-parse HEAD)"
|
||||
short_sha="$(git rev-parse --short=12 HEAD)"
|
||||
image_tag="production-${short_sha}"
|
||||
local_commit="localhost:${REGISTRY_HOST##*:}/${IMAGE_NAME}:${image_tag}"
|
||||
local_latest="localhost:${REGISTRY_HOST##*:}/${IMAGE_NAME}:production-latest"
|
||||
remote_commit="${REGISTRY_HOST}/${IMAGE_NAME}:${image_tag}"
|
||||
|
||||
log "构建提交 ${commit_sha}"
|
||||
docker pull "$local_latest" >/dev/null 2>&1 || true
|
||||
build_args=()
|
||||
if docker image inspect "$local_latest" >/dev/null 2>&1; then
|
||||
build_args+=(--cache-from "$local_latest")
|
||||
fi
|
||||
DOCKER_BUILDKIT=1 docker build "${build_args[@]}" \
|
||||
-t "$local_commit" \
|
||||
-t "$local_latest" \
|
||||
.
|
||||
docker push "$local_commit"
|
||||
docker push "$local_latest"
|
||||
ok "镜像已推送: $remote_commit"
|
||||
|
||||
if ! ssh -o BatchMode=yes -o ConnectTimeout=10 "$PRODUCTION_SERVER" \
|
||||
"docker pull '$remote_commit'"; then
|
||||
log '生产机无法直接拉取,改用 SSH 传输镜像'
|
||||
docker save "$local_commit" | ssh -o BatchMode=yes "$PRODUCTION_SERVER" docker load
|
||||
ssh -o BatchMode=yes "$PRODUCTION_SERVER" \
|
||||
"docker tag '$local_commit' '$remote_commit'"
|
||||
fi
|
||||
|
||||
ssh -o BatchMode=yes "$PRODUCTION_SERVER" \
|
||||
"REMOTE_IMAGE='$remote_commit' IMAGE_TAG='$image_tag' COMMIT_SHA='$commit_sha' bash -s" <<'PRODUCTION'
|
||||
set -Eeuo pipefail
|
||||
|
||||
target=/mnt/PoolOne/apps/youyidian-notification-center
|
||||
cd "$target"
|
||||
test -f .env
|
||||
test -f docker-compose.yml
|
||||
|
||||
old_image="$(docker inspect -f '{{.Config.Image}}' youyidian-notification-center 2>/dev/null || true)"
|
||||
if [ -n "$old_image" ] && docker image inspect "$old_image" >/dev/null 2>&1; then
|
||||
docker tag "$old_image" youyidian-notification-center:rollback-before-release
|
||||
fi
|
||||
|
||||
docker tag "$REMOTE_IMAGE" "youyidian-notification-center:$IMAGE_TAG"
|
||||
YYD_NOTIFICATION_IMAGE_TAG="$IMAGE_TAG" docker compose up -d --no-build --force-recreate
|
||||
|
||||
healthy=0
|
||||
for _ in $(seq 1 30); do
|
||||
if curl -fsS --max-time 3 http://127.0.0.1:3088/health >/tmp/yyd-notification-health.json; then
|
||||
healthy=1
|
||||
break
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
|
||||
if [ "$healthy" != 1 ]; then
|
||||
docker compose logs --tail 120
|
||||
if docker image inspect youyidian-notification-center:rollback-before-release >/dev/null 2>&1; then
|
||||
YYD_NOTIFICATION_IMAGE_TAG=rollback-before-release docker compose up -d --no-build --force-recreate
|
||||
fi
|
||||
exit 1
|
||||
fi
|
||||
|
||||
printf '%s' "$COMMIT_SHA" > DEPLOYED_COMMIT
|
||||
curl -fsS --max-time 10 https://sc.jiansun.vip/notification-center/health
|
||||
printf '\nDEPLOYED_COMMIT='
|
||||
cat DEPLOYED_COMMIT
|
||||
printf '\nCONTAINER_IMAGE='
|
||||
docker inspect -f '{{.Config.Image}}' youyidian-notification-center
|
||||
printf '\n'
|
||||
PRODUCTION
|
||||
|
||||
ok "通知中心已部署到 ${commit_sha}"
|
||||
'@
|
||||
|
||||
$replacements = @{
|
||||
'__REPO_URL__' = ConvertTo-ShellSingleQuoted $RepoUrl
|
||||
'__BRANCH__' = ConvertTo-ShellSingleQuoted $Branch
|
||||
'__COMMIT__' = ConvertTo-ShellSingleQuoted $Commit
|
||||
'__BUILD_DIR__' = ConvertTo-ShellSingleQuoted $RemoteBuildDir
|
||||
'__PRODUCTION_SERVER__' = ConvertTo-ShellSingleQuoted $ProductionServer
|
||||
'__REGISTRY_HOST__' = ConvertTo-ShellSingleQuoted $RegistryHost
|
||||
'__IMAGE_NAME__' = ConvertTo-ShellSingleQuoted $ImageName
|
||||
'__DRY_RUN__' = if ($DryRun) { '1' } else { '0' }
|
||||
}
|
||||
foreach ($entry in $replacements.GetEnumerator()) {
|
||||
$remoteScript = $remoteScript.Replace($entry.Key, $entry.Value)
|
||||
}
|
||||
|
||||
$remoteScript | ssh -o BatchMode=yes -o ConnectTimeout=10 $BuildServer 'bash -s'
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "通知中心构建机发布失败,退出码: $LASTEXITCODE"
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user