批量更新项目依赖&自动调用jenkins构建

背景

  1. 有10+个项目都依赖一个common仓库,每次修改common后都需要更新10+个项目的go mod
  2. 更新后还需要都去jenkins里面点构建

思路

  1. 在一个工作目录拉取需要更新的项目中的一个,如A项目
  2. 拉取后进入A项目目录
  3. 检测需要更新的分支是否存在 git ls-remote --heads origin $TARGET_BRANCH
  4. 存在则直接checkout过去,不存在则基于main分支新起一个$TARGET_BRANCH分支
  5. 更新依赖,运行
     go get -u ****/common@依赖的分支
     go mod tidy
     git add go.mod go.sum
     git commit -m "update common@$DEPENDENCY"
     git push origin $TARGET_BRANCH` 
  6. 获取个人 jenkins API Token 网页路径 https://jenkins-k8s.***.com/user/wanna/configure
  7. 获取jenkins crumbs for CSRF
     JENKINS_CRUMB=$(curl -s 'https://jenkins-k8s.****.com/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)' --user $CERTIFICATE |grep Jenkins-Crumb| awk -F':' '{print $2}')
    echo $JENKINS_CRUMB
  8. 去jenkins点击项目构建后复制出请求的curl
  9. 替换项目名和crumbs并运行新的curl
  10. 切换到上级目录
  11. 重复1-10 更新项目B直到更新完全部项目

实现

#!/bin/bash

WORK_DIR="$HOME/.wanna/git_temp/"
if [ ! -d "$WORK_DIR" ]; then
  mkdir -p "$WORK_DIR"
fi


ALL_PROJECT="project1,project2,project3,project4"

PROJECTS=$1
TARGET_BRANCH=$2
DEPENDENCY=$3
DEPLOY_ENVS=$4

# jenkins 凭证
CERTIFICATE="wanna:119d3f8b35f947f6921910e561998e3299"

if  [ ! -n "$PROJECTS" ]; then
    echo "input project name; eg:【 ./auto_update.sh project1,project2 version/1.9.1 feat/add_contlevel test 】"
    exit 0
fi

if  [ "$PROJECTS" = "all" ]; then
    PROJECTS=${ALL_PROJECT}
fi

if  [ ! -n "$TARGET_BRANCH" ]; then
    echo "input target branch name; eg:【 ./auto_update.sh project1,project2 version/1.9.1 feat/add_contlevel test 】"
    exit 0
fi

if  [ ! -n "$DEPENDENCY" ]; then
    DEPENDENCY="main"
fi

if  [ ! -n "$DEPLOY_ENVS" ]; then
    DEPLOY_ENVS="local01-test"
fi


PROJECT_NAME=(${PROJECTS//,/ })

# get crumbs for CSRF
JENKINS_CRUMB=$(curl -s 'https://jenkins-k8s.****.com/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)' --user $CERTIFICATE |grep Jenkins-Crumb| awk -F':' '{print $2}')
echo $JENKINS_CRUMB

# 拼接环境
IFS=',' read -r -a ENV_ARRAY <<< "$DEPLOY_ENVS"
ENV_COUNT=${#ENV_ARRAY[@]}
if [ $ENV_COUNT -gt 1 ]; then
    for i in ${ENV_ARRAY[@]}; do
      if [ $i == ${ENV_ARRAY[0]} ]; then
        DEPLOY_ENVS_STR="%5B%22$i%22"
      else
        DEPLOY_ENVS_STR="$DEPLOY_ENVS_STR%2C+%22$i%22"
      fi
    done

    DEPLOY_ENVS_STR="$DEPLOY_ENVS_STR%5D"

else
    DEPLOY_ENVS_STR="%22${ENV_ARRAY[0]}%22"
fi

# 手动发一次jenkins后拷贝提交的请求里面的json字段
FORM_DATA_TEMPLATE="json=%7B%22parameter%22%3A+%5B%7B%22name%22%3A+%22branch%22%2C+%22value%22%3A+%22$TARGET_BRANCH%22%2C+%22quickFilter%22%3A+%22%22%7D%2C+%7B%22name%22%3A+%22deploy_envs%22%2C+%22value%22%3A+$DEPLOY_ENVS_STR%7D%2C+%7B%22name%22%3A+%22build_for_vest%22%2C+%22value%22%3A+false%7D%2C+%7B%22name%22%3A+%22is_g%22%2C+%22value%22%3A+$IS_G%7D%5D%2C+%22statusCode%22%3A+%22303%22%2C+%22redirectTo%22%3A+%22.%22%2C+%22Jenkins-Crumb%22%3A+%22$JENKINS_CRUMB%22%7D&Submit=Build"



# 切到工作目录
cd $WORK_DIR

for PROJECT in ${PROJECT_NAME[@]}; do
    echo "$PROJECT start..."
    #  下载项目
    if [ -d "${PROJECT}" ]; then
        echo "$PROJECT exists"
    else
        echo "cloning $PROJECT"
        git clone ssh://git@git.***.com/$PROJECT.git
    fi
    # 切换到项目目录
    cd $PROJECT
    exists_in_remote=`git ls-remote --heads origin $TARGET_BRANCH`
    # 远程分支不在就创建
    if [ -z "$exists_in_remote" ]; then
        echo "Branch name $TARGET_BRANCH doesn't exist in remote repository. Pushing it now."
        git checkout main
        git checkout -b $TARGET_BRANCH
        git push -u origin $TARGET_BRANCH
    else
        git checkout $TARGET_BRANCH
        git pull --rebase
    fi

    # 切换到指定的分支

    # 拉取最新代码
    git pull -f

    # 更新指定的依赖包
    go get -u git.***.com/common@$DEPENDENCY
    go mod tidy

    # 提交并推送更新
    git add go.mod go.sum
    git commit -m "update common@$DEPENDENCY"
    git push origin $TARGET_BRANCH

    echo "send to jenkins build"

    curl "https://jenkins-k8s.***.com/job/game/job/$PROJECT/build?delay=0sec" \
        --user $CERTIFICATE \
        --data-raw "$FORM_DATA_TEMPLATE" \
        --compressed

    echo "$PROJECT end"
    echo "========================================================================================================"
    cd ..
done



# 使用方法:
# 第一个参数: 需要更新的项目用","隔开 如果传all 则是更新所有人的所有项目
# 第二个参数: 指定项目需要更新的分支
# 第三个参数: common的分支名字 一般是feat/*** 默认不填则为main
# 第四个参数: 需要发布的环境,一般是test, 是test时可以不填 (不能在不填第三个参数的情况下填第四个参数)
# ./auto_update.sh project1,project2 version/1.9.1 feat/add_contlevel dev 把project1,project2项目的version/1.9.1分支更新到common@feat/add_contlevel,并发布到dev环境
# ./auto_update.sh all version/1.9.1 feat/add_contlevel 把所有项目的version/1.9.1分支更新到common@feat/add_contlevel,并发布到test环境
# ./auto_update.sh all version/1.9.1  把所有项目的version/1.9.1分支更新到common@main,并发布到test环境
本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!