Update my-first-workflow.yaml
This commit is contained in:
@@ -1,9 +1,8 @@
|
||||
# 触发条件(旧版语法)
|
||||
# Woodpecker 顶层仅允许 when/clone/pipeline 等核心字段,无steps/workflow/environment
|
||||
when:
|
||||
event: [push, manual]
|
||||
branch: main
|
||||
|
||||
# 克隆配置(旧版仍支持)
|
||||
clone:
|
||||
git:
|
||||
image: woodpeckerci/plugin-git
|
||||
@@ -12,178 +11,165 @@ clone:
|
||||
lfs: false
|
||||
use-ssh: true
|
||||
|
||||
# 旧版:顶层是 workflow,不是 pipeline
|
||||
workflow "my-first-workflow":
|
||||
steps:
|
||||
# ------------------------------
|
||||
# 1. 编译 Go 程序
|
||||
# ------------------------------
|
||||
- name: build-logic
|
||||
image: golang:1.25
|
||||
commands:
|
||||
- export CGO_ENABLED=0
|
||||
- export GO111MODULE=on
|
||||
- export GOSUMDB=off
|
||||
- VERSION="v$(git rev-parse --short=8 HEAD)"
|
||||
- echo "BUILD_VERSION=$VERSION" > .env
|
||||
- mkdir -p build
|
||||
- BIN_NAME="logic_$VERSION"
|
||||
- echo "BIN_NAME=$BIN_NAME" >> .env
|
||||
- go build -v \
|
||||
-p=4 \
|
||||
-trimpath \
|
||||
-buildvcs=false \
|
||||
-ldflags "-s -w -buildid= -extldflags '-static'" \
|
||||
-o ./build/$BIN_NAME \
|
||||
./logic
|
||||
- if [ ! -f ./build/$BIN_NAME ]; then
|
||||
echo "❌ 编译失败:产物 $BIN_NAME 不存在"
|
||||
exit 1
|
||||
fi
|
||||
- ls -lh ./build/
|
||||
# 所有自定义变量放入 pipeline 全局变量(Woodpecker 无顶层environment)
|
||||
pipeline:
|
||||
# 全局变量定义(所有步骤可直接引用)
|
||||
SCREEN_NAME: logic_service
|
||||
REMOTE_EXE_DIR: /opt/logic
|
||||
JSON_CONFIG_URL: "https://xxx.com/deploy-config.json"
|
||||
JSON_FIELD_ADDR: "loginaddr"
|
||||
JSON_FIELD_USER: "user"
|
||||
JSON_FIELD_PASS: "password"
|
||||
JSON_FIELD_ONLINEID: "online_id"
|
||||
|
||||
# ------------------------------
|
||||
# 2. 获取并解析 JSON 配置(含 online_id)
|
||||
# ------------------------------
|
||||
- name: fetch-deploy-config
|
||||
image: alpine:latest
|
||||
commands:
|
||||
- apk add --no-cache curl jq
|
||||
- source .env
|
||||
- JSON_CONFIG_URL="https://xxx.com/deploy-config.json" # 替换为你的地址
|
||||
- JSON_FIELD_ADDR="loginaddr"
|
||||
- JSON_FIELD_USER="user"
|
||||
- JSON_FIELD_PASS="password"
|
||||
- JSON_FIELD_ONLINEID="online_id"
|
||||
# 1. 缓存Go依赖
|
||||
cache-go-mod:
|
||||
image: woodpeckerci/plugin-cache
|
||||
settings:
|
||||
mount:
|
||||
- ~/go/pkg/mod
|
||||
- ~/.cache/go-build
|
||||
key: ${CI_OS}-go-${CI_COMMIT_SHA:0:8}
|
||||
restore_keys:
|
||||
- ${CI_OS}-go-
|
||||
|
||||
- echo "从 $JSON_CONFIG_URL 拉取配置..."
|
||||
- curl -sSL "$JSON_CONFIG_URL" -o /tmp/deploy-config.json
|
||||
- if [ ! -f /tmp/deploy-config.json ]; then
|
||||
echo "❌ 拉取配置失败"
|
||||
exit 1
|
||||
fi
|
||||
# 2. 配置Go环境&预下载依赖
|
||||
prepare-go:
|
||||
image: golang:1.25
|
||||
commands:
|
||||
- go version
|
||||
- go mod download -x
|
||||
|
||||
# 3. 生成构建版本号(写入CI环境文件供后续步骤使用)
|
||||
set-version:
|
||||
image: golang:1.25
|
||||
commands:
|
||||
- VERSION="v$(git rev-parse --short=8 HEAD)"
|
||||
- echo "BUILD_VERSION=${VERSION}" >> $CI_ENV_FILE
|
||||
- echo "构建版本号:${VERSION}"
|
||||
|
||||
# 4. 编译Go服务(静态编译,无依赖)
|
||||
build-logic:
|
||||
image: golang:1.25
|
||||
commands:
|
||||
- mkdir -p build
|
||||
- BIN_NAME="logic_${BUILD_VERSION}"
|
||||
- echo "BIN_NAME=${BIN_NAME}" >> $CI_ENV_FILE
|
||||
- CGO_ENABLED=0 GO111MODULE=on GOSUMDB=off go build -v \
|
||||
-p=4 \
|
||||
-trimpath \
|
||||
-buildvcs=false \
|
||||
-ldflags "-s -w -buildid= -extldflags '-static'" \
|
||||
-o ./build/${BIN_NAME} \
|
||||
./logic
|
||||
- if [ ! -f ./build/${BIN_NAME} ]; then
|
||||
echo "❌ 编译失败:产物${BIN_NAME}不存在"
|
||||
exit 1
|
||||
fi
|
||||
- ls -lh ./build/
|
||||
- echo "产物名称:${BIN_NAME}"
|
||||
|
||||
# 5. 拉取JSON&解析服务器信息/online_id(核心步骤)
|
||||
fetch-deploy-config:
|
||||
image: alpine:latest
|
||||
commands:
|
||||
- apk add --no-cache curl jq
|
||||
- echo "从${JSON_CONFIG_URL}拉取部署配置..."
|
||||
- curl -sSL ${JSON_CONFIG_URL} -o /tmp/deploy-config.json || { echo "❌ 拉取JSON失败"; exit 1; }
|
||||
- |
|
||||
JSON_TYPE=$(jq -r 'type' /tmp/deploy-config.json)
|
||||
if [ "$JSON_TYPE" = "array" ]; then
|
||||
REMOTE_HOSTS=$(jq -r ".[].${JSON_FIELD_ADDR}" /tmp/deploy-config.json | tr '\n' ',' | sed 's/,$//')
|
||||
REMOTE_USERS=$(jq -r ".[].${JSON_FIELD_USER}" /tmp/deploy-config.json | tr '\n' ',' | sed 's/,$//')
|
||||
REMOTE_PASSWORDS=$(jq -r ".[].${JSON_FIELD_PASS}" /tmp/deploy-config.json | tr '\n' ',' | sed 's/,$//')
|
||||
REMOTE_ONLINE_IDS=$(jq -r ".[].${JSON_FIELD_ONLINEID}" /tmp/deploy-config.json | tr '\n' ',' | sed 's/,$//')
|
||||
else
|
||||
REMOTE_HOSTS=$(jq -r ".${JSON_FIELD_ADDR}" /tmp/deploy-config.json)
|
||||
REMOTE_USERS=$(jq -r ".${JSON_FIELD_USER}" /tmp/deploy-config.json)
|
||||
REMOTE_PASSWORDS=$(jq -r ".${JSON_FIELD_PASS}" /tmp/deploy-config.json)
|
||||
REMOTE_ONLINE_IDS=$(jq -r ".${JSON_FIELD_ONLINEID}" /tmp/deploy-config.json)
|
||||
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
|
||||
settings:
|
||||
host: ${REMOTE_HOSTS}
|
||||
username: ${REMOTE_USERS}
|
||||
password: ${REMOTE_PASSWORDS}
|
||||
source: ./build/${BIN_NAME}
|
||||
target: ${REMOTE_EXE_DIR}/
|
||||
strip_components: 1
|
||||
skip_verify: true
|
||||
depends_on: [build-logic, fetch-deploy-config]
|
||||
|
||||
# 7. 远程部署:安装Screen+启动程序(动态-online_id)
|
||||
deploy-to-servers:
|
||||
image: appleboy/drone-ssh
|
||||
settings:
|
||||
host: ${REMOTE_HOSTS}
|
||||
username: ${REMOTE_USERS}
|
||||
password: ${REMOTE_PASSWORDS}
|
||||
skip_verify: true
|
||||
script:
|
||||
# 检查并安装Screen
|
||||
- |
|
||||
JSON_TYPE=$(jq -r 'type' /tmp/deploy-config.json)
|
||||
if [ "$JSON_TYPE" = "array" ]; then
|
||||
REMOTE_HOSTS=$(jq -r ".[].$JSON_FIELD_ADDR" /tmp/deploy-config.json | tr '\n' ',' | sed 's/,$//')
|
||||
REMOTE_USERS=$(jq -r ".[].$JSON_FIELD_USER" /tmp/deploy-config.json | tr '\n' ',' | sed 's/,$//')
|
||||
REMOTE_PASSWORDS=$(jq -r ".[].$JSON_FIELD_PASS" /tmp/deploy-config.json | tr '\n' ',' | sed 's/,$//')
|
||||
REMOTE_ONLINE_IDS=$(jq -r ".[].$JSON_FIELD_ONLINEID" /tmp/deploy-config.json | tr '\n' ',' | sed 's/,$//')
|
||||
if command -v screen &> /dev/null; then
|
||||
echo "✅ Screen已安装"
|
||||
else
|
||||
REMOTE_HOSTS=$(jq -r ".$JSON_FIELD_ADDR" /tmp/deploy-config.json)
|
||||
REMOTE_USERS=$(jq -r ".$JSON_FIELD_USER" /tmp/deploy-config.json)
|
||||
REMOTE_PASSWORDS=$(jq -r ".$JSON_FIELD_PASS" /tmp/deploy-config.json)
|
||||
REMOTE_ONLINE_IDS=$(jq -r ".$JSON_FIELD_ONLINEID" /tmp/deploy-config.json)
|
||||
fi
|
||||
|
||||
echo "REMOTE_HOSTS=$REMOTE_HOSTS" >> .env
|
||||
echo "REMOTE_USERS=$REMOTE_USERS" >> .env
|
||||
echo "REMOTE_PASSWORDS=$REMOTE_PASSWORDS" >> .env
|
||||
echo "REMOTE_ONLINE_IDS=$REMOTE_ONLINE_IDS" >> .env
|
||||
echo "REMOTE_EXE_DIR=/opt/logic" >> .env
|
||||
echo "SCREEN_NAME=logic_service" >> .env
|
||||
|
||||
- cat .env
|
||||
|
||||
# ------------------------------
|
||||
# 3. SCP 推送程序到服务器(密码登录)
|
||||
# ------------------------------
|
||||
- name: scp-exe
|
||||
image: appleboy/drone-scp
|
||||
settings:
|
||||
host: ${REMOTE_HOSTS}
|
||||
username: ${REMOTE_USERS}
|
||||
password: ${REMOTE_PASSWORDS}
|
||||
source: ./build/${BIN_NAME}
|
||||
target: ${REMOTE_EXE_DIR}/
|
||||
strip_components: 1
|
||||
skip_verify: true
|
||||
environment:
|
||||
- BIN_NAME=${BIN_NAME}
|
||||
- REMOTE_EXE_DIR=${REMOTE_EXE_DIR}
|
||||
when:
|
||||
- success
|
||||
|
||||
# ------------------------------
|
||||
# 4. 远程部署:安装 screen + 启动程序(带 -id=online_id)
|
||||
# ------------------------------
|
||||
- name: deploy-to-servers
|
||||
image: appleboy/drone-ssh
|
||||
settings:
|
||||
host: ${REMOTE_HOSTS}
|
||||
username: ${REMOTE_USERS}
|
||||
password: ${REMOTE_PASSWORDS}
|
||||
skip_verify: true
|
||||
script:
|
||||
- |
|
||||
# 加载变量(旧版 drone-ssh 会自动把环境变量带过去)
|
||||
source /dev/stdin << 'EOF'
|
||||
export BIN_NAME="${BIN_NAME}"
|
||||
export SCREEN_NAME="${SCREEN_NAME}"
|
||||
export REMOTE_EXE_DIR="${REMOTE_EXE_DIR}"
|
||||
export ONLINE_ID="${REMOTE_ONLINE_IDS}"
|
||||
EOF
|
||||
|
||||
# 检查并安装 screen
|
||||
echo "检查 Screen..."
|
||||
if ! command -v screen &> /dev/null; then
|
||||
echo "安装 screen..."
|
||||
echo "🔧 开始安装Screen"
|
||||
if command -v apt &> /dev/null; then
|
||||
apt update -y && apt install -y screen
|
||||
apt update -y && apt install -y screen -qq
|
||||
elif command -v yum &> /dev/null; then
|
||||
yum install -y screen
|
||||
yum install -y screen -q
|
||||
elif command -v dnf &> /dev/null; then
|
||||
dnf install -y screen
|
||||
dnf install -y screen -q
|
||||
elif command -v pacman &> /dev/null; then
|
||||
pacman -S --noconfirm screen
|
||||
pacman -S --noconfirm screen
|
||||
else
|
||||
echo "❌ 不支持的包管理器"
|
||||
exit 1
|
||||
echo "❌ 不支持的包管理器,无法安装Screen"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# 赋权
|
||||
mkdir -p "$REMOTE_EXE_DIR"
|
||||
chmod +x "$REMOTE_EXE_DIR/$BIN_NAME" || { echo "❌ 赋权失败"; exit 1; }
|
||||
|
||||
# 停止旧会话
|
||||
screen -S "$SCREEN_NAME" -X quit || true
|
||||
|
||||
# 启动新程序(带 -id=$ONLINE_ID)
|
||||
echo "启动 $SCREEN_NAME with -id=$ONLINE_ID"
|
||||
screen -dmS "$SCREEN_NAME" bash -c "\"$REMOTE_EXE_DIR/$BIN_NAME\" -id=$ONLINE_ID | tee -a \"\$HOME/run.log\""
|
||||
|
||||
sleep 2
|
||||
if screen -ls | grep -q "$SCREEN_NAME"; then
|
||||
echo "✅ 启动成功:$SCREEN_NAME (id=$ONLINE_ID)"
|
||||
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
|
||||
# 启动新程序(动态-id,日志写入run.log)
|
||||
- |
|
||||
echo "🚀 启动Screen会话[${SCREEN_NAME}],OnlineID=${REMOTE_ONLINE_IDS}"
|
||||
screen -dmS ${SCREEN_NAME} bash -c "\"${REMOTE_EXE_DIR}/${BIN_NAME}\" -id=${REMOTE_ONLINE_IDS} | tee -a \"\$HOME/run.log\""
|
||||
sleep 2
|
||||
if screen -ls | grep -q "${SCREEN_NAME}"; then
|
||||
echo "✅ 程序启动成功!会话列表:"
|
||||
screen -ls
|
||||
else
|
||||
echo "❌ 启动失败"
|
||||
else
|
||||
echo "❌ 程序启动失败,无目标会话"
|
||||
screen -ls
|
||||
exit 1
|
||||
fi
|
||||
environment:
|
||||
- BIN_NAME=${BIN_NAME}
|
||||
- SCREEN_NAME=${SCREEN_NAME}
|
||||
- REMOTE_EXE_DIR=${REMOTE_EXE_DIR}
|
||||
- REMOTE_ONLINE_IDS=${REMOTE_ONLINE_IDS}
|
||||
when:
|
||||
- success
|
||||
fi
|
||||
depends_on: scp-exe-to-servers
|
||||
|
||||
# ------------------------------
|
||||
# 5. 打印结果
|
||||
# ------------------------------
|
||||
- name: print-info
|
||||
image: alpine:latest
|
||||
commands:
|
||||
- source .env
|
||||
- echo "======================================"
|
||||
- echo "✅ 部署完成"
|
||||
- echo "版本:$BUILD_VERSION"
|
||||
- echo "程序:$BIN_NAME"
|
||||
- echo "服务器:$REMOTE_HOSTS"
|
||||
- echo "OnlineID:$REMOTE_ONLINE_IDS"
|
||||
- echo "======================================"
|
||||
when:
|
||||
- success
|
||||
# 8. 打印部署完成汇总信息
|
||||
print-deploy-info:
|
||||
image: alpine:latest
|
||||
commands:
|
||||
- echo "======================================"
|
||||
- echo "🎉 全量部署完成!"
|
||||
- echo "版本号:${BUILD_VERSION}"
|
||||
- echo "触发方式:${CI_EVENT_NAME}"
|
||||
- echo "程序名称:${BIN_NAME}"
|
||||
- echo "部署目录:${REMOTE_EXE_DIR}"
|
||||
- echo "Screen会话:${SCREEN_NAME}"
|
||||
- echo "部署服务器:${REMOTE_HOSTS}"
|
||||
- echo "服务器OnlineID:${REMOTE_ONLINE_IDS}"
|
||||
- echo "对应Commit:${CI_COMMIT_SHA}"
|
||||
- echo "======================================"
|
||||
depends_on: deploy-to-servers
|
||||
|
||||
Reference in New Issue
Block a user