From 582908c3e98c4c8794c3e56b1aedd961c57ebe77 Mon Sep 17 00:00:00 2001 From: 72wo <1@72wo.cn> Date: Mon, 26 Jan 2026 14:19:12 +0800 Subject: [PATCH] Update my-first-workflow.yaml --- .woodpecker/my-first-workflow.yaml | 310 ++++++++++++++--------------- 1 file changed, 148 insertions(+), 162 deletions(-) diff --git a/.woodpecker/my-first-workflow.yaml b/.woodpecker/my-first-workflow.yaml index 3ae57d600..b8292171d 100644 --- a/.woodpecker/my-first-workflow.yaml +++ b/.woodpecker/my-first-workflow.yaml @@ -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