GitHub Actions 是 GitHub 的持续集成服务,于2018年10月推出。
说到持续集成,就得提下前端工程化
前端部署发展史
前端一说起刀耕火种,那肯定紧随着前端工程化这一话题。随着 react/vue/angular,es6+,webpack,babel,typescript 以及 node 的发展,前端已经在逐渐替代过去 script 引 cdn 开发的方式了,掀起了工程化这一大浪潮。得益于工程化的发展与开源社区的良好生态,前端应用的可用性与效率得到了很大提高。
刀耕火种
本地开发完,根据项目 通过webpack或者rullup构建成静态文件,然后压缩扔给后台或者运维,运维将静态资源放在服务。可能中间运维还会向你要一份部署文档,大部分情况下是nginx的配置。
server {
listen 80;
server_name server.nam;
location / {
# 避免非root路径404
try_files $uri $uri/ /index.html;
}
# 解决跨域
location /api {
proxy_pass http://api.server.nam;
}
# 为带 hash 值的文件配置永久缓存
location ~* \.(?:css|js)$ {
try_files $uri =404;
expires 1y;
add_header Cache-Control "public";
}
location ~ ^.+\..+$ {
try_files $uri =404;
}
}
这个时候,无论跨域的配置还是缓存的配置,都是运维来管理,运维不懂前端。但配置方式却是前端在提供,而前端并不熟悉 nginx
使用Docker构建
docker的引进,解决大部分部署问题。dockerfile就是部署脚本,部署脚本就是dockerfile。这种方式很大程度上缓解了前端与运维人员之间的摩擦,至少部署脚本没有问题了。。。
这时候,前端提供的不再是静态资源,而是提供了一个服务,一个http服务
FROM node:alpine
# 代表生产环境
ENV PROJECT_ENV production
# 许多 package 会根据此环境变量,做出不同的行为
# 另外,在 webpack 中打包也会根据此环境变量做出优化,但是 create-react-app 在打包时会写死该环境变量
ENV NODE_ENV production
WORKDIR /code
ADD . /code
RUN npm install && npm run build && npm install -g http-server
EXPOSE 80
CMD http-server ./public -p 80
有了dockerfile就意味着前端需要维护 docker-compose.yaml,然后运维人员执行docker-compose up -d
。
但是这种模式也会存在一些问题:
- 构建镜像体积过大。
- 构建时间太长。
当然这些问题都是可以优化的
FROM node:alpine as builder
ENV PROJECT_ENV production
ENV NODE_ENV production
WORKDIR /code
ADD package.json /code
RUN npm install --production
ADD . /code
# npm run uploadCdn 是把静态资源上传至 oss 上的脚本文件,将来会使用 cdn 对 oss 加速
RUN npm run build && npm run uploadCdn
# 选择更小体积的基础镜像
FROM nginx:alpine
COPY --from=builder code/public/index.html code/public/favicon.ico /usr/share/nginx/html/
COPY --from=builder code/public/static /usr/share/nginx/html/static
- 利用镜像缓存,减少构建时间。
- npm install --production
- npm cache 或者使用npm 私库
但是这里仍然会有些问题,比如缓存,比如跨域等问题。
CI/CD与gitlab
- CI,Continuous Integration,持续集成
- CD,Continuous Delivery,持续交付
通过与仓库代码添加持续集成方案。工程负责人只需要编写工程的yml就可以了。
deploy:
stage: deploy
only:
- master
script:
- docker-compose up --build -d
tags:
- shell
当然我们还可以在持续集成方案中添加各种lint
、test
、package
等安全检测,提高代码质量。
kubernetes + jenkins

Jenkins 拥有丰富的插件、良好的生态社区、开源、基于java可移植到所有的主要平台。
Jenkins能够与主流的源代码管理系统(Git、SVN、Mercurial以及CVS)、主流的构建工具(Ant、Maven、Grunt)、shell脚本和Windows批处理命令、测试框架、报表生成器的都良好地协同工作。
并且Jenkins有良好的可伸缩性:
- 并行运行多个构建方案
- 自动挂载和移除代理、节约开销
- 分配负载
GitHub Action
但是这种方案并不适合独立开发者,或者个人使用。虽然好用,但是太庞大,而且个人搭建浪费资源。毕竟能省就省才是王道。
所以这里就介绍到了今天的主题GitHub Action(下面简称action)
action其实是GitHub的持续集成服务。相信大家肯定也用过Travis CI。
Travis CI 提供的是持续集成服务(Continuous Integration,简称 CI)。它绑定 Github 上面的项目,只要有新的代码,就会自动抓取。然后,提供一个运行环境,执行测试,完成构建,还能部署到服务器。
大家知道,持续集成由很多操作组成,比如抓取代码、运行测试、登录远程服务器,发布到第三方服务等等。GitHub 把这些操作就称为 actions。
很多操作在不同项目里面是类似的,完全可以共享。GitHub 注意到了这一点,想出了一个很妙的点子,允许开发者把每个操作写成独立的脚本文件,存放到代码仓库,使得其他开发者可以引用。
如果你需要某个 action,不必自己写复杂的脚本,直接引用他人写好的 action 即可,整个持续集成过程,就变成了一个 actions 的组合。这就是 GitHub Actions 最特别的地方。
官方市场 ,在这里可以搜索到其他人提交的actions
基本概念
Github Action 分为四部分
- workflow (工作流程):持续集成一次运行的过程,就是一个 workflow。
- job (任务):一个 workflow 由一个或多个 jobs 构成,含义是一次持续集成的运行,可以完成多个任务。
- step(步骤):每个 job 由多个 step 构成,一步步完成。
- action (动作):每个 step 可以依次执行一个或多个命令(action)。
workflow
具体配置大家可以去看 官方文档 ,我在这里就不一一赘述了 (懒
这里给大家贴一个我自己的 工程示例

通过上图我们可以看到 我们每次的push commit 都会触发action,CI结束之后我们可以可以查看完整的日志。
我工程的主要诉求就是验证成功直接push到我阿里云的机器上面实现代码reload。这里我采用的是官网市场开源的一个action appleboy/ssh-action ,主要就是通过ssh登陆服务器,执行某个shell脚本 实现工程的reload。
nodejs.yml
# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
name: Node.js CI
on:
push:
branches: [ master ]
pull_request:
types: [closed]
branches:
- master
jobs:
deploy:
runs-on: ubuntu-latest
name: Deploy to server
steps:
- name: Exec deploy script with SSH
uses: appleboy/ssh-action@master
with:
command_timeout: 8m
host: ${{ secrets.ALIYUM_HOST }}
username: ${{ secrets.ALIYUM_USER }}
password: ${{ secrets.ALIYUM_PWD }}
port: ${{secrets.ALIYUM_PORT }}
script: sh ${{ secrets.PATH }}/blog-front/.deploy/main.sh
secrets.ALIYUM_HOST
这种变量可以在仓库的setting里面进行设置
这里的 secret 就是一种 context,描述 CI/CD 一个 workflow 中的上下文信息,使用 ${{ expression }} 语法表示。
除了 secret,还有
- github: workflow 的信息,如 github.sha 可以获取当前的 commit SHA,我们可以利用它为 sentry 或者 docker image 打入版本号
- env: 环境变量
- job: 当前执行 job 的信息,如 job.status 表示当前 job 的执行状态
- matrix: 描述一些构建信息,如 node 以及 os 版本号
#!/bin/bash
WEB_PATH=$(dirname $0)
# WEB_USER='root'
# WEB_USERGROUP='root'
echo "[deploy] Fetch and rebuilding..."
cd $WEB_PATH
cd ..
echo "[deploy] path:" $(pwd)
echo "[deploy] pulling source code..."
git fetch --all && git reset --hard origin/master && git pull
git checkout master
echo "[deploy] building..."
npm ci
npm run build
echo "[deploy] Rebuild done."
以上就是今天要给大家分享的,没尝试过的小伙伴一定要去尝试下,真香!!!