背景:
目前公司前端项目比较多,发布多是用手动打包的形式实现,当然后期我们基于portainer实现了自己的depoly脚本,但本质上还不够自动化。
gitlab ci/cd是gitlab 自身集成的功能,理论上我们只需要增加一个配置文件即可。
实现步骤:
1、增加gitlab-ci.yml 文件到项目根目录(纯前后端分离项目,这一步就够了)
2、将项目打包镜像所需要的文件,拷贝到项目输出目录里,参考下述copy.js
3、Rancher 上增加应用,导入文件里增加
配置文件:
1、gitlab-ci.yml
variables:
package_cmd: 'npm run public'
npm_install: 'npm --registry https://nexus.sxftwork.com/repository/westmoney-npm-group/ install && npm ls'
node_version: '16.15.1'
GIT_STRATEGY: clone
cache:
paths:
- $CI_PROJECT_DIR/dist/*
stages:
- package
- build
- push
- update
build-code-job:
stage: build
only:
- test
- pre
tags:
- gitlab-runner-share1
script:
- echo "begin build images"
- pwd && ls -al
- set +e
- if [[ $CI_COMMIT_TAG ]];then harbor_path="online";image_tag=$CI_COMMIT_TAG; else harbor_path="offline";image_tag=$CI_COMMIT_BRANCH;fi
- set -e
- cd dist && docker build -t harbor.saxofintech.com/$harbor_path/$CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME:$image_tag .
push-code-job:
stage: push
only:
- test
- pre
tags:
- gitlab-runner-share1
script:
- echo "begin push images"
- set +e
- if [[ $CI_COMMIT_TAG ]];then harbor_path="online";image_tag=$CI_COMMIT_TAG; else harbor_path="offline";image_tag=$CI_COMMIT_BRANCH;fi
- set -e
- docker push harbor.saxofintech.com/$harbor_path/$CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME:$image_tag
- docker rmi harbor.saxofintech.com/$harbor_path/$CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME:$image_tag
- rm -rf $CI_PROJECT_DIR/dist
package-code-job:
stage: package
only:
- test
- pre
tags:
- gitlab-runner-share1
script:
- echo "begin to package $CI_PROJECT_DIR"
- echo "$npm_install && $package_cmd" > start_build.sh
- pwd && ls -al
- set +e
# if you change docker run cmd,you must delete docker container
#- docker stop $CI_PROJECT_NAME && docker rm $CI_PROJECT_NAME
- if docker ps -a | grep $CI_PROJECT_NAME; then docker start $CI_PROJECT_NAME; else docker run --add-host nexus.sxftwork.com:10.72.88.107 --name $CI_PROJECT_NAME -v $CI_PROJECT_DIR:/usr/src/app -w /usr/src/app node:$node_version sh start_build.sh; fi
- set -e
- /data/gitrunner-src/check_build.sh $CI_PROJECT_NAME
- pwd && ls -al
update-code-job:
stage: update
only:
- test
- pre
tags:
- gitlab-runner-share1
script:
- echo "begin update K8S app image"
- set +e
- if [[ $CI_COMMIT_TAG ]];then harbor_path="online";image_tag=$CI_COMMIT_TAG; else harbor_path="offline";image_tag=$CI_COMMIT_BRANCH;fi
- set -e
- /sbin/kubectl --kubeconfig /root/.kube/wm-fat-config -n westmoney set image deployment/$CI_PROJECT_NAME app=harbor.saxofintech.com/$harbor_path/$CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME:$image_tag
- /sbin/kubectl --kubeconfig /root/.kube/wm-fat-config -n westmoney rollout restart deployment $CI_PROJECT_NAME
- echo "please check K8S status"
2、 copy.js脚本文件:
const fs = require('fs');
const path = require('path');
const resolve = (dir) =>{
return path.resolve(__dirname,dir)
}
const dirs = ['./.nuxt','./static','./router'];
const files = ['./nuxt.config.js','./package.json','./Dockerfile','./env.js'];
const copyFile = (src,dest)=>{
fs.cp(src,dest,function(err){
if (err) {
return console.error(err);
}
})
}
const filesFromDir = (path)=>{
return fs.readdirSync(resolve(path))
}
const copyFileSys = (src,dest)=>{
let fullpath = resolve(src)
let stat = fs.lstatSync(fullpath);
let isDirectory = stat.isDirectory();
// console.log(`${fileFullPath}是否是文件夹:`+stat.isDirectory()) //是文件夹吗
if(isDirectory){
console.log('文件夹路径:',fullpath)
let curLevelFiles = filesFromDir(fullpath);
curLevelFiles.forEach((name,j)=>{
let curLevelDestFileFullPaths = resolve(`${fullpath}/${name}`);
copyFileSys(curLevelDestFileFullPaths,curLevelDestFileFullPaths.replace(__dirname,`${__dirname}/dist`));
})
}else{
console.log('文件路径:',fullpath);
copyFile(src,dest);
}
}
fs.mkdir(resolve('./dist'),function(err){
files.forEach((item,index)=>{
fs.copyFile(resolve(item),resolve(`./dist/${item}`),function(err){
if (err) {
return console.error(err);
}
})
})
dirs.forEach((item,index)=>{
copyFileSys(item,resolve('./dist'));
})
});