• 前端持续集成


    视频教程

    前端持续集成一(jenkins 安装)

    前端持续集成二(自动部署)

    前置条件

    jenkins + nginx 实现持续集成

    搭建jenkins

    jenkins 是一个开源持续集成工具,安装非常简单,为了管理方便,这里使用 docker 进行安装。

    安装 docker

    centos 安装 docker

    sudo yum install docker
    

    启动 docker 服务

    sudo systemctl start docker
    

    安装 jenkins

    创建 jenkins 数据持久化目录

    sudo mkdir -p /data
    sudo chmod 777 /data
    mkdir -p /data/jenkins_home
    

    通过docker容器安装jenkins

    docker run \
      -u root \
      --rm \
      --name jenkins-server \
      -d \
      -p 8080:8080 \
      -p 50000:50000 \
      -v /data/jenkins_home:/var/jenkins_home \
      -v /var/run/docker.sock:/var/run/docker.sock \
      registry.cn-hangzhou.aliyuncs.com/hzero-cli/jenkins
    

    关于 docker 命令的学习可以看这里 👉 Docker 命令大全

    -w470

    上面命令运行完成之后您就已经成功运行了 jenkins 服务

    您可以打开地址 https://centos服务器ip:8080,可以看到 jenkins 的界面。

    这里的 centos服务器ip 就是你自己的服务器 ip,在这个教程里面,我们演示的服务器ip是 172.22.0.4

    -w1091

    接下来我们需要获取jenkins初始化密码。

    docker exec -it jenkins-server \
        cat /var/jenkins_home/secrets/initialAdminPassword
    

    -w455

    这里返回的一段字符串6c46ccc61c804279a1017b743ab22aa4就是我们需要的密码

    输入密码之后,选择安装初始化的插件

    -w1013

    -w997 插件安装好之后,系统会提示你设置用户名密码,当然你也可以不设置,直接用 admin 账号。重新进入 jenkins 界面。

    -w689 点击输入账号里面,这里的密码就是上文获取到的 jenkins 初始化密码 6c46ccc61c804279a1017b743ab22aa4,点击登录,进入系统:

    -w696

    到此为止。jenkins 就算是安装好了

    名如果想要卸载 jenkins 的话,只需要运行 docker rm -f jenkins-server 就可以了。

    因为您配置了 jenkins 数据持久化的目录 /data/jenkins_home, 只要这个文件夹还在,jenkins 配置就可以一直保留,下次想运行 jenkins 是,运行上文安装 jenkins 的 docker run 命令就可以恢复 docker 运行了。

    配置 jenkins 的 nodejs 插件

    安装完 jenkins 之后, 需要配置一下 nodejs 插件,后面才能让 jenkins 跑前端持续集成任务。

    点击 系统管理 进入 jenkins 系统管理页面

    -w315

    点击 插件管理 进入插件管理

    -w1021

    进入 可选插件 选项卡,搜索并安装 nodejs 插件

    -w1120

    勾选 安装完成后重启选项,安装完插件之后 jenkins 会 自动重启

    -w554

    进入 全局工具配置 配置 nodejs 全局工具

    -w931

    点击 新增 NodeJS 按键新增一个 nodejs 全局工具,勾选 自动安装

    15821185123655

    注意: - 安装 nodejs 时需要安装两个 node 全局命令 yarnlerna, 然后点击保存。

    测试 nodejs 插件

    我们安装完了 nodejs 插件之后,先回到首页 新建一个 jenkins 任务测试一下 nodejs。

    点击 创建一个新任务 打开任务编辑界面

    -w630

    选择 构建自由风格的软件项目, 输入一个任务名字test-node-demo:

    -w718

    在构建环境这里选择我们刚刚配置的 nodejs 全局工具

    -w734

    在构建这里 点击 增加构建步骤 ,在弹出的选项中选择 执行shell

    -w359

    在命令输入框中输入,然后点击保存按钮

    node -e 'console.log("Hello Hzero!");'
    node --version
    

    -w758

    然后点击这个任务的 立即构建 按钮

    构建时,在下面会出现一个进度条,点击进度条 可以看执行的日志

    -w624

    进入日志之后,将看到看到如下信息

    -w1061

    到此,nodejs 插件测试成功!

    安装 nginx

    centos 安装 nginx 也非常简单 ,一句命令 sudo yum install nginx 就能搞定, 但是这样安装 nginx 之后,配置管理和nginx升级都比较麻烦,所以我们这里用 docker 来安装 nginx 。

    这里我们先定义两个文件目录,用来保存 nginx 的部署文件和 nginx 的配置

    首先创建 nginx 数据持久化文件夹和 配置保存文件夹,

    sudo mkdir -p /data/nginx/wwwroot
    sudo mkdir -p /data/nginx/cfg
    

    -w380

    创建 nginx 配置文件, 保存在 /data/nginx/cfg/nginx_hzero.conf

    在命令行运行下面命令:

    # /data/nginx/cfg/nginx_hzero.conf
    
    sudo -s # 进入root用户模式
    
    cat > /data/nginx/cfg/nginx_hzero.conf << END
    
    server {
        listen       80;
        server_name  localhost;
        root   /usr/share/nginx/html/dist;
        
        location / {
          try_files \$uri /index.html;
        }
    
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /usr/share/nginx/html/dist;
        }
    
        # Media: images, icons, video, audio, HTC
        location ~* \.(jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ {
        expires 1M;
        access_log off;
        add_header Cache-Control "public";
        }
    
        # CSS and Javascript
        location ~* \.(css|js)$ {
        expires 1y;
        access_log off;
        add_header Cache-Control "public";
        }
    }
    
    END
    
    

    -w590

    运行nginx镜像

    docker run \
      -u root \
      --rm \
      --name nginx \
      -d \
      -p 40080:80 \
      -v /data/nginx/cfg/:/etc/nginx/conf.d/ \
      -v /data/nginx/wwwroot/:/usr/share/nginx/html/ \
      nginx
    

    -w458

    添加测试文件

    sudo mkdir -p /data/nginx/wwwroot/dist
    sudo echo Hello Nginx > /data/nginx/wwwroot/dist/test.txt
    

    测试 nginx 运行效果

    curl http://172.22.0.4:40080/test.txt
    

    -w472

    如果能显示 Hello Nginx 说明 nginx 安装成功

    配置 jenkins 持续集成任务

    构建

    配置 jenkins 任务之前,我们先准备一个 hzero-front 工程的代码仓库地址: https://code.choerodon.com.cn/hft/hzero-front-demo.git

    回到 jenkins 首页 新建一个 jenkins 任务。

    点击 创建一个新任务 打开任务编辑界面

    -w630 选择 构建自由风格的软件项目, 输入一个任务名字hzero-front-ci:

    点击保存后会进入任务编辑页面:

    -w1054

    在任务编辑界面的源代码管理 选择 git 选项 安装图片填写下面信息:

    在编译环境设置里面勾选上 nodejs 工具。

    -w980

    添加一个构建步骤 执行 shell

    -w515

    输入下面的 shell 脚本:

    yarn install
    
    cat > src/config/.env.production.local.yml  << END
    BASE_PATH: /
    PLATFORM_VERSION: SAAS
    CLIENT_ID: localhost
    GENERATE_SOURCEMAP: false
    API_HOST: http://backend.hft.jajabjbj.top
    WEBSOCKET_HOST: ws://ws.hft.jajabjbj.top
    SKIP_TS_CHECK_IN_START: false
    ENABLE_VUE_SUPPORT: false
    SKIP_ESLINT_CHECK_IN_START: false
    END
    yarn run build:production
    tar -zcf dist.tar.gz ./dist
    

    -w961

    点击保存。

    下一步然后点击 立即构建,这里会构建并生成 dist 文件

    -w711

    部署

    构建完成生成了 dist 文件,下一步我们要把 构建生成的文件部署到 nginx 的 www 目录 /data/nginx/wwwroot

    接下来我们配置一下 dist 部署流程

    部署通常都是指把构建好的 dist 文件部署到远程服务器,部署的方法有很多,比如 ftp、 构建 docker等、ssh , 这里我们演示一下如何通过 ssh 远程部署 dist 文件到 nginx 服务器上。

    首先我们需要安装一个 jenkins 插件 Publish Over SSH

    -w814

    插件的安装方法上文中有提到,这里就不再赘述。

    安装好之后,打开 系统管理 > 配置中心

    -w793

    把 nginx 服务器的信息 添加到 Publish Over SSH 的 ssh 配置。

    -w1413

    对关键配置项的解释:

    然后打开我们刚刚创建的 jenkins 任务,点击配置按钮,进入任务编辑页面。

    -w500

    Post-build Actions 配置部分添加一个 构建后的部署流程。

    -w651

    然后输入相应的配置

    -w968

    对关键配置项的解释:

    cd /data/nginx/wwwroot
    sudo rm -rf dist
    sudo tar -zxf dist.tar.gz
    

    然后点击保存,再构建一次。

    -w1156

    看下构建日志。提示发布成功。

    -w525

    然后我们可以 在浏览器输入一下 nginx 服务器地址, 试试服务是否成功。

    配置自动持续集成

    如果想实现完全自动的持续集成,还需要配置一个地方

    打开任务配置设置一个触发选项 Poll SCM,设置 Schedule 规则为: H/15 * * * *

    -w1229

    这里配置项的意思是:每 15 分钟检查一次 git 源代码仓库是否有新的变更,如果有就执行构建任务。

    关于 cronjob 表达式的学习

    jenkins + gh-pages 实现持续集成

    如果没有 nginx 服务器,我们也可以把 dist 部署到 gh-pages 上。

    考虑到 github 的 gh-pages 网速在国内有些慢, 本教程就用国内的 gitee 做一个示范。

    gitee网站: https://gitee.com/

    首先我们在 gitee 上面注册好账号,然后再创建一个代码仓库。

    -w786

    我们可以得到一个代码仓库地址:https://gitee.com/hzero-cli/hzero-front-demo-dist.git

    部署到 gh-pages 上面我们需要用到一个 npm 工具

    把这个工具配置到 nodejs 的全局工具上面:

    -w910

    配置好工具之后,开始创建 jenkins 任务。

    为了简便,我们基于之前的持续集成任务创建一个新的持续集成任务。

    点击 新建任务 按钮

    -w670

    为任务起一个新名字: hzero-front-ci-gitee

    -w1074

    注意这里我们要选择 Copy from, 输入前面创建的任务名字:hzero-front-ci

    点击 ok ,进入构建配置部分。

    -w1201

    修改构建脚本,添加 gh-pages 部署命令:

    git config --global user.email "you@example.com"
    git config --global user.name "Your Name"
    gh-pages -r https://hzero-cli:abcd1234@gitee.com/hzero-cli/hzero-front-demo-dist.git   -b gh-pages   -d dist
    

    然后删除从 hzero-front-ci 任务复制过来的 ssh部署 配置

    保存,点击立即构建。

    这样构建生成的 dist 就可以发布到 gitee 代码仓库了。

    -w820

    这里会多一个分支,就是我们部署上去的文件。

    接下来我们需要给 gitee 代码仓库设置一下 gh-pages 的 http 服务。

    点击 服务 > Gitee Pages

    -w973

    设置部署分支为 gh-pages ,然后点击开始按钮

    运行成功之后, 我们得到一个 http 访问地址:http://hzero-cli.gitee.io/hzero-front-demo-dist/

    但是访问时, console 还是会报错:

    -w1147

    这是因为 gitee 的 gh-pages 提供的 http 地址有一个根路径(public_path)。

    所以我们修改一下构建的环境变量,打开任务的构建配置修改环境变量:

    PUBLIC_URL: /hzero-front-demo-dist/
    BASE_PATH: /hzero-front-demo-dist/
    

    注意一下 BASE_PATH 和 PUBLIC_URL 的区别。

    虽然 BASE_PATH 不会影响资源加载路径,但是我们进入页面之后刷新,必须浏览器的地址栏是以 http://hzero-cli.gitee.io/hzero-front-demo-dist/ 为前缀,所以要加一下 BASE_PATH 的配置。

    清除构建缓存,然后点击重新构建

    -w369

    注意: 由于 hzero-cli 默认开启了增量更新, 所以修改了环境变量之后,需要清空当前构建任务的缓存。

    如果你访问页面,第二次刷新还会有 404 的问题

    这是因为我们 gh-pages 和 nginx 配置 不一样。 nginx 上面配置了一段代码:

        location / {
          try_files $uri /index.html;
        }
    

    有了这段代码, 服务器就会路径找不到的http请求重新定位到 /index.html

    但是 gh-pages 的原理是: 如果当前 http 请求路径定位不到仓库的文件,就返回 404.html 的内容。

    所以为了能让页面正常显示,我们还需要在脚本构建完成之后 加一行代码 cp dist/index.html dist/404.html 让浏览器能获取到 index.html 。

    最后脚本修改如下:

    yarn install
    cat > src/config/.env.production.local.yml  << END
    PUBLIC_URL: /hzero-front-demo-dist/
    BASE_PATH: /hzero-front-demo-dist/
    
    PLATFORM_VERSION: SAAS
    CLIENT_ID: localhost
    GENERATE_SOURCEMAP: false
    API_HOST: http://backend.hft.jajabjbj.top
    WEBSOCKET_HOST: ws://ws.hft.jajabjbj.top
    SKIP_TS_CHECK_IN_START: false
    ENABLE_VUE_SUPPORT: false
    SKIP_ESLINT_CHECK_IN_START: false
    
    END
    
    yarn run build:production
    cp dist/index.html dist/404.html
    
    git config --global user.email "you@example.com"
    git config --global user.name "Your Name"
    gh-pages-clean
    gh-pages -r https://hzero-cli:abcd1234@gitee.com/hzero-cli/hzero-front-demo-dist.git \
      -b gh-pages \
      -d dist
    

    清除构建缓存之后,点击重新构建, 构建成功会自动部署,部署完成之后就可以访问: http://hzero-cli.gitee.io/hzero-front-demo-dist

    gitlab-ci + choerodon 云平台的 k8s 环境持续集成

    关于 gitlab-ci 的持续集成,hzero-cli 创建的项目中包括了 gitlab-ci 脚本,不需要进行特殊设置。

    
    image: registry.cn-hangzhou.aliyuncs.com/choerodon-tools/cifront:0.7.0
    
    stages:
    #  - node_dep_install
      - node_build
      - docker_build
    
    #node_dep_install:
    #  stage: node_dep_install
    #  script:
    #    - node_module
    
    node_build:
      image: registry.cn-hangzhou.aliyuncs.com/hzero-cli/cifront:0.0.1
      stage: node_build
      script:
        - node_module
        - node_build
      only:
        - master
    
    docker_build:
      image: registry.cn-hangzhou.aliyuncs.com/choerodon-tools/cibase:0.7.0
      stage: docker_build
      script:
        - docker_build
        # - rm -rf /cache/${CI_PROJECT_NAME}-${CI_PROJECT_ID}-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHA}
        - chart_build
      only:
        - master
    
    .auto_devops: &auto_devops |
      http_status_code=`curl -o .auto_devops.sh -s -m 10 --connect-timeout 10 -w %{http_code} "${CHOERODON_URL}/devops/ci?token=${Token}&type=front"`
      if [ "$http_status_code" != "200" ]; then
        cat .auto_devops.sh
        exit 1
      fi
      source .auto_devops.sh
      export TEMP_DIR=/cache/${CI_PROJECT_NAME}-${CI_PROJECT_ID}-${CI_COMMIT_REF_NAME}-front
      echo $TEMP_DIR
      function node_module(){
          mkdir -p $TEMP_DIR
          if [ -f "$TEMP_DIR/node_modules.tar.gz" ]; then
            tar -zxf $TEMP_DIR/node_modules.tar.gz
            chmod -R 777 node_modules
          else
            yarn
          fi
      }
    
      function node_build(){
          if [ -f "$TEMP_DIR/dist.tar.gz" ]; then
            tar -zxf $TEMP_DIR/dist.tar.gz
          fi
          if [ -f "$TEMP_DIR/dll.tar.gz" ]; then
            tar -zxf $TEMP_DIR/dll.tar.gz
          fi
          chmod -R 777 node_modules
          yarn build:production
          # cp -r dist /cache/${CI_PROJECT_NAME}-${CI_PROJECT_ID}-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHA}/dist
          tar -zcf $TEMP_DIR/dist.tar.gz ./dist
          tar -zcf $TEMP_DIR/node_modules.tar.gz ./node_modules
          tar -zcf $TEMP_DIR/dll.tar.gz ./dll
      }
    
      function docker_build(){
          # cp -r /cache/${CI_PROJECT_NAME}-${CI_PROJECT_ID}-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHA}/* ${1:-"."}
          tar -zxf $TEMP_DIR/dist.tar.gz
          docker login -u ${DOCKER_USER} -p ${DOCKER_PWD} ${DOCKER_REGISTRY}
          docker build --pull -t ${DOCKER_REGISTRY}/${GROUP_NAME}/${PROJECT_NAME}:${CI_COMMIT_TAG} ${1:-"."}
          docker push ${DOCKER_REGISTRY}/${GROUP_NAME}/${PROJECT_NAME}:${CI_COMMIT_TAG}
          echo "${DOCKER_REGISTRY}/${GROUP_NAME}/${PROJECT_NAME}:${CI_COMMIT_TAG}"
      }
    
    before_script:
      - *auto_devops
    
    
    

    更新代码仓库内容之后会自动触发 gitlab cicd 的 pipeline

    这里注意一下:更新了 PUBLIC_URL 配置之后,还是需要执行一下 构建缓存清空:

    -w1436

    DEMO 参考