简介
使用过git的开发者都知道,这是一个很好用的代码管理工具。
网上已有很多在线的git管理平台,如github、gitee等,但有一些限制,如:
- 有成员人数限制。github免费的私有库最多3人,gitee为5人;
- github网速慢;
- 代码曝露在公网上(虽然可以设置私有库)
我们就需要一款开源的、可搭在本地的可视化git产品。这里比较有名的就是Gitlab了,是面向企业的,但是其占用的资源也很大。
本文介绍的就是另一款轻量级产品:Gitea。
下文演示环境为Centos 7.9。
注:要有Linux、Docker基础
安装
Gitea有多种安装方式,最简单的就是在官网https://dl.gitea.io/gitea下载对应版本文件,上传至服务器后添加执行权限并运行,给定web参数,例如:
wget -O gitea https://dl.gitea.io/gitea/1.18/gitea-1.18-linux-amd64
chmod +x gitea
./gitea web
然后通过http://
Gitea可选自带的SQLite3数据库,也可以选装其他性能好的,包括MySQL、PostgreSQL、MSSQL或 TiDB (MySQL协议) 等。
若用别的数据库,采用上述简单方式后,需要再额外安装数据库。
为了更好地管理安装的产品,也是顺应网络潮流,我们下文展示Docker安装方法。
Docker
经过多次的发展及命名变更,现在的docker分为社区版Community Edition (CE) 和 企业版Enterprise Edition (EE)。
我们这里使用开源的社区版。本节命令使用root用户执行,参考自官方网站https://docs.docker.com/engine/install/centos/
卸载
如果系统里已安装旧版docker,想要升级的,先执行命令卸载:
echo ">>>>>>>>>>>>>>>>>>>>1.1 Stopping docker service"
systemctl stop docker.socket
systemctl stop docker.service
echo ">>>>>>>>>>>>>>>>>>>>1.2 Removing docker files"
rm -rf /etc/docker
rm -rf /run/docker
rm -rf /var/lib/dockershim
rm -rf /var/lib/docker
echo ">>>>>>>>>>>>>>>>>>>>1.3 Uninstalling docker rpms"
yum remove -y docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine \
docker-ce \
docker-ce-cli \
docker-ce-rootless-extras \
docker-scan-plugin \
container-selinux \
containerd.io \
docker-compose-plugin
安装
执行命令(社区版的docker包后缀为-ce):
echo ">>>>>>>>>>>>>>>>>>>>2.1 Installing docker"
yum -y install yum-utils
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum -y install docker-ce docker-ce-cli containerd.io docker-compose-plugin
# 验证安装
docker -v
启动
echo ">>>>>>>>>>>>>>>>>>>>3.1 Starting docker"
systemctl enable docker.service #开机自启
systemctl start docker.service
Gitea
Gitea不能以root用户运行,所以要创建一个用户来运行。使用root用户执行本节命令,参考自官方网站https://docs.gitea.io/zh-cn/install-with-docker/
创建用户
root用户执行命令:
useradd -g docker gitea
这里指定了用户组为docker(安装docker时自动创建的),这样用户gitea就可以直接使用docker相关命令
拉取镜像
后续使用mysql数据库,本处拉取2个镜像:
docker pull gitea/gitea
docker pull mysql
#查看所有镜像文件
docker images
创建容器目录
我们将所有容器映射到宿主机的目录放在一起,方便管理,大致目录结构:
本小节开始,使用gitea用户执行后续命令。
mkdir -p ~/workspace/containers/gitea
mkdir -p ~/workspace/containers/mysql
创建配置文件
我们使用docker compose插件,通过配置文件来启停服务。
配置文件gitea-compose.yml放在~/workspace/containers下(文件名可自定义),内容:
version: "3"
networks:
gitea:
services:
server:
image: gitea/gitea:latest
container_name: gitea
extra_hosts:
<HOST_NAME>: <HOST_IP>
environment:
- USER_UID=<USER_UID>
- USER_GID=<USER_GID>
- GITEA__database__DB_TYPE=mysql
- GITEA__database__HOST=db:3306
- GITEA__database__NAME=gitea
- GITEA__database__USER=gitea
- GITEA__database__PASSWD=gitea
restart: always
networks:
- gitea
volumes:
- ./gitea:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- "13000:3000"
- "13022:22"
depends_on:
- db
db:
image: mysql:latest
container_name: mysql
restart: always
environment:
- MYSQL_ROOT_PASSWORD=gitea
- MYSQL_USER=gitea
- MYSQL_PASSWORD=gitea
- MYSQL_DATABASE=gitea
networks:
- gitea
volumes:
- ./mysql:/var/lib/mysql
<HOST_NAME>、<HOST_IP>替换为宿主机域名、IP;
另有2处需要替换:<USER_UID>和<USER_GID>,值为gitea用户的ID及其用户组ID,可通过下述命令分别获取:
id -u gitea
id -g gitea
其他的密码、端口等设置,可自视情况调整。
启动服务
gitea用户下执行:
cd ~/workspace/containers
docker compose -f gitea-compose.yml up -d
至此,Gitea即可登录使用了!登录网址:http://
使用
首次登录
首次打开登录页,会弹出初始配置。
第一部分是数据库,值已自动填入,与gitea-compose.yml中设置的一致œ:
下划页面可以看到一般设置:
划到最后的可选设置,我们创建一个管理员账号:
最后点击立即安装即可,过几秒会自动跳转至首页(如果未跳转,刷新下页面):
设置
个人设置
点击页面右上角的个人链接:
可以设置个人的一些相关信息:
创建组织
可以创建一个组织,将某个项目上的代码仓库、开发人员归入该组织进行管理。
点击左上角的用户名,选择创建组织:
输入组织名,并根据需要选择组织属性:
点击创建组织后,首页变更为当前组织:
点击右上角的访问按钮,弹出组织的相关信息:
可以看到,当前还没有仓库,组织成员、组织团队都是1个,即创建者。
Owners团队是组织的管理者,可以设置组织团队、组织下的仓库。
可以由各自开发员登录Gitea时自己注册账户,也可以由管理员在"管理后台"的"帐户管理"页签创建。
分支保护
创建了仓库后,点击仓库名可以进入仓库界面,点击右侧的设置,选择分支:
勾选"启用分支保护"即可,该分支的代码则只支持合并:
持续发布
这里贴上一张CICD工具对比图:
下文,我们将演示使用Drone完成持续发布。
安装Drone
参考官方文档https://docs.drone.io/server/overview/
拉取镜像
执行docker命令拉取drone镜像:
docker pull drone/drone
docker pull drone/drone-runner-docker
配置
为了与Gitea集成,需要在Gitea账户上做些设置(参考https://docs.drone.io/server/provider/gitea/)。
OAuth2
OAuth2的用处:登录某网站时,不用该网站账号,而是微信账号。
在个人设置的"应用"页签,填写应用名称及重定向URI(URI为Drone的登录地址,端口在后续设置中会引用到):
暂存生成的客户端ID及秘钥:
通信秘钥
在Drone服务端和运行端之间的通信秘钥,执行命令:
openssl rand -hex 16
暂存该命令生成的16位随机码
配置文件
在服务器gitea用户的目录~/workspace/containers下创建文件drone-compose.yml:
version: "3"
services:
drone-server:
image: drone/drone:latest
container_name: drone-server
restart: always
ports:
- "13080:80"
extra_hosts:
<HOST_NAME>: <HOST_IP>
volumes:
- ./drone:/data
environment:
- DRONE_GITEA_SERVER=http://<HOST_NAME>:13000
- DRONE_GITEA_CLIENT_ID=<CLIENT_ID>
- DRONE_GITEA_CLIENT_SECRET=<CLIENT_SECRET>
- DRONE_RPC_SECRET=<RPC_SECRET>
- DRONE_SERVER_HOST=<HOST_NAME>:13080
- DRONE_SERVER_PROTO=http
- DRONE_GIT_ALWAYS_AUTH=true
- DRONE_USER_CREATE=username:<GITEA_USERNAME>,admin:true
drone-runner:
image: drone/drone-runner-docker:latest
container_name: drone-runner
restart: always
ports:
- "13010:3000"
extra_hosts:
<HOST_NAME>: <HOST_IP>
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- TZ="Asia/Shanghai"
- DRONE_RPC_HOST=<HOST_NAME>:13080
- DRONE_RPC_PROTO=http
- DRONE_RPC_SECRET=<RPC_SECRET>
- DRONE_RUNNER_NAME=drone-runner
- DRONE_RUNNER_CAPACITY=2
替换该配置文件中的:
- <HOST_NAME>:运行Drone的主机域名
- <HOST_IP>:运行Drone的主机IP
- <CLIENT_ID>、<CLIENT_SECRET>:Gitea上生成的OAuth2 ID
- <RPC_SECRET>:上一步生成的通信秘钥
- <GITEA_USERNAME>:Gitea帐户名
启动
修改完配置文件后,在同目录下创建子目录drone,然后启动Drone服务:
docker compose -f drone-compose.yml up -d
输入登录地址http://
点击CONTINUE按钮,跳转Gitea认证页面:
点击应用授权后,自动跳转回Drone注册页:
输入Gitea帐户的邮箱、用户名即可,点击SUBMIT,会自动跳转至首页:
这里列出了Gitea账户的仓库,点击仓库名,跳转其设置页面:
启用Trusted,然后保存即可:
同时,可以在Gitea的该仓库设置中,看到Web钩子中多了一项:
使用
简单例子
在仓库根目录创建文件".drone.yml",内容:
kind: pipeline
type: docker
name: Test
clone:
disable: true
steps:
- name: test
pull: if-not-exists
image: alpine
commands:
- whoami
- pwd
保存后,会自动触发一次构建,但是会失败。在Web钩子的设置界面最后:
这里需要额外设置一步,将Drone的服务器加进Gitea白名单。
编辑Gitea容器的设置文件app.ini(<Gitea容器映射在宿主机的目录>/gitea/conf/app.ini,本文即为~/workspace/containers/gitea/gitea/conf/app.ini),添加:
[webhook]
ALLOWED_HOST_LIST = <宿主机Host>
重启Gitea容器:
docker compose -f gitea-compose.yml down
docker compose -f gitea-compose.yml up -d
点击上图测试按钮下的刷新图标,重新触发,可以看到构建成功:
在Drone页面也可以看到成功记录:
点击仓库名后:
点击第二次构建后:
可以看到左侧是我们定义的构建名(Test)和步骤名(test),右侧是执行的命令及对应结果。
因为是第一次触发构建,本地没有alpine镜像,日志中会显示下载记录。
EBS
概述
前面演示的简单案例中,用的是Docker类型通道,也就是每个步骤都会引用一个镜像来执行对应步骤。
各步骤之间共享一个虚拟目录/drone/src,在构建结束后,该目录会删除。
现在有一种需求,将增量代码发布到多个环境中去。找了很多镜像,没有找到合适的,最终改用EXEC类型的通道,直接在宿主机端执行脚本部署。
大致步骤:
- 获取增量代码
- 在宿主机执行git diff命令获取增量代码
- 发布到指定环境
- 在.drone.yml中配置,每个环境配置一个步骤
- 在步骤中执行同样的脚本,将增量代码发送到目标环境,并在目标环境调用指定脚本。
这里使用sshpass命令,可以免交互的调用scp、ssh等命令
- 前面步骤成功后,将本次构建的git提交ID更新入配置文件,以供下次获取增量代码使用
这里涉及到3个新设置:
- 安装EXEC类型的Runner
- 安装git命令
- 安装sshpass命令
安装
EXEC Runner
参考官方文档https://docs.drone.io/runner/exec/installation/linux/,root用户执行:
wget https://github.com/drone-runners/drone-runner-exec/releases/download/v1.0.0-beta.10/drone_runner_exec_linux_amd64.tar.gz
tar -xzvf drone_runner_exec_linux_amd64.tar.gz
install -t /usr/local/bin drone-runner-exec
mkdir /etc/drone-runner-exec
mkdir /var/log/drone-runner-exec
在/etc/drone-runner-exec下创建配置文件config:
DRONE_RPC_PROTO=http
DRONE_RPC_HOST=<HOST_NAME>:13080
DRONE_RPC_SECRET=<RPC_SECRET>
DRONE_LOG_FILE=/var/log/drone-runner-exec/log.txt
DRONE_LOG_FILE_MAX_SIZE=10
DRONE_LOG_FILE_MAX_AGE=30
DRONE_UI_USERNAME=drone
DRONE_UI_PASSWORD=drone
替换<HOST_NAME>、<RPC_SECRET>,与drone-compose.yml中一致。
然后启动:
drone-runner-exec service install
drone-runner-exec service start
tail -10 /var/log/drone-runner-exec/log.txt
可以看到成功连接到Server:
服务器命令
安装git、sshpass
yum -y install git
yum -y install sshpass
简单案例
修改.drone.yml为:
kind: pipeline
type: exec
name: Test
clone:
disable: true
steps:
- name: test
commands:
- whoami
- pwd
提交后,可以看到Drone中成功构建:
EBS部署配置
配置ssh
gitea用户下执行(替换自己的邮箱):
ssh-keygen -t rsa -C "[email protected]"
cat /home/gitea/.ssh/id_rsa.pub
将id_rsa.pub的内容复制到Gitea的账户设置下:
点击验证:
按提示执行命令(注意将命令最后的路径替换为ssh key的路径,默认为~/.ssh):
操作要快一点,防止超时。
gitea帐户执行:
git clone <ssh url>
主要是为了建立host认证,后续自动部署时不失败:
克隆后,可以删除仓库目录。
部署目录
下载deploy目录(https://pan.baidu.com/s/1hNHNi6-4XZ0Fd3XCO-IkTQ,提取码:a8kb),上传到gitea用户的~/workspace下
.drone.yml
kind: pipeline
type: exec
name: Test For EBS Deploy
clone:
disable: true
steps:
- name: Generate Incremental Codes
commands:
- su - gitea -c "bash ~/workspace/deploy/scripts/01_GenIncrementalCodes.sh $DRONE_GIT_SSH_URL $DRONE_REPO_NAME $DRONE_BRANCH $DRONE_COMMIT"
- name: Deploy Codes In DEV
environment:
TARGET_HOST: 172.16.135.143
TARGET_USER: strive
TARGET_PSWD: xxxxxx
TARGET_PORT: 22
APPS_PSWD: APPS
CUX_PSWD: CUX
commands:
- su - gitea -c "bash ~/workspace/deploy/scripts/02_SendAndInstall.sh $TARGET_HOST $TARGET_USER $TARGET_PSWD $TARGET_PORT $APPS_PSWD $CUX_PSWD $DRONE_COMMIT"
- name: Deploy Codes In SIT
environment:
TARGET_HOST: 172.16.135.141
TARGET_USER: strive
TARGET_PSWD:
from_secret: SIT_STRIVE_PSWD
TARGET_PORT: 22
APPS_PSWD: APPS
CUX_PSWD: CUX
commands:
- su - gitea -c "bash ~/workspace/deploy/scripts/02_SendAndInstall.sh $TARGET_HOST $TARGET_USER $TARGET_PSWD $TARGET_PORT $APPS_PSWD $CUX_PSWD $DRONE_COMMIT"
- name: Reset Config
commands:
- su - gitea -c "bash ~/workspace/deploy/scripts/03_ResetConfig.sh $DRONE_COMMIT"
上面的.drone.yml中,设置了四个步骤:
获取增量代码
su - gitea -c "bash ~/workspace/deploy/scripts/01_GenIncrementalCodes.sh $DRONE_GIT_SSH_URL $DRONE_REPO_NAME $DRONE_BRANCH $DRONE_COMMIT"
这里切换到gitea用户,并调用脚本01_GenIncrementalCodes.sh,传入参数:GIT仓库克隆路径、仓库名、分支名、提交ID。
DRONE开头的这些变量是Drone自带的,全部变量可在任意步骤下调用env命令,然后在构建日志中查看。
获取增量代码的脚本01_GenIncrementalCodes.sh:
set -e
echo "------------------1. Setting parameters value------------------"
DRONE_GIT_SSH_URL=$1
DRONE_REPO_NAME=$2
DRONE_BRANCH=$3
DRONE_COMMIT=$4
echo "------------------2. Sychronizing repository------------------"
cd ~/workspace/deploy/repository
if [ -e $DRONE_REPO_NAME ]; then
echo ">>>>>>>>>>>>>>>>Pulling Repository"
cd $DRONE_REPO_NAME
git pull --progress -v --no-rebase origin
else
echo ">>>>>>>>>>>>>>>>Clonning Repository"
git clone $DRONE_GIT_SSH_URL
cd ./$DRONE_REPO_NAME
fi
echo "------------------3. Checkouting trigger branch------------------"
git checkout -B $DRONE_BRANCH origin/$DRONE_BRANCH
git branch
echo "------------------4. Getting last commit ID------------------"
source ~/workspace/deploy/config/deploy.cfg
if [ -z "$LAST_COMMIT_ID" ]; then
echo "Getting First Commit ID"
LAST_COMMIT_ID=$(git log --oneline --format='%h' | tail -1)
fi
echo "LAST_COMMIT_ID=$LAST_COMMIT_ID"
echo ""
echo "------------------5. Generating incremental codes------------------"
CURRENT_TIME=$(date "+%Y%m%d%H%M")
echo "Adding new directory: $CURRENT_TIME"
mkdir ~/workspace/deploy/codes/$CURRENT_TIME
git archive --format=zip -o ~/workspace/deploy/codes/$CURRENT_TIME/IncrementalCodes.zip HEAD $(git diff $LAST_COMMIT_ID..$DRONE_COMMIT --name-only)
cp ~/workspace/deploy/scripts/install* ~/workspace/deploy/codes/$CURRENT_TIME
sed -i "s/\(INSTALLING_DIR=\)\(.*\)/\1$CURRENT_TIME/" ~/workspace/deploy/config/deploy.cfg
这里的逻辑大致为:
- 接收调用时传入的参数值;
- 判断~/workspace/deploy/repository下有无触发构建的仓库名目录,无则克隆仓库,有则拉取最新代码;
- 切换到触发构建的分支
- ~/workspace/deploy/config/deploy.cfg中存储的是键值对,通过source命令,将上次构建的最新提交ID读至变量LAST_COMMIT_ID;
若为空,则通过命令"git log --oneline --format='%h' | tail -1"获取第一次提交ID - 根据上次提交ID及本次提交ID,通过命令git diff导出增量代码,放到~/workspace/deploy/codes/$CURRENT_TIME下;
其中CURRENT_TIME为当前时间,格式为"年月日时分" - 将EBS代码安装脚本install.pl、install.cfg一起复制到~/workspace/deploy/codes/$CURRENT_TIME
- 将配置文件中INSTALLING_DIR对应的值置为当前时间$CURRENT_TIME
部署至DEV环境
首先是设置了几个环境变量:
environment:
TARGET_HOST: 172.16.135.143
TARGET_USER: strive
TARGET_PSWD: xxxxxx
TARGET_PORT: 22
APPS_PSWD: APPS
CUX_PSWD: CUX
这里列出了要部署到的环境信息,包括IP、用户、密码、数据库用户密码(APPS/CUX)。
注意不能有空值,测试时发现给空时,构建会卡住无反应,日志也无报错。
然后是在目标环境安装增量代码:
su - gitea -c "bash ~/workspace/deploy/scripts/02_SendAndInstall.sh $TARGET_HOST $TARGET_USER $TARGET_PSWD $TARGET_PORT $APPS_PSWD $CUX_PSWD $DRONE_COMMIT"
脚本02_SendAndInstall.sh:
set -e
echo "------------------1. Setting parameters value------------------"
# 接收脚本参数
TARGET_HOST=$1
TARGET_USER=$2
TARGET_PSWD=$3
TARGET_PORT=$4
APPS_PSWD=$5
CUX_PSWD=$6
DRONE_COMMIT_ID=$7
source ~/workspace/deploy/config/deploy.cfg
# Shell变量名中不可出现".",替换TARGET_HOST中的"."为"_"
REPLACED_HOST="H${TARGET_HOST//./_}"
echo "Replaced HOST: $REPLACED_HOST, Current commit ID: ${!REPLACED_HOST}, Drone commit ID: $DRONE_COMMIT_ID"
# 当前TARGET_HOST的提交ID与触发部署的提交ID不一致时
if [ ! "${!REPLACED_HOST}" == $DRONE_COMMIT_ID ]; then
echo "------------------2. Sending codes to $TARGET_USER@$TARGET_HOST------------------"
sshpass -p $TARGET_PSWD ssh -o StrictHostKeyChecking=no -p $TARGET_PORT $TARGET_USER@$TARGET_HOST "echo ''"
sshpass -p $TARGET_PSWD scp -P $TARGET_PORT -r ~/workspace/deploy/codes/$INSTALLING_DIR $TARGET_USER@$TARGET_HOST:/home/$TARGET_USER/workspace
echo "------------------3. Calling remote install script------------------"
sshpass -p $TARGET_PSWD ssh -o StrictHostKeyChecking=no -p $TARGET_PORT $TARGET_USER@$TARGET_HOST "cd ~/workspace/$INSTALLING_DIR/; bash install.sh $APPS_PSWD $CUX_PSWD"
echo "------------------4. Setting new commit ID------------------"
# 远程机HOST不存在于配置文件中时,加一行
if [ ! "${!REPLACED_HOST}" ]; then
echo "$REPLACED_HOST=$DRONE_COMMIT_ID" >> ~/workspace/deploy/config/deploy.cfg
# 存在时,替换
else
sed -i "s/\($REPLACED_HOST=\)\(.*\)/\1$DRONE_COMMIT_ID/" ~/workspace/deploy/config/deploy.cfg
fi
# 当前TARGET_HOST的提交ID与触发部署的提交ID一致时,跳过处理
else
echo ">>>>>>>>>>>>>Already deployed successfully, skip left steps."
fi
这里的逻辑大致为:
- 接收调用时传入的参数值;初始化~/workspace/deploy/config/deploy.cfg中的配置;
此配置中存放了各环境的已部署的提交ID,环境键值为H+IP;
因为环境变量不能以数字开头,也不能包含点,所以用H拼在开头,IP中的"."也替换成"_" - 若已部署的提交ID与此次触发构建的提交ID一致,则跳过剩余步骤,否则继续;
- 首次登录时会将目标host加入~/.ssh/known_hosts,所以先调用一次ssh, 给定参数-o StrictHostKeyChecking=no,实现默认添加;
- 调用scp命令将~/workspace/deploy/codes/$INSTALLING_DIR,发送到目标环境用户的/home/$TARGET_USER/workspace
- 调用ssh命令,远程登录目标环境,并调用install.sh命令,完成安装;
- 因为前面调用了set -e,安装失败时会直接中断构建;
若安装成功,则更新此环境部署的提交ID
install.sh
在目标环境执行的安装脚本,内容为:
# 1. 获取配置信息
GetConfig(){
# 任意一行代码出错则退出
set -e
echo " >>>>>>>>>>>>>>>>>>>>>>>>3.1 Setting parameters value>>>>>>>>>>>>>>>>>>>>>>>>"
# 初始化上下文
#source ~/.bash_profile
# 接收参数传入的APPS/CUX密码
APPS_PSWD=$1
CUX_PSWD=$2
[ -z "$APPS_PSWD" ] && APPS_PSWD=apps #为空时赋默认值
[ -z "$APPS_PSWD" ] && APPS_PSWD=apps #为空时赋默认值
# 设置文件变量
CURRENT_DIR=$(cd `dirname $0`; pwd)
CFG_FILE=$CURRENT_DIR/install.cfg
LOG_FILE=$CURRENT_DIR/install.log
ERR_FILE=$CURRENT_DIR/install.err
echo "" > $LOG_FILE
# 解压代码文件
mkdir code
unzip -q -d ./code IncrementalCodes.zip
}
# 2. 批量安装(若代码结构不是标准的objectlist,可修改此处)
BatchInstall(){
echo " >>>>>>>>>>>>>>>>>>>>>>>>3.2 Installing>>>>>>>>>>>>>>>>>>>>>>>>"
for loop_num in 1
do
sleep 1
#perl install.pl installpath=$CURRENT_DIR cfgfile=$CFG_FILE appsusr=APPS appspwd=$APPS_PSWD dbschemapwd=$CUX_PSWD logfile=$LOG_FILE
done
}
# 3. 导出报错内容
ExpErrorMsg(){
echo " >>>>>>>>>>>>>>>>>>>>>>>>3.3 Exporting error file>>>>>>>>>>>>>>>>>>>>>>>>"
STEP_NAME=""
STEP_FLAG=true
ERROR_FLAG=false
ERROR_MSG=""
# 遍历行读取日志文件install.log
while read ROW_CONTENT
do
# 读到每个大类(表、包头、Form等)开始安装的日志时,写入上个脚本执行结果、初始化错误标志、记录当前大类
if [[ "$ROW_CONTENT" =~ ^"# install step".* ]]; then
WriteErrorMsg
STEP_NAME=$ROW_CONTENT
STEP_FLAG=false
# SQL类脚本,若有非ORA-00955(同名创建)错误或SP2开头错误,标记出错
elif [[ ("$ROW_CONTENT" =~ ^ORA-.* && ! "$ROW_CONTENT" =~ ^ORA-00955.*) || "$ROW_CONTENT" =~ ^SP2-.* ]]; then
ERROR_FLAG=true
# 程序包编译失败,标记出错
elif [[ "$ROW_CONTENT" =~ ^"created with compilation errors".* ]]; then
ERROR_FLAG=true
# Form编译失败,标记出错
elif [[ "$ROW_CONTENT" =~ ^"Form not created".* ]]; then
ERROR_FLAG=true
# SQL类脚本开始执行,写入上个脚本执行结果,并初始化错误标志
elif [[ "$ROW_CONTENT" =~ ^run.* ]]; then
WriteErrorMsg
# Form开始编译,写入上个脚本执行结果,并初始化错误标志
elif [[ "$ROW_CONTENT" =~ ^frmcmp_batch.* ]]; then
WriteErrorMsg
fi
# 拼接单个脚本的执行日志
ERROR_MSG="$ERROR_MSG$ROW_CONTENT\n"
done < $LOG_FILE
# 最后一个脚本执行结果处理
WriteErrorMsg
# 如果错误日志大小不为0,则有错误,返回错误码
if [ -s "$ERR_FILE" ] ; then
echo "Installation failed:"
cat $ERR_FILE
exit 1
fi
}
# 3.1-错误信息写入文件
WriteErrorMsg(){
# 若由错误
if [ $ERROR_FLAG = true ]; then
# 若大类未写入错误文件,则先写入
if [ $STEP_FLAG != true ]; then
echo "$STEP_NAME" >> $ERR_FILE
STEP_FLAG=true
fi
# echo -e,转义后文本,即有换行
# 将脚本及报错内容写入错误文件
echo -e "$ERROR_MSG" | while read TMP_MSG
do
echo "$TMP_MSG" >> $ERR_FILE
done
echo "------------------------------------------" >> $ERR_FILE
fi
# 重置错误标记
ERROR_FLAG=false
ERROR_MSG=""
}
GetConfig $1 $2 # 1. 获取配置信息
BatchInstall # 2. 批量安装
ExpErrorMsg # 3. 导出报错内容
大致逻辑就是:
- 读取被调用时传入的参数值;
- 调用perl install.pl 执行安装;
- 读取安装日志install.log,判断有无数据库对象(表、视图、包等)编译错误、Form编译失败,有则结束程序,返回错误状态1
这里为了模拟测试通过,注释掉了source ~/.bash_profile和perl install.pl命令,实际使用时需放开。
部署至SIT环境
与部署至DEV环境一致,为了测试多个环境而设。
类似的,若项目上有多个环境,复制一份此步骤出来,修改对应环境信息即可。
设置配置文件
最后一步,将本次触发构建的提交ID更新回设置文件
# 全部环境部署成功后,更新配置文件中的提交ID
set -e
DRONE_COMMIT=$1
sed -i "s/\(LAST_COMMIT_ID=\)\(.*\)/\1$DRONE_COMMIT/" ~/workspace/deploy/config/deploy.cfg
优化设置
触发条件
搭建好的Web钩子默认是全分支、全事件触发的,项目上实际使用时,不用这么频繁,设置为特定分支变动即触发即可。
打开Web钩子设置:
下划到事件设置:
只保留"推送"事件,指定特定分支。
点击最下方的"更新钩子"按钮。
分支保护
启用触发构建分支的保护,并设置审批白名单。
在前面介绍过的分支保护设置中,下划到审批白名单:
"所需的批准"为必要的审批人数;
批准的用户或团队里,可以设置审批人,或专门建立一个审批团队:组织的团队里再新建一个团队,然后加入到协作者:
审批路径:
操作人员
包括项目管理者在内,不设置在仓库的Owners团队中,因为有超级权限,可以越过审批直接合并。
为防止误操作,管理员账户非必要不适用,每个人单独创建自己的账号。
至此,可以模拟项目开发场景:
- 每个开发员创建各自开发分支,推送到远程仓库;
- 每个开发员发起合并到指定分支;
- 管理者从指定分支发起合并到触发构建的分支,因为加了审批人,需要额外一步审批操作,防止误点;
- 审批后,点击合并,自动触发构建
构建样例
测试时的构建日志,增量代码生成:
已部署过,不再处理:
未部署过,触发部署:
最后更新配置文件:
若某步出错,则会中断构建:
修正后,可以点击右上角的Restart来重新构建:
标签:Gitea,TARGET,gitea,drone,DRONE,docker,ID From: https://www.cnblogs.com/star-tong/p/17013675.html