GitHub Action 基础与自动发布npm实例

1.概念解析

Github Actions: 是一种持续集成和持续交付(CI/CD)平台,可以用于自动执行生成测试部署管道。可以创建工作流程构建测试存储库的每个拉取请求,或将合并的拉取请求署到生产环境。

主要的几个概念

name 说明
workflow(工作流程) 可配置的自动化过程,可运行一个或多个作业,通过 ymal 文件定义,工作流程在存储库的.github/workflows 目录中定义
event(事件) 存储库中触发工作流程运行的特定活动,例如拉取分支open issure,push commit
job(任务) 在同一个运行器中执行的一组步骤,一个 workfow 由 1 个多多个 job 构成 ,
step(步骤) 每个 job 由多个 step 构成
action(动作) 每个 step 可以一次执行一个或者多个 action 命令

2. 实例

先来实操一个例子,后续讲解字段。

2.1 runs-on------Github 托管的虚拟机配置

如果是github则可以直接使用runs-on: ubuntu-latest, 如果在公司内部的github上,则需要配置自己托管的虚拟机。

托管虚拟机创建成果:

  • 根据图片的步骤,选择需要安装的机子类型(我最开始选择了 linux-64),但是在机子上需要执行两次./run.sh才启动,并且 action 不能正确执行成功,因此切换到了 window
  • 在托管的机子上,运行config runner中的所有命令
  • 在 github 中,将会看到生成的托管机子,idle表示没有作业

2.2 自动发布 npm

根据图片,选择发布的类型,将会有一个发布模板:

2.3 修改 yaml 文件(yaml 文件基础剖析)

yaml 复制代码
name: your-repository-release # 工作流名称,将出现在Github`Actions`选项卡中,默认为`文件名称`
run-name: ${{ github.actor }} is release GitHub Actions # 当action运行的时候,显示在运行tab上的内容,`github.actor`是当前运行action 的github作者
# on: #: 指定工作流的触发器,当向master分支 push代码的时候触发
#   push:
#     branches:
#       - master
on:
  workflow_dispatch: # 指定工作流的触发器,手动触发
    inputs: # inputs:手动触发的时候,可以添加需要输入的参数,在后面可以通过变量访问
      releaseStep:
        description: "start to release"
        required: true
        default: "start....."

jobs: # 将 `your-repository-release`的所有工作流运行的作业放在一起
  publish-npm: # 定义第一个job的名字
    runs-on: [self-hosted] # 作业将在`self-hosted`上运行,后面将会讲解如果配置self-hosted
    steps: # 该作业所有的步骤集合,每个项都是一个单独的操作或shell脚本
      - uses: actions/checkout@v3 # 使用该仓库,检索代码
      - uses: actions/setup-node@v3 # 使用该仓库,安装指定版本的Node.js
        with:
          node-version: 16 # 指定node版本
      - run: echo "${{github.event.inputs.releaseStep}}" # 打印参数
      - run: npm install # 运行命令
      - run: npm run build
      - run: npm publish

2.4 什么是actions/checkout@v3

当第一眼看到actions/checkout@v3actions/setup-node@v3,会很好奇这是什么。其实他们是已经存在 github 上的一些仓库,是GitHub Actions中常用的 action

  • actions/checkout@v3: 检查 GitHub 仓库中的代码,并将代码检出到当前工作流程运行的虚拟机中。它还支持检出指定的分支、标记或提交 ID,并可以将检出目录指定为自定义目录。
yaml 复制代码
# 检出存储库的其他分支或标记,请在 with 字段中指定它们。例如,下面的示例将检出存储库的 v1.0 标记:
- name: Checkout code
  uses: actions/checkout@v2
  with:
  ref: v1.0

到此,你就完成了一个完整的发布流程内容。

  • push 到 master,将自动触发
  • workflow_dispatch: 需要到actions tab, 进行手动选择触发。

3 表达式 与变量

表达式可以是boolean, null, number, string数据类型,通过字段env:${{xxx}}进行使用。

  • 表达式中可以使用运算符||, &&, >=, <=, []索引等等。
  • 可以使用函数:contains('Hello world', 'llo'), startsWith('Hello world', 'He'), join, toJSON
  • if条件表达式,为 true, 执行下一步,false 不执行
  • 可通过env进行访问变量

tips: linux 使用 $varible_name获取变量, window 使用$env:varible_name获取变量。

yaml 复制代码
name: Node.js Package

on:
  workflow_dispatch:
env:
  DAY_OF_WEEK: DAY_OF_WEEK_Monday # 顶层变量

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: test_echo
        run: echo 'befrore'
      - name: test_if
        if: ${{ env.DAY_OF_WEEK == 'DAY_OF_WEEK_Monday' }}
        run: |
          echo " Today is $DAY_OF_WEEK!"
          echo "here is: $test_if_var"
          echo "$First_Name $MY_ENV_VAR"
        env:
          test_if_var: I'M TEST ENV VAR # test_if 的变量
    env: # teps test_echo 的变量
      First_Name: Mona
      MY_ENV_VAR: ${{ github.ref == 'refs/heads/main' && 'value_for_main_branch' || 'value_for_other_branches' }}

4 上下文

上下文是一种访问工作流运行、变量、运行器环境、作业、步骤相关信息的方式。每一个上下文都是一个包含属性的对象。我们可以通过${{context}}表达式语法访问上下文。

上下文名称 描述
github 工作流程运行的相关信息
env 包含工作流、作业或步骤中设置的变量
vars 存储库、组织或环境级别设置的变量
job 当前运行的作业的信息
steps 当前作业中已运行的步骤的信息
runner 运行当前作业的运行器的信息
runner 运行当前作业的运行器的信息
secrets 包含可用于工作流运行的机密的名称和值
needs 定义为当前作业直接依赖项的所有作业的输出
inputs 传递给操作可重用工作流或手动触发的工作流的输入属性
jobs 仅在可重用工作流中可用,并且只能用于设置可重用工作流的输出
strategy 对于具有矩阵的工作流,包含有关当前作业的矩阵执行策略的信息
matrix 对于具有矩阵的工作流, 包含工作流程文件中定义的适用于当前作业的矩阵属性

5. 触发工作流的方式

这里列举常用的触发工作流的方式:

  • 需要知道更详细的触发类型,请click here
  • 需要知道更详细的工作流程语法,请click here

5.1 事件触发

yaml 复制代码
### 事件触发,当 push 或者 fork 时,进行触发
on: [push, fork, page_build]

5.2 活动类型与筛选器

  • branchesbranches-ignore 筛选器: 接受 *、**、+、?! 等字符匹配多个分支名称的 glob 模式
yaml 复制代码
on:
  # 事件活动类型:使用 on.<event_name>.types 定义将触发工作流运行的事件活动类型
  label:  # 创建标签 触发(有created、edited 、deleted)
    types:
      - created

 # 创建issure时触发(有created、edited 、deleted), (labeled)被标记触发
  issues:
    types:
      - opened
      - labeled

 # 筛选器类型:push 事件具有 branches 筛选器
  push: # 筛选器向main分支推送触发
    branches:
      - main
    paths: # 只要推送 JavaScript 文件 (.js),就会运行以下工作流
      - '**.js'
      - '!sub/docs/**' # 该路径不触发
    paths-ignore: # 推送到`docs/**`的内容,将不触发
      - 'docs/**'

  # 筛选器类型:向分支进行PR的时候触发,向tag为`v2`(refs/tags/v2)或`v1.`(refs/tags/v1.9.1)开头的标记触发
  # !开头的,例如`releases/a-alpha`,将不触发
  pull_request:
    branches:
      - main
      - 'releases/*'
      - '!releases/**-alpha'
    tags:
      - v2
      - v1.*

  # 筛选器类型:向分支进行PR的时候触发,但被`branches-ignore`的分支不触发
  pull_request:
    branches-ignore:
      - 'mona/octocat'
      - 'releases/**-alpha'
    tags-ignore:
      - v2
      - v1.*

  # 指定触发工作流必须在哪些分支上运行才能触发工作流
  # 仅当名为 Build 的工作流在名称以 releases/ 开头的分支上运行时,具有以下触发器的工作流才会运行
  workflow_run:
    workflows: ["Build"]
    types: [requested]
    branches:
      - 'releases/**'

  # 仅当名为 Build 的工作流不在名为 "feature/**" 的分支上运行时,具有以下触发器的工作流才会运行
  workflow_run:
    workflows: ["Build"]
    types: [requested]
    branches-ignore:
      - "feature/**"

  #仅当名为`Greeting on variable day`的工作流执行完成后,再出发该工作流
  workflow_run:
  workflows: [Greeting on variable day]
  types:
    - completed
  #
  page_build: # 推送到启用了 GitHub Pages 的分支

5.3 手动触发

在前面的实例中,已经实践过手动触发的例子了

yaml 复制代码
on:
  workflow_dispatch:
    inputs:
      logLevel:
        description: 'Log level'
        required: true
        default: 'warning'
        type: choice
        options:
          - info
          - warning
          - debug
      print_tags:
        description: 'True to print to STDOUT'
        required: true
        type: boolean

jobs:
  print-tag:
    runs-on: ubuntu-latest
    if:  ${{ inputs.print_tags }}
    steps:
      - name: Print the input tag to STDOUT
        run: echo  The tags are ${{ inputs.logLevel }}
    - env:
          EVENT_CONTEXT: ${{ toJSON(github.event) }} # github.event 上下文打印出来, 查看哪些属性可用于触发工作流的事件
          PR: ${{ github.event.pull_request.html_url }} # 访问event事件属性

  # 向问题添加特定标签时,且标签name为`bug`, 运行工作流
  run_if_label_matches:
    if: github.event.label.name == 'bug'
    runs-on: ubuntu-latest
    steps:
      - run: echo 'The label was bug'

5.4 读取 package.json version

yaml 复制代码
name: Greeting on variable day

on: workflow_dispatch

jobs:
  greeting_job:
    runs-on: [self-hosted]

    steps:
      - name: Set color
        id: color-selector
        run: |
          echo "SELECTED_COLOR=green" >> $Env:GITHUB_OUTPUT
          $version = node -p "require('./package.json').version"
          echo "version_name=$version" >> $Env:GITHUB_OUTPUT
      - name: Get color
        env:
          TEST: ${{ steps.color-selector.outputs.version_name }}
        run: |
          echo "$env:TEST"

6. 利用Github Action进行Build和推送npm包,自动打Rlease Tag 完整实例

yaml 复制代码
name: biz-web-library-release
run-name: ${{ github.actor }} is learning GitHub Actions
# on:
#   push:
#     branches:
#       - master
on:
  workflow_dispatch:
    inputs:
      versionType:
        description: 'type of release version:'
        required: true
        default: 'patch'
        type: choice
        options:
          - patch
          - minor
          - major
      bodyContent:
        description: 'new feature:'
        required: true
        default: 'add new feature'
        type: string
  
jobs:
   npm-publish:
    runs-on: [ self-hosted ]
    steps:
      - name: step1:checkout code
        uses: actions/checkout@v3     
      
      - name: step2:download node
        uses: actions/setup-node@v3
        with:
          node-version: 16
      
      - name: step3:package version chagne and publish 
        run: |
         npm version ${{github.event.inputs.versionType}}
      - run: npm install
      - run: npm run build
      - run: npm publish
        
      - name: step4:set version name    
        id: version_name
        run: |
          echo "SELECTED_COLOR=green" >> $Env:GITHUB_OUTPUT
          $version = node -p "require('./package.json').version"
          echo "version_name=$version" >> $Env:GITHUB_OUTPUT
      
      - name: step5:create release
        id: create_release
        uses: actions/create-release@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
#           VERTION_NAME: ${{ steps.version_name.outputs.version_name }}
        with:
          tag_name: ${{ steps.version_name.outputs.version_name }}
          release_name: Release v${{ steps.version_name.outputs.version_name }}
          body: ${{github.event.inputs.bodyContent}}
          draft: false
          prerelease: false

      - name: step6:commit code(package.json's version)
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          git config --global user.email "xxx"
          git config --global user.name "xxx"
          git add .
          git commit -m "Commit Message"
          git push

7.利用Github Action在发布后进行文档构建

yaml 复制代码
name: deploy-page
run-name: ${{ github.actor }} is deploy oss page
# on:
#   push:
#     branches:
#       - master
on:
  workflow_dispatch:
  workflow_run:
    workflows: [biz-web-library-release]
    types:
      - completed
jobs:
   npm-publish-doc:
    runs-on: [ self-hosted ]
    steps:
      - name: step1:checkout code
        uses: actions/checkout@v3     
      
      - name: step2:download node
        uses: actions/setup-node@v3
        with:
          node-version: 16
      
      - name: step3:publish doc
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          git config --global user.email "xxx"
          git config --global user.name "xxx"
          npm install
          npm run docs:build
          npm run docs:deploy

8. 调试阶段遇到的问题

  • npm ERR! fatal: tag 'v1.0.5' already exists
html 复制代码
step1: 进入 \actions-runner\_work\工作目录 step2: 找到重复的tag: git tag step3:
删除tag: git tag -d v3.1.0
  • error: dst refspec refs/heads/master matches more than one
javascript 复制代码
git push origin :refs/tags/refs/heads/master
javascript 复制代码
as is:
>> $GITHUB_OUTPUT
to be:
>> $Env:GITHUB_OUTPUT
  • window服务器装git,可用windows PowerShell 的命令(记得输出参数:-OutFile)
javascript 复制代码
Invoke-WebRequest -Uri https://github.com/actions/runner/releases/download/v2.312.0/actions-runner-win-x64-2.312.0.zip -OutFile actions-runner.zip
  • window 服务器上dumi打包失败问题解决
ruby 复制代码
https://github.com/umijs/dumi/issues/1701
  • linux 安装runner运行两次./run.sh,但是启动后不能正确运行程序,因此换成了window。
相关推荐
王解1 小时前
Jest项目实战(4):将工具库顺利迁移到GitHub的完整指南
单元测试·github
油泼辣子多加1 小时前
2024年11月4日Github流行趋势
github
梓羽玩Python2 小时前
推荐一款用了5年的全能下载神器:Motrix!全平台支持,不限速下载网盘文件就靠它!
程序员·开源·github
小牛itbull9 小时前
ReactPress:重塑内容管理的未来
react.js·github·reactpress
鱼满满记16 小时前
1.6K+ Star!GenAIScript:一个可自动化的GenAI脚本环境
人工智能·ai·github
梦魇梦狸º19 小时前
腾讯轻量云服务器docker拉取不到镜像的问题:拉取超时
docker·容器·github
Huazie1 天前
一篇搞定 Hexo Diversity 主题接入!支持多主题自由切换!
javascript·github·hexo
草明2 天前
Nginx 做反向代理,一个服务优先被使用,当无法提供服务时才使用其他的备用服务
运维·nginx·github
马里嗷2 天前
Puppeteer - 掌控浏览器自动化的开源利器
后端·github