曾静的博客

但行好事,莫问前程.

嗨,我是曾静 (@devzeng),目前暂居深圳。


这是我用来记录平日学习笔记的地方,欢迎您的访问.

自定义GitHub Actions

GitHub Actions 是 GitHub 官方推出的持续集成和持续交付(CI/CD)平台,可以让用户便捷实现自动化构建、测试和部署流程。

github-actions

关于 GitHub Actions

GitHub Actions 有几个概念(workflow、event、job、action、step、runner),下面会简单介绍常用的workflow、job、step的使用。

overview-actions-simple

workflow (工作流程)

workflow 是可配置的自动化流程,可以运行一个或多个job。workflow 由仓库 .github\workflows 目录下的 yaml 文件定义。每个项目可以有一个或多个workflow。下面是一个简单的webpack构建的流程:

name: webpack

on:
  workflow_dispatch:
  push:
    tags:
      - '*'

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        id: checkout
        uses: actions/checkout@v4

      - name: Build
        id: build
        run: |
          npm install
          npm run build

Workflow文件语法特别多也比较复杂,详细参考官方文档 Workflow syntax for GitHub Actions,一般我们需要使用下面的几个字段的定义。

(1) name

name workflow的名称,可为空默认是workflow文件的名称,配置示例如下:

name: 'workflow name'

(2) on

on 指定触发workflow的条件,配置示例如下:

on:
  workflow_dispatch:
  push:
    tags:
      - '*'

上面的示例表示 手动触发(workflow_dispatch) 和 任意tag push的时候触发,更多触发条件,可以参考官方的文档 Triggering a workflow

(3) jobs

1) jobs..name

name 表示任务的名称,可以不填

jobs:
    job1:
        name: job1
    job2:
        name: job2
2) jobs..needs

needs 指定当前任务的依赖关系,可以通过设置needs来控制job的运行顺序。示例代码如下:

jobs:
    job1:
        name: job1
    job2:
        name: job2
        needs: job1
    job3:
        name: job3
        needs: [job1, job2]

上面代码表示任务按照 job1 > job2 > job3 的顺序执行。

3) jobs..runs-on

runs-on 必填字段,表示当前指定的运行环境。目前支持的环境如下:

  • ubuntu-latest 或 ubuntu-20.04、ubuntu-22.04
  • windows-latest 或 windows-2019、windows-2022
  • macos-latest 或 macos-14、macos-13

更多配置和环境说明可以参考官方文档。About GitHub-hosted runners

不同的任务可以使用不同环境,比如部分跨平台的项目可以在各自平台的宿主容器上面单独编译,示例代码如下:

jobs:
  job1:
    runs-on: ubuntu-latest

  job2:
    runs-on: windows-latest

  job3:
    runs-on: macos-latest
4) jobs..steps

steps 指定每个job下运行的步骤,可以有一个或多个step。step参数定义:

  • jobs..steps.name: 步骤名称
  • jobs..steps.id: 步骤ID
  • jobs..steps.uses: 使用的action,如actions/checkout@v4,表示用户actions的checkout 库 的v4 tag
  • jobs..steps.env: 步骤需要的环境变量
  • jobs..steps.run: 步骤上运行的命令
  • jobs..steps.with: action需要的参数

示例代码如下:

jobs:
  build:
    runs-on: ubuntu-latest

    env:
      FIRST_NAME: Mona

    steps:
      - name: Checkout
        id: checkout
        uses: actions/checkout@v4

      - name: Setup Node.js
        id: setup-node
        uses: actions/setup-node@v4
        with:
          node-version-file: .node-version
          cache: npm

      - name: My first step
        uses: actions/hello_world@main
        with:
          first_name: Mona
          middle_name: The
          last_name: Octocat

      - name: Print a greeting
        env:
          MY_VAR: Hi there! My name is
          FIRST_NAME: Mona
          MIDDLE_NAME: The
          LAST_NAME: Octocat
        run: |
          echo $MY_VAR $FIRST_NAME $MIDDLE_NAME $LAST_NAME.

定制 GitHub Actions

GitHub 官方提供了一个插件市场(Marketplace),可以在里面找到其他人开发的actions,基本上你需要的功能都可以在上面找到。

github-marketplace

但是有些时候没有合适的action我们可以考虑创建自己的action。GitHub官方也非常贴心提供了一个体验课程《Creating actions》开发一个专属的action。

目前支持创建 Docker/Javascript/Composite Actions 三种 action, 下面以一个实际的例子来介绍如何开发一个Javascript action。

1、创建

GitHub 官方提供两个模板工程 typescript-actionjavascript-action,在创建的时候可以选择。

action-template

点右上角的 Use this template 可以快速创建一个项目仓库

create-template-repo

2、开发

需要开发一个action实现将编译产物上传到upyun的功能,要求支持上传多个文件。使用upyun官方提供的npm库实现。

npm install upyun --save
npm install @types/upyun --save-dev

(1) 定义 action 描述文件

每个 action 的输入输出定义在 action.yml 文件中,下面是示例代码:

name: 'upyun-deploy-action'
description: 'GitHub Actions upyun deploy'
author: 'zengjing'

# Define your inputs here.
inputs:
  path:
    description: 'input path parameters'
    required: true

# Define your outputs here.
outputs:
  result:
    description: 'output result'

runs:
  using: node20
  main: dist/index.js

(2) 获取输入参数

import * as core from '@actions/core'

export interface UploadInputs {
  srcPath: string
  destPath: string
}

export function getInputs(): UploadInputs[] {
  const path = core.getInput(Inputs.Path, { required: true })
  const lines = path.split(/[\s\n]/)
  const inputs: UploadInputs[] = []
  for (const line of lines) {
    const items = line.split('->')
    if (items.length === 2) {
      const srcPath: string = items[0].trim()
      const destPath: string = items[1].trim()
      const input = { srcPath: srcPath, destPath: destPath } as UploadInputs
      inputs.push(input)
    }
  }
  return inputs
}

(3) 上传文件

import * as core from '@actions/core'

export interface UploadOutputs {
  srcPath: string
  destPath: string
  result: boolean
}

export function uploadArtifacts(inputs: UploadInputs[]): UploadOutputs[] {
    const results: UploadOutputs[] = []
    for (const input of inputs) {
        core.info(`Start to upload artifact from ${input.srcPath} to ${input.destPath}`)
        try {
            const result = await uploadArtifact(input.srcPath, input.destPath)
            results.push({ srcPath: input.srcPath, destPath: input.destPath, result: result })
        } catch (e) {
            results.push({ srcPath: input.srcPath, destPath: input.destPath, result: false })
        }
    }
    return results
}

(4) 输出结果

import * as core from '@actions/core'

// Set outputs for other workflow steps to use
core.setOutput('result', JSON.stringify(results))

(5)发布

npm run bundle

打包完成后提交代码,项目根目录下面有个 script\release 这个脚本可以创建tag并发布。

3、使用

因为上传到upyun需要三个配置 service/operator/password,在代码里面是通过环境变量获取的

需要先在项目设置里面配置 (Settings -> Security -> Secrets and variables -> Actions),点 New repository secret添加Secrets。

github-secrets

在workflow添加step:

- name: Upload
  uses: hhtczengjing/upyun-deploy@v1
  env:
   UPYUN_SERVICE_NAME: $
   UPYUN_OPERATOR: $
   UPYUN_PASSWORD: $
  with:
   path: |
      version.json->/versions/products
      package.json->/versions/products

最终的代码在:https://github.com/hhtczengjing/upyun-deploy.git

参考资料

最近的文章

hvigor插件开发实战

hvigor 构建工具是一款基于 TypeScript 实现的构建任务编排工具,主要提供任务管理机制,包括任务注册编排、工程模型管理、配置管理等关键能力,提供专用于构建和测试应用的流程和可配置设置。DevEco Studio 使用构建工具 hvigor 来自动执行和管理构建流程,实现应用/服务构建任务流的执行,完成 HAP/APP 的构建打包。hvigor 允许开发者实现自己的插件,开发者可以定义自己的构建逻辑。目前主要提供了两种方式来实现插件:基于hvigorfile脚本开发插件 和 基...…

Note继续阅读
更早的文章

iOS推送设置个性化消息提示音

更新到 iOS 17 后,不少用户反馈默认的通知声音不一样了,觉得新的提示音太安静了,以至于错过某些关键的通知。很可惜的是我们无法指导用户通过设置更改 App 默认的通知铃声,只能更改系统自带APP相关的提示音(如:电话、短信、提醒、收到新邮件声等)。部分用户表示微信可以修改推送的铃声,而且是修改完立即就生效了。设置界面效果:首先想到的是 APNs 推送可以指定 sound 字段,用于设置用户的铃声,大多数APP使用的跟随系统默认就是 default。示例数据:{ "aps" : {...…

iOS继续阅读