Update my-first-workflow.yaml

This commit is contained in:
2026-01-26 14:17:42 +08:00
committed by GitHub
parent 4dc6376fc1
commit 7b871d54d8

View File

@@ -1,9 +1,9 @@
# 触发条件push到main分支手动触发 # 触发条件旧版语法
when: when:
event: [push, manual] event: [push, manual]
branch: main branch: main
# 克隆配置启用SSH拉取代码 # 克隆配置旧版仍支持
clone: clone:
git: git:
image: woodpeckerci/plugin-git image: woodpeckerci/plugin-git
@@ -12,192 +12,178 @@ clone:
lfs: false lfs: false
use-ssh: true use-ssh: true
# 全局环境变量 # 旧版顶层是 workflow不是 pipeline
environment: workflow "my-first-workflow":
CGO_ENABLED: 0 steps:
GO111MODULE: on # ------------------------------
GOSUMDB: off # 1. 编译 Go 程序
SCREEN_NAME: logic_service # screen会话名称全局统一 # ------------------------------
REMOTE_EXE_DIR: /opt/logic # 远程服务器程序存放目录 - name: build-logic
JSON_CONFIG_URL: "https://xxx.com/deploy-config.json" # 替换为你的JSON配置地址 image: golang:1.25
# JSON字段名与你的JSON对应无需修改 commands:
JSON_FIELD_ADDR: "loginaddr" - export CGO_ENABLED=0
JSON_FIELD_USER: "user" - export GO111MODULE=on
JSON_FIELD_PASS: "password" - export GOSUMDB=off
JSON_FIELD_ONLINEID: "online_id" # 新增解析JSON中的online_id字段 - VERSION="v$(git rev-parse --short=8 HEAD)"
- echo "BUILD_VERSION=$VERSION" > .env
# 流水线核心步骤 - mkdir -p build
pipeline: - BIN_NAME="logic_$VERSION"
# 1. 缓存Go依赖 - echo "BIN_NAME=$BIN_NAME" >> .env
cache-go-mod: - go build -v \
image: woodpeckerci/plugin-cache -p=4 \
settings: -trimpath \
mount: -buildvcs=false \
- ~/go/pkg/mod -ldflags "-s -w -buildid= -extldflags '-static'" \
- ~/.cache/go-build -o ./build/$BIN_NAME \
key: ${CI_OS}-go-${CI_COMMIT_SHA:0:8} ./logic
restore_keys: - if [ ! -f ./build/$BIN_NAME ]; then
- ${CI_OS}-go- echo "❌ 编译失败:产物 $BIN_NAME 不存在"
exit 1
# 2. 配置Go环境并预下载依赖
prepare-go:
image: golang:1.25
commands:
- go version
- go mod download -x
# 3. 生成构建版本号
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
- 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
- if [ ! -f /tmp/deploy-config.json ]; then
echo "❌ 拉取JSON配置失败"
exit 1
fi
# 检测JSON格式数组/对象新增解析online_id
- |
JSON_TYPE=$(jq -r 'type' /tmp/deploy-config.json)
if [ "$JSON_TYPE" = "array" ]; then
# 多服务器提取所有地址用户名密码online_id逗号分隔一一对应
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}"
- echo "解析出的用户名:${REMOTE_USERS}"
- echo "解析出的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
environment:
- BIN_NAME=${BIN_NAME}
- REMOTE_EXE_DIR=${REMOTE_EXE_DIR}
depends_on: [build-logic, fetch-deploy-config]
# 7. 远程部署核心修改使用动态online_id启动程序
deploy-to-servers:
image: appleboy/drone-ssh
settings:
host: ${REMOTE_HOSTS}
username: ${REMOTE_USERS}
password: ${REMOTE_PASSWORDS}
skip_verify: true
# 脚本新增读取当前服务器的online_id动态拼接启动参数
script:
# 第一步检查并安装screen无修改
- |
echo "检查Screen是否已安装..."
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
elif command -v yum &> /dev/null; then
yum install -y screen
elif command -v dnf &> /dev/null; then
dnf install -y screen
elif command -v pacman &> /dev/null; then
pacman -S --noconfirm screen
else
echo "❌ 不支持的包管理器无法安装Screen"
exit 1
fi
command -v screen || { echo "❌ Screen安装失败"; exit 1; }
fi fi
# 第二步设置程序执行权限无修改 - ls -lh ./build/
- mkdir -p ${REMOTE_EXE_DIR}
- chmod +x ${REMOTE_EXE_DIR}/${BIN_NAME} || { echo "❌ 设置权限失败"; exit 1; } # ------------------------------
# 第三步停止旧会话无修改 # 2. 获取并解析 JSON 配置 online_id
- screen -S ${SCREEN_NAME} -X quit || true # ------------------------------
# 第四步启动新程序核心修改使用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"
- 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
- | - |
echo "启动Screen会话[${SCREEN_NAME}]OnlineID${REMOTE_ONLINE_IDS}" JSON_TYPE=$(jq -r 'type' /tmp/deploy-config.json)
screen -dmS ${SCREEN_NAME} bash -c "\"${REMOTE_EXE_DIR}/${BIN_NAME}\" -id=${REMOTE_ONLINE_IDS} | tee -a \"\$HOME/run.log\"" if [ "$JSON_TYPE" = "array" ]; then
REMOTE_HOSTS=$(jq -r ".[].$JSON_FIELD_ADDR" /tmp/deploy-config.json | tr '\n' ',' | sed 's/,$//')
sleep 2 REMOTE_USERS=$(jq -r ".[].$JSON_FIELD_USER" /tmp/deploy-config.json | tr '\n' ',' | sed 's/,$//')
if screen -ls | grep -q "${SCREEN_NAME}"; then REMOTE_PASSWORDS=$(jq -r ".[].$JSON_FIELD_PASS" /tmp/deploy-config.json | tr '\n' ',' | sed 's/,$//')
echo "✅ 程序启动成功!会话:${SCREEN_NAME} | OnlineID${REMOTE_ONLINE_IDS}" REMOTE_ONLINE_IDS=$(jq -r ".[].$JSON_FIELD_ONLINEID" /tmp/deploy-config.json | tr '\n' ',' | sed 's/,$//')
screen -ls
else else
echo "❌ 程序启动失败,未创建[${SCREEN_NAME}]会话" 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..."
if command -v apt &> /dev/null; then
apt update -y && apt install -y screen
elif command -v yum &> /dev/null; then
yum install -y screen
elif command -v dnf &> /dev/null; then
dnf install -y screen
elif command -v pacman &> /dev/null; then
pacman -S --noconfirm screen
else
echo "❌ 不支持的包管理器"
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)"
screen -ls
else
echo "❌ 启动失败"
screen -ls screen -ls
exit 1 exit 1
fi fi
environment: environment:
- BIN_NAME=${BIN_NAME} - BIN_NAME=${BIN_NAME}
- SCREEN_NAME=${SCREEN_NAME} - SCREEN_NAME=${SCREEN_NAME}
- REMOTE_EXE_DIR=${REMOTE_EXE_DIR} - REMOTE_EXE_DIR=${REMOTE_EXE_DIR}
- REMOTE_ONLINE_IDS=${REMOTE_ONLINE_IDS} # 传递解析的online_id - REMOTE_ONLINE_IDS=${REMOTE_ONLINE_IDS}
depends_on: scp-exe-to-servers when:
- success
# 8. 打印部署完成信息新增显示online_id # ------------------------------
print-deploy-info: # 5. 打印结果
image: alpine:latest # ------------------------------
commands: - name: print-info
- echo "======================================" image: alpine:latest
- echo "✅ 部署完成!" commands:
- echo "版本号:${BUILD_VERSION}" - source .env
- echo "触发方式:${CI_EVENT_NAME}" - echo "======================================"
- echo "程序名称:${BIN_NAME}" - echo "✅ 部署完成"
- echo "远程部署目录:${REMOTE_EXE_DIR}" - echo "版本:$BUILD_VERSION"
- echo "Screen会话名${SCREEN_NAME}" - echo "程序:$BIN_NAME"
- echo "部署服务器:${REMOTE_HOSTS}" - echo "服务器:$REMOTE_HOSTS"
- echo "服务器OnlineID${REMOTE_ONLINE_IDS}" # 新增显示online_id - echo "OnlineID$REMOTE_ONLINE_IDS"
- echo "对应Commit${CI_COMMIT_SHA}" - echo "======================================"
- echo "======================================" when:
depends_on: deploy-to-servers - success