Files
bl/.woodpecker/my-first-workflow.yaml
2026-01-27 02:48:52 +00:00

223 lines
8.7 KiB
Go
Raw 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.

# 触发条件仅pushmanual手动触发分支限定main修正格式错误
when:
- event: push
- event: manual
branch: main
skip_clone: true
# 全局配置变量替换占位符即可使用
variables:
SCREEN_NAME: "logic_service"
REMOTE_EXE_DIR: "/opt/logic"
JSON_CONFIG_URL: "https://你的JSON配置地址.com/deploy.json"
LOG_PATH: "$HOME/run.log"
# 流水线核心步骤理顺依赖链确保build依赖clone结果
steps:
# ========== 1. 替代clone拉取代码核心依赖 ==========
prepare:
image: debian:bookworm
environment:
from_secret:
WOODPECKER_SSH_KEY: WOODPECKER_SSH_KEY
commands:
- apt update
# 安装完整依赖解决SSH/libcrypto问题
- apt install -y ca-certificates curl git openssh-client openssl libssl-dev
# 清理旧SSH文件严格配置权限
- rm -rf /root/.ssh/*
- mkdir -p /root/.ssh && chmod 700 /root/.ssh
# 写入并清理SSH密钥兼容RSA/ED25519保留原始换行
# 替换原echo "$WOODPECKER_SSH_KEY"那行其余ssh配置不变
- echo "$WOODPECKER_SSH_KEY" > /root/.ssh/id_ed25519 && chmod 600 /root/.ssh/id_ed25519
- chmod 600 /root/.ssh/id_ed25519
# 添加GitHub主机密钥完整覆盖避免重复
- ssh-keyscan -H github.com > /root/.ssh/known_hosts
- chmod 600 /root/.ssh/known_hosts
# 检查私钥是否能被解析关键测试
- ssh-keygen -lf /root/.ssh/id_ed25519
- echo "🔍 尝试SSH连接GitHub详细日志..."
# 重新执行命令取消输出屏蔽查看具体错误
- ssh -vvv -i /root/.ssh/id_ed25519 -o StrictHostKeyChecking=accept-new git@github.com 2>&1
# 拉取代码拆分命令避免静默失败
- git init
- git remote add origin $CI_REPO_CLONE_SSH_URL
- git config core.sshCommand 'ssh -i /root/.ssh/id_ed25519'
- git fetch origin $CI_REPO_DEFAULT_BRANCH
- git checkout $CI_REPO_DEFAULT_BRANCH
- echo "✅ 代码拉取完成"
# ========== 2. 初始化Go环境依赖prepare代码拉取完成 ==========
prepare-go:
image: golang:1.25
depends_on: [prepare] # 明确依赖先拉代码再初始化Go
commands:
- go version
- go mod download -x
- go mod verify
- echo "✅ Go环境初始化完成"
# ========== 3. 生成版本号依赖prepare-goGo环境就绪 ==========
set-version:
image: golang:1.25
depends_on: [prepare-go] # 明确依赖Go环境就绪后生成版本号
commands:
- |
if [ -n "${CI_COMMIT_TAG}" ]; then
VERSION="${CI_COMMIT_TAG}"
else
VERSION="v$(git rev-parse --short=8 HEAD)" # 依赖prepare拉取的代码
fi
echo "BUILD_VERSION=${VERSION}" >> $CI_ENV_FILE
echo "✅ 生成版本号:${VERSION}"
# ========== 4. 编译Go服务核心依赖prepare+prepare-go+set-version ==========
build_logic:
image: golang:1.25
depends_on: [set-version] # 明确依赖版本号生成后再编译
environment:
CGO_ENABLED: 0
GO111MODULE: on
GOSUMDB: off
commands:
- mkdir -p build
- BIN_NAME="logic_${BUILD_VERSION}" # 依赖set-version的BUILD_VERSION
- echo "BIN_NAME=${BIN_NAME}" >> $CI_ENV_FILE
- |
go build -v \
-p=4 \
-trimpath \
-buildvcs=false \
-ldflags "-s -w -buildid= -extldflags '-static' -X main.version=${BUILD_VERSION}" \
-o ./build/${BIN_NAME} \
./logic # 依赖prepare拉取的./logic代码目录
- |
if [ ! -f ./build/${BIN_NAME} ]; then
echo "❌ 编译失败:产物${BIN_NAME}不存在"
exit 1
fi
- ls -lh ./build/
- ./build/${BIN_NAME} -v || true
- echo "✅ Go服务编译完成"
# ========== 5. 拉取部署配置可并行依赖prepare确保代码拉取完成 ==========
fetch-deploy-config:
image: alpine:latest
depends_on: [prepare] # 确保代码拉取完成后再拉配置
commands:
- apk add --no-cache curl jq
- echo "🔧 拉取部署配置:${JSON_CONFIG_URL}"
- |
for i in 1 2 3; do
curl -sSL --connect-timeout 10 ${JSON_CONFIG_URL} -o /tmp/deploy-config.json && break
echo "⚠️ 第${i}次拉取失败,重试中..."
sleep 2
done
if [ ! -f /tmp/deploy-config.json ]; then
echo "❌ 拉取JSON失败"
exit 1
fi
- |
JSON_TYPE=$(jq -r 'type' /tmp/deploy-config.json)
if [ "$JSON_TYPE" = "array" ]; then
REMOTE_HOSTS=$(jq -r '.[].loginaddr' /tmp/deploy-config.json | tr '\n' ',' | sed 's/,$//')
REMOTE_USERS=$(jq -r '.[].user' /tmp/deploy-config.json | tr '\n' ',' | sed 's/,$//')
REMOTE_PASSWORDS=$(jq -r '.[].password' /tmp/deploy-config.json | tr '\n' ',' | sed 's/,$//')
REMOTE_ONLINE_IDS=$(jq -r '.[].online_id' /tmp/deploy-config.json | tr '\n' ',' | sed 's/,$//')
else
REMOTE_HOSTS=$(jq -r '.loginaddr' /tmp/deploy-config.json)
REMOTE_USERS=$(jq -r '.user' /tmp/deploy-config.json)
REMOTE_PASSWORDS=$(jq -r '.password' /tmp/deploy-config.json)
REMOTE_ONLINE_IDS=$(jq -r '.online_id' /tmp/deploy-config.json)
fi
- |
if [ -z "$REMOTE_HOSTS" ] || [ -z "$REMOTE_USERS" ]; then
echo "❌ 解析配置失败:服务器/用户名为空"
cat /tmp/deploy-config.json
exit 1
fi
- echo "✅ 配置解析完成 | 服务器:${REMOTE_HOSTS} | OnlineID${REMOTE_ONLINE_IDS}"
- echo "REMOTE_HOSTS=${REMOTE_HOSTS}" >> $CI_ENV_FILE
- echo "REMOTE_USERS=${REMOTE_USERS}" >> $CI_ENV_FILE
- echo "REMOTE_PASSWORDS=${REMOTE_PASSWORDS}" >> $CI_ENV_FILE
- echo "REMOTE_ONLINE_IDS=${REMOTE_ONLINE_IDS}" >> $CI_ENV_FILE
# ========== 6. SCP推送产物依赖编译+配置解析 ==========
scp-exe-to-servers:
image: appleboy/drone-scp:1.6.2
settings:
host: ${REMOTE_HOSTS}
username: ${REMOTE_USERS}
password: ${REMOTE_PASSWORDS}
source: ./build/${BIN_NAME}
target: ${REMOTE_EXE_DIR}/
strip_components: 1
skip_verify: true
timeout: 30s
depends_on:
- build_logic
- fetch-deploy-config
# ========== 7. 远程部署依赖SCP推送 ==========
deploy-to-servers:
image: appleboy/drone-ssh:1.7.0
settings:
host: ${REMOTE_HOSTS}
username: ${REMOTE_USERS}
password: ${REMOTE_PASSWORDS}
skip_verify: true
timeout: 60s
script:
- |
if command -v screen &> /dev/null; then
echo "✅ Screen已安装"
else
echo "🔧 安装Screen..."
if command -v apt &> /dev/null; then
apt update -y && apt install -y screen -qq
elif command -v yum &> /dev/null; then
yum install -y screen -q
elif command -v dnf &> /dev/null; then
dnf install -y screen -q
else
echo "❌ 不支持的包管理器,安装失败"
exit 1
fi
command -v screen || { echo "❌ Screen安装后检测失败"; exit 1; }
fi
- mkdir -p ${REMOTE_EXE_DIR}
- chmod +x ${REMOTE_EXE_DIR}/${BIN_NAME} || { echo "❌ 设置执行权限失败"; exit 1; }
- screen -S ${SCREEN_NAME} -X quit || true
- |
echo "🚀 启动程序:${REMOTE_EXE_DIR}/${BIN_NAME} -id=${REMOTE_ONLINE_IDS}"
screen -dmS ${SCREEN_NAME} bash -c "\"${REMOTE_EXE_DIR}/${BIN_NAME}\" -id=${REMOTE_ONLINE_IDS} | tee -a ${LOG_PATH}"
sleep 2
if screen -ls | grep -q "${SCREEN_NAME}"; then
echo "✅ 启动成功Screen会话"
screen -ls
else
echo "❌ 启动失败,无${SCREEN_NAME}会话"
screen -ls && exit 1
fi
depends_on: [scp-exe-to-servers]
# ========== 8. 打印部署汇总依赖部署完成 ==========
print-deploy-info:
image: alpine:latest
depends_on: [deploy-to-servers]
commands:
- echo "======================================"
- echo "🎉 全量部署完成!"
- echo "📌 版本号:${BUILD_VERSION}"
- echo "📌 触发方式:${CI_EVENT_NAME}"
- echo "📌 部署服务器:${REMOTE_HOSTS}"
- echo "📌 OnlineID${REMOTE_ONLINE_IDS}"
- echo "📌 Screen会话${SCREEN_NAME}"
- echo "📌 程序目录:${REMOTE_EXE_DIR}"
- echo "📌 日志路径:${LOG_PATH}"
- echo "📌 对应Commit${CI_COMMIT_SHA}"
- echo "======================================"