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次下载。

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

相关推荐
崔庆才丨静觅2 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60613 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了3 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅3 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅3 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅4 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment4 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅4 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊4 小时前
jwt介绍
前端
爱敲代码的小鱼4 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax