Github通过workflow实现自动部署

背景

当我们开发一款插件或者组件库想要开源的时候,目前惯用的做法就是发布到npm供开发者下载,同时源码上传到github,除此以外,我们每次发布前,还需要提前执行npm run build生成对应的插件包,才能发布到npm,面对这一连串的步骤,我们如何能够做到当提交代码后,自动触发构建,一键发布到npm,同时在github创建release版本,如下图:

下面以我自身开源的插件为例,给大家演示Github自动触发构建、自动发布的过程。

组件开发

一、Github创建空的开源仓库rocket-render

Github代码

二、本地插件或组件库开发,基于Vite@vue/cli都可以,框架自由选择,当前使用的是@vue/cli4.x版本。

  1. 组件库开发一般使用packages文件夹,当然使用src也可以。
  2. 遵循Vue插件开发规范。
js 复制代码
// index.js 文件如下

// 导入组件
import SearchForm from './SearchForm/index';

// 定义全局安装方式
const install = function (Vue, opts = {}) {
    Vue.use(SearchForm);
}
// 具名导出
export { SearchForm };
// 默认导出
export default {
  install,
};

推荐分别使用具名导出和默认导出,方便开发者做全量加载或者按需加载。

此处没有提供完整代码,大家可以参考仓库代码,我们主要是为了讲解github自动部署。

组件打包

一、使用@vue/cli提供的库模式进行打包: 库打包模式

二、修改package.json中的scripts构建脚本。

  1. 配置脚本如下。
json 复制代码
"scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint",
    "lib": "vue-cli-service build --target lib --name rocket-render --dest lib packages/index.js",
}

lib就是本次增加的组件打包命令,我们需要把它打包成一个组件包。

  • --target 用来设置打包模式为库模式。
  • --name 设置打包后文件名称。
  • --dest 设置打包后输出的目录名称。
  1. 打包后结果如下:

默认生成了commonumd两种包。

  1. package.json文件添加files配置
json 复制代码
"files": [
    "lib",
    "types/*.d.ts"
],

项目打包后,会输出到一个目录,通过指定files属性,可以让npm publish的时候,只发布files配置的文件或目录,而不是把整个项目都发布上去。

  1. 配置dependencies
json 复制代码
"dependencies": {
    "element-ui": "^2.15.6",
    "vue": "^2.6.11"
}

这个属性叫:生产依赖。想必只要是做前端的都知道,但是有一点大家可能会忽略:

  1. 如果是单独启动这个项目,则dependenciesdevDependencies毫无区别,因为所有的插件都会被安装到node_modules里面去。
  2. 如果这个项目是被其它项目安装,则其它项目在安装的时候,只有dependencies里面的包才会被安装,这个非常关键。

rocket-render基于Vue2开发,使用ElementUI进行二次封装的低代码渲染引擎,因此开发者在使用的时候,必须保证自己是Vue项目,并且采用了ElementUI框架,否则是不能使用此组件库的,那我们打出去的包里面是不包含VueElementUI的,也就是开发者自己的项目本身会安装这两个依赖。

三、安装插件,自动生成changelog

当我们提交代码后,需要手动更新package.json中的版本号,太麻烦,可以使用standard-version插件帮助我们修改版本号,同时生成每个版本的提交日志。

  1. 安装standard-version插件。
  2. 配置命令脚本。
json 复制代码
"scripts": {
    "release:major": "standard-version --release-as major",
    "release:minor": "standard-version --release-as minor",
    "release:patch": "standard-version --release-as patch"
}

例如:vue:2.7.4

major:主版本为 2

minor:小版本为 7

patch:修复版本为 4

  1. changelog截图如下:

组件文档

组件开发完成后,通常需要给开发者提供能够查看的文档,比如,rocket-render我给开发者提供了配套的开发文档。

rocket-render文档

那如何给组件开发文档呢?其实开源的文档插件有很多,比如:vuepressvitepressDuMIDoczMDX等,大家自由选择。

由于我们是基于Vue2开发的低代码渲染引擎组件,因此我们使用的是:vuepress,效果如下图所示:

文档打包

文档实际上是一个一个的markdown文件,最终通过打包工具,编译成对应的html文件,开发者才能访问。上面介绍的每一款文档框架,都自带打包功能,本文以vuepress为例。

一、添加打包脚本

js 复制代码
"scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint",
    "lib": "vue-cli-service build --target lib --name rocket-render --dest lib packages/index.js",
    "docs:dev": "vuepress dev docs",
    "docs:build": "vuepress build docs",
    "format": "prettier --write \"examples/**/*.{js,ts,jsx,tsx}\" \"examples/**/*.vue\" ./**/*.{js,ts} ",
    "update:version": "npm version patch",
    "release:major": "standard-version --release-as major",
    "release:minor": "standard-version --release-as minor",
    "release:patch": "standard-version --release-as patch"
  },

docs:dev 为本地启动时命令,相当于项目的启动,可以实时查看本地文档内容。

docs:build 为本地文档编译命令,用于生成对应的html文件。

提交代码、远程推送

这个就是常规的代码提交,远程推送,不做过多解释。

shell 复制代码
git init
git add README.md
git commit -m "first commit"
git branch -M main
git remote add origin https://github.com/JackySoft/test.git
git push -u origin main

本地代码推送到github已有仓库中,使用上面命令即可。

注意:上述的origin地址需要替换为自己项目的仓库地址。

配置workflows

仓库主页有一个Actions页签,最终会在这个里面生成工作流,触发仓库构建。但需要提前在本地创建工作流文件,提交到github以后,才能触发构建。

相关概念理解

  • workflow(工作流程):持续集成一次运行的过程,就是一个workflow

  • job(任务):一个workflow由一个或者多个jobs构成,含义是一次持续集成的运行,可以完成多个任务。

  • step(步骤):每个job由多个step构成,一步步完成。

  • action(动作):每个step可以依次执行一个或者多个命令。

本地代码添加workflow

  1. 项目根目录,创建.github文件夹。
  2. 继续创建workflows文件夹。
  3. 创建npm-publish.yml文件。

配置worksflow

完整配置如下,后面会解释配置:

yml 复制代码
# action名称
name: Publish and Release

# 当代码合并到master分支的时候,执行下列脚本
on:
  push:
    branches: [master]
# 任务
jobs:
  publish-npm:
    runs-on: ubuntu-latest
    steps:
      - name: 检查master分支
        uses: actions/checkout@master

      - name: 设置Node.js
        uses: actions/setup-node@master
        with:
          node-version: 14
          registry-url: https://registry.npmjs.org/ # 如果不配置将影响publish

      - name: 安装依赖
        run: npm install

      - name: 构建packages
        run: npm run lib

      - name: 发布NPM包
        env:
          NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
        run: |
          npm publish
      - name: publish 成功通知
        run: echo npm 推送成功,请访问 https://jackysoft.github.io/rocket-render-doc

      - name: 读取当前版本号
        id: version
        uses: ashley-taylor/read-json-property-action@v1.0
        with:
          path: ./package.json
          property: version

      - name: 创建GitHub Release
        id: create_release
        uses: actions/create-release@latest
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          tag_name: v${{steps.version.outputs.value}}
          release_name: v${{steps.version.outputs.value}}
          draft: false
          prerelease: false

一、 name 为工作流程的名称,随意定义,最终会显示在Action中,如下:

二、触发分支构建

yml 复制代码
on:
  push:
    branches: [master]

当检测到master分支有代码推送时,就会执行该工作流。

三、定义任务:jobs<job_id>.runs-on

yml 复制代码
# 任务
jobs:
  publish-npm:
    runs-on: ubuntu-latest

publish-npm为任务ID,随意定义

runs-on是固定语法,用来指定运行该任务所依赖的虚拟机环境,此处配置为ubuntu-latest

此处也可以不用指定。

四、定义步骤:steps

指定每个 job 的运行步骤,可以包含一个或者多个步骤。

  • jobs.<job_id>.steps.name:步骤名称。
  • jobs.<job_id>.steps.run:该步骤运行的命令或者 action。
  • jobs.<job_id>.steps.env:该步骤所需的环境变量。
yml 复制代码
steps:
    - name: 检查master分支
      uses: actions/checkout@master

    - name: 设置Node.js
      uses: actions/setup-node@master
      with:
          node-version: 14
          registry-url: https://registry.npmjs.org/ # 如果不配置将影响publish

上面两个steps作用:

  1. 切换到master分支,并获取该分支代码。
  2. 指定虚拟环境的node版本和npm镜像源。

五、安装依赖、执行构建

yml 复制代码
- name: 安装依赖
  run: npm install

- name: 构建packages
  run: npm run lib

上面steps就很容易理解了:

  1. 安装依赖,也可以使用:yarn install
  2. 执行构建。我们在前面讲过,scripts脚本配置的打包命令为:lib

六、发布到npm

yml 复制代码
- name: 发布NPM包
  env:
    NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
  run: |
    npm publish
- name: publish 成功通知
  run: echo npm 推送成功,请访问 https://jackysoft.github.io/rocket-render-doc

这一步极为关键,当构建完代码以后,需要把组件库发布到npm,正常情况,是本地终端(window叫:dos)通过npm login登录npm,进行发布。有了workflow,这里就只需要执行npm publish就可以直接发布了。

为什么github不登录到npm就能直接发布?

细心的人会发现,里面有一个变量:NODE_AUTH_TOKEN,配置的是:${{secrets.NPM_TOKEN}}

实际上就是:npm生成了一个钥匙,给了githubgithub拿着钥匙,就直接开了门。

npm怎么生成这把钥匙?

  1. 登录NPM官网:npm 官网
  2. 点击个人中心下的Access Token

下面这些都是钥匙:

  1. 点击新建经典Token(Classic Token)

第一个token是精细化配置,第二个是常规配置,主要还是从安全角度去区分的。

如果不是高度机密的项目,用不着第一个。

  1. 输入name,选择publish

name可以随意输入。

  1. 获取token,拿到钥匙🔑

生成token以后,需要复制该token配置到github中。

  1. github中配置npm钥匙

默认是空的,只需要新增一个即可,变量名称必须叫:NPM_TOKEN,因为workflow里面使用到的变量是:${{secrets.NPM_TOKEN}}

到此,我们就完成了一大半了,代码推送到master仓库以后,action已经能自动触发构建了,并且能够把包发布到npm仓库。

七、生成Release

yml 复制代码
- name: 读取当前版本号
  id: version
  uses: ashley-taylor/read-json-property-action@v1.0
  with:
    path: ./package.json
    property: version

- name: 创建GitHub Release
  id: create_release
  uses: actions/create-release@latest
  env:
    GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  with:
    tag_name: v${{steps.version.outputs.value}}
    release_name: v${{steps.version.outputs.value}}
    draft: false
    prerelease: false

上面steps用来读取版本号和创建release版本。uses对应的是市场上面的插件,里面还有一个变量:GITHUB_TOKEN,这个是github自己创建的,不需要我们来创建,我们直管使用即可,毕竟当前就在github自己家里,你也没见过哪个人在自己家里,还要把门反锁的,如果存在,那就是你爸妈怕你出去犯罪,才把你锁屋里的。

运行Actions

  1. 本地代码提交后,github会自动运行
  1. 执行workflow配置的steps
  1. 生成Release版本

末尾

最近刚写了一款vite插件,或许对你的工作有帮助,链接参考:vite-plugin-externals-new

刚发布就有169次下载。

好了,我是河畔一角,分享到此结束,祝你工作愉快、顺心如意、四季发财、前程似锦。

相关推荐
理想不理想v3 分钟前
vue经典前端面试题
前端·javascript·vue.js
不收藏找不到我4 分钟前
浏览器交互事件汇总
前端·交互
YBN娜17 分钟前
Vue实现登录功能
前端·javascript·vue.js
阳光开朗大男孩 = ̄ω ̄=17 分钟前
CSS——选择器、PxCook软件、盒子模型
前端·javascript·css
minDuck22 分钟前
ruoyi-vue集成tianai-captcha验证码
java·前端·vue.js
小政爱学习!43 分钟前
封装axios、环境变量、api解耦、解决跨域、全局组件注入
开发语言·前端·javascript
魏大帅。1 小时前
Axios 的 responseType 属性详解及 Blob 与 ArrayBuffer 解析
前端·javascript·ajax
花花鱼1 小时前
vue3 基于element-plus进行的一个可拖动改变导航与内容区域大小的简单方法
前端·javascript·elementui
k09331 小时前
sourceTree回滚版本到某次提交
开发语言·前端·javascript
EricWang13581 小时前
[OS] 项目三-2-proc.c: exit(int status)
服务器·c语言·前端