批量更新项目依赖&自动调用jenkins构建
背景
- 有10+个项目都依赖一个common仓库,每次修改common后都需要更新10+个项目的go mod
- 更新后还需要都去jenkins里面点构建
思路
- 在一个工作目录拉取需要更新的项目中的一个,如A项目
- 拉取后进入A项目目录
- 检测需要更新的分支是否存在
git ls-remote --heads origin $TARGET_BRANCH
- 存在则直接checkout过去,不存在则基于main分支新起一个$TARGET_BRANCH分支
- 更新依赖,运行
go get -u ****/common@依赖的分支 go mod tidy git add go.mod go.sum git commit -m "update common@$DEPENDENCY" git push origin $TARGET_BRANCH`
- 获取个人 jenkins API Token 网页路径 https://jenkins-k8s.***.com/user/wanna/configure
- 获取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
- 去jenkins点击项目构建后复制出请求的curl
- 替换项目名和crumbs并运行新的curl
- 切换到上级目录
- 重复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 协议》,转载必须注明作者和本文链接