Gitea
简介
使用过git的开发者都知道,这是一个很好用的代码管理工具。
网上已有很多在线的git管理平台,如github、gitee等,但有一些限制,如:
- 有成员人数限制。github免费的私有库最多3人,gitee为5人;
- github网速慢;
- 代码曝露在公网上(虽然可以设置私有库)
有时我们需要一款开源的、可搭在本地的可视化git产品。这里比较有名的就是Gitlab了,是面向企业的,但是其占用的资源也很大。
本文介绍的就是另一款轻量级产品:Gitea。
下文演示环境为虚拟机Centos 7.9,CPU架构为AMD(x86_64)(可用arch命令查看)。
阅读本文需要有Linux、Docker基础
安装
Gitea有多种安装方式,最简单的就是在官网https://dl.gitea.io/gitea下载源文件,然后在服务器端直接运行:
wget -O gitea https://dl.gitea.io/gitea/1.18/gitea-1.18-linux-amd64
chmod +x gitea
./gitea web
通过http://hostname:3000即可访问。
Gitea可选自带的SQLite3数据库,也可以选装其他性能好的,包括MySQL、PostgreSQL、MSSQL或 TiDB (MySQL协议) 等。
若用别的数据库,采用上述方式安装后,需要再额外安装数据库。
为了与Drone统一安装方式,更好地管理安装的产品,下文将展示通过Docker安装的方法。
安装项较多,整合了一个Gitea、Drone的安装脚本,参考最后一个章节快速安装。接下来的2个章节为该脚本的拆解。
Docker
经过多次的发展及命名变更,现在的docker分为社区版Community Edition (CE) 和 企业版Enterprise Edition (EE)。
我们这里使用开源的社区版。本节命令使用root
用户执行,参考自官方网站Docker安装
卸载
如果系统里已安装旧版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
用户执行本节命令,参考自官方网站Gitea安装
创建用户
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://hostname:13000
不使用-f参数指定文件时,docker compose命令会查找docker-compose.yml文件
使用
首次登录
首次打开登录页,会弹出初始配置。
第一部分是数据库,根据gitea-compose.yml中的设置已自动填入:
下划页面可以看到一般设置:
划到最后的可选设置,我们创建一个管理员账号:
最后点击立即安装即可,过几秒会自动跳转至首页(如果未跳转或页面报错,刷新下页面):
使用设置
个人设置
点击页面右上角的个人链接:
可以设置个人的一些相关信息:
创建组织
可以创建一个组织,将某个项目上的代码仓库、开发人员归入该组织进行管理。
点击左上角的用户名,选择创建组织:
输入组织名,并根据需要选择组织可见性:
点击创建组织后,首页变更为当前组织:
点击右上角的访问按钮,弹出组织的相关信息:
可以看到,当前还没有仓库,组织成员、组织团队都仅1个,即创建者。
Owners团队是组织的管理者,可以设置组织团队、组织下的仓库。
可以由各开发员登录Gitea时自己注册账户,也可以由管理员在"管理后台"的"帐户管理"页签创建。
分支保护
创建了仓库后,点击仓库名可以进入仓库界面,点击右侧的设置,选择分支:
勾选"启用分支保护"即可,该分支的代码则只支持合并:
持续发布
现有的持续发布/持续集成产品有很多,这里贴上部分流行的CICD工具对比图:
下文中,我们将演示使用Drone完成持续发布。
安装Drone
参考官方文档Drone Server安装
拉取镜像
执行docker命令拉取drone及其docker类型runner的镜像:
docker pull drone/drone
docker pull drone/drone-runner-docker
配置
OAuth2
OAuth2的用处:登录某网站时,不用该网站账号,而是第三方账号,例如有些网站可以直接微信登录。
在Gitea上创建OAuth2应用,使Drone可以直接使用Gitea账户登录。
在个人设置的"应用"页签,填写应用名称及重定向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://hostname:13080/
点击CONTINUE按钮,会跳转Gitea认证页面:
点击应用授权后,自动跳转回Drone注册页:
输入Gitea帐户的邮箱、用户名即可,点击SUBMIT,会跳转至Drone首页:
首页列出了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的Web钩子白名单。
添加白名单:
编辑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,在构建结束后,该目录会删除。
为了将增量代码
发布到多个环境
中去,找了很多镜像,没有找到比较合适的,要么会导致.drone.yml文件变得臃肿,要么不支持ssh到目标环境调用脚本时传参。
翻阅官方资料后,最终决定改用EXEC类型的通道,直接在宿主机端执行自定义脚本来完成构建。
下述自动部署的实现效果及主体逻辑:
- 获取增量代码
- 在宿主机执行git diff命令获取增量代码
- 发布到指定环境
- 在.drone.yml中配置,每个环境配置一个步骤
- 在步骤中执行同样的脚本,将增量代码发送到目标环境,并在目标环境调用指定脚本。
这里使用sshpass命令,可以免交互的调用scp、ssh等命令
当然,要是运行Drone的宿主机,添加到了目标环境的authorized_keys中,可以不安装sshpass命令。
- 更新配置文件
- 前面步骤成功后,将触发本次构建的git提交ID更新入配置文件,以供下次获取增量代码使用
按照上述逻辑,需要安装:
- EXEC类型的Runner
- git命令
- sshpass命令
本方法有个弊端,就是要自开发大量的脚本,对开发者来说是个不小的挑战。
安装
EXEC Runner
参考官方文档Exec Runner安装,目前尚未发布正式版:
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 Server信息、日志路径、日志单个文件大小(单位:M)、日志保留天数、可视化界面的登录用户及密码。
然后启动:
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 "xx@qq.com"
cat /home/gitea/.ssh/id_rsa.pub
将id_rsa.pub的内容复制到Gitea的账户设置下:
点击验证:
按提示执行命令(注意将命令最后的路径替换为ssh key的路径,默认为~/.ssh):
操作要快一点,防止超时。
演示环境的ssh命令版本较低,不支持上图中的-Y参数。如果升级ssh,步骤繁琐,而且影响很大,可以切到gitea容器内执行。
cp ~/.ssh/id_rsa* ~/workspace/containers/gitea/gitea #将ssh秘钥复制到容器目录下
docker exec -it gitea bash #进入容器
cd /data/gitea #进入复制有ssh秘钥的gitea目录
echo -n 'xxxx' | ssh-keygen -Y sign -n gitea -f id_rsa #执行上图中的签名命令
rm id_rsa* #删除秘钥
gitea
帐户执行:
git clone <ssh url>
主要是为了建立host认证,后续自动部署时不失败:
克隆后,可以删除仓库目录。
部署目录
下载docker/workspace/deploy目录(点此下载),上传到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中存储的是键值对:
- 获取增量代码
-
获取当前时间(格式为"年月日时分"),存入变量CURRENT_TIME,并创建目录~/workspace/deploy/codes/$CURRENT_TIME;
-
根据上次提交ID及本次提交ID,通过命令git diff导出增量代码,放到上步的目录中;
-
将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 "[ ! -e ~/workspace ] && mkdir ~/workspace"
sshpass -p $TARGET_PSWD scp -P $TARGET_PORT -r ~/workspace/deploy/codes/$INSTALLING_DIR $TARGET_USER@$TARGET_HOST:~/workspace
echo "------------------3. Calling remote install script------------------"
sshpass -p $TARGET_PSWD ssh -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
这里的逻辑大致为:
- 初始化:
- 接收调用时传入的参数值;
- 调用source命令,将部署配置文件(~/workspace/deploy/config/deploy.cfg)中的值赋到对应环境变量;
此配置中存放了各环境的已部署的提交ID,各目标环境键值为H+IP:
- 因为环境变量名不能以数字开头,也不能包含点,所以用H拼在开头,IP中的"."也替换成"_"
若已部署的提交ID与此次触发构建的提交ID一致,则跳过剩余步骤,否则继续:
- 发送代码:
- 调用ssh命令,在远程环境用户的主目录下创建workspace目录;
给定参数-o StrictHostKeyChecking=no,自动添加目标环境host至本机的~/.ssh/known_hosts中; - 调用scp命令将增量代码及其安装脚本,发送到目标环境用户的~/workspace下
- 调用ssh命令,在远程环境用户的主目录下创建workspace目录;
- 调用ssh命令,调用目标环境的install.sh命令,完成代码安装;
- 因为前面调用了set -e,安装失败时会直接中断构建;
若安装成功,则更新此环境部署的提交ID至部署配置文件(~/workspace/deploy/config/deploy.cfg)
install.sh:
前面通过ssh命令在目标环境运行了安装脚本,该脚本内容为:
# 1. 获取配置信息
GetConfig(){
# 任意一行代码出错则退出
set -e
echo " >>>>>>>>>>>>>>>>>>>>>>>>3.1 Setting parameters value>>>>>>>>>>>>>>>>>>>>>>>>"
# 初始化上下文
#source ~/.bash_profile
# 接收参数传入的APPS/CUX密码
APPS_PSWD=$1
CUX_PSWD=$2
# 设置文件变量
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 执行EBS代码安装;
- 读取安装日志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
优化设置
密码设置
在前面演示的.drone.yml中,部署至SIT环境的步骤里使用了from_secret:
- name: Deploy Codes In SIT
environment:
...
TARGET_PSWD:
from_secret: SIT_STRIVE_PSWD
这里是将密码设置在了Drone中:
同样的,使用到密码的地方都推荐使用此种方式,防止明文配置密码,导致泄露。
触发条件
搭建好的Web钩子默认是全分支、全事件触发的,项目上实际使用时,不用这么频繁,设置为特定分支变动时触发即可。
打开Web钩子设置:
下划到事件设置:
只保留"推送"事件,指定特定分支。
点击最下方的"更新钩子"按钮保存修改。
分支保护
启用触发构建分支的保护,并设置审批白名单。
在前面介绍过的分支保护设置中,下划到审批白名单:
"所需的批准"为必要的审批人数;
批准的用户或团队里,可以单独设置审批人,或专门建立一个审批团队:组织的团队里再新建一个团队,然后加入到协作者:
审批路径:
操作人员
包括项目管理者在内,不设置在组织的Owners团队中,因为有超级权限,可以越过审批直接合并。
为防止误操作,管理员账户非必要不使用,每个人单独创建自己的账号。
至此,可以模拟项目开发场景:
- 每个开发员创建各自开发分支,推送到远程仓库;
- 每个开发员发起合并到指定分支;
- 管理者从指定分支发起合并到触发构建的分支,因为加了审批人,需要额外一步审批操作,防止误点;
- 审批后,点击合并,自动触发构建
构建样例
测试时的构建日志,增量代码生成:
已部署过,不再处理:
未部署过,触发部署:
最后更新配置文件:
若某步出错,则会中断构建:
修正后,可以点击右上角的Restart来重新构建:
快速安装
为了简化Gitea安装、Drone安装、自动部署设置,此处提供了快速安装脚本。
脚本内容为前2个章节中可自动化安装步骤的合并。
下载自动部署包及目录,点此进入下载
因为一个脚本包含了多项安装步骤,提高了问题出现概率,若某步出现问题,可在解决后,手动复制剩余命令执行。
在线安装
若是服务器可以访问外网,将下载好的目录直接上传至服务器/tmp下,然后以root
用户运行安装:
bash /tmp/install-online.sh
离线安装
有些项目的服务器不允许曝露至外网的,就需要将安装包提前打好后再安装。
这里还是要依赖一台同配置
、可访问外网
的服务器。
下载依赖包
依赖包的处理很麻烦,还是通过yum命令自动处理。运行下述命令,仅下载安装包及其依赖:
mkdir /tmp/rpms
yum -y install yum-utils
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum install --downloadonly --downloaddir=/tmp/rpms docker-ce docker-ce-cli containerd.io docker-compose-plugin
wget -P /tmp/rpms https://github.com/drone-runners/drone-runner-exec/releases/download/v1.0.0-beta.10/drone_runner_exec_linux_amd64.tar.gz
若wget速度较慢,可使用网盘中的版本,或尝试进入github页面手动下载。
将/tmp/rpms下的文件放到从网盘下载到本地的docker/rpms下:
导出镜像
在装有Docker的服务器上,导出镜像文件:
docker pull gitea/gitea
docker pull mysql
docker pull drone/drone
docker pull drone/drone-runner-docker
docker save gitea/gitea:latest | gzip > gitea.tar.gz
docker save mysql:latest | gzip > mysql.tar.gz
docker save drone/drone:latest | gzip > drone_server.tar.gz
docker save drone/drone-runner-docker:latest | gzip > drone_runner.tar.gz
将导出的四个镜像文件放到从网盘下载到本地的docker/rpms下:
或者使用网盘中的版本,为截止2022-12-25的官方最新版本。
安装
上传完整的docker目录及安装脚本install-offline.sh至服务器/tmp下,然后root
用户运行:
bash /tmp/install-offline.sh
后续设置
前面的安装脚本执行完后,即可登录Gitea,然后进行配置:
关于Drone:
- 修改drone-compose.yml中的认证ID及Gitea用户名;
- 启动并设置
- 优化设置
然后在Gitea仓库中添加.drone.yml即可。