thumbnail
本文的起因是Salary主题的 Github Action 自动 打 Tag 流程,每次都需要手动修改 package.json 去触发新版本打 tag ,由于不想每次都手动修改,于是有了本文的实践。
SCOTT STUDIO

Nodejs实现脚本

我们首先需要在工程目录中的下增加一个 update-version.js脚本

实现更新脚本

//update-version.js

const path = require('path');
const fs = require('fs');
const newVersion = process.argv[2].replace(/^v/, ''); // 获取命令行参数中的新版本号,并过滤v字头

if (!newVersion) {
    console.log('请传入新版本号,版本号遵循semver规范 .eg: 1.0.0, 1.0.1, 1.1.0');
    process.exit(1);
}

// 获取当前命令行上下文路径

const currentDirectory = process.cwd();

// 获取 package.json 文件中的版本号
const packageJsonPath = path.join(currentDirectory, 'package.json');
const packageJsonPathOut = path.join(currentDirectory, '../package.json');
const packageJsonContent = fs.readFileSync(packageJsonPath, 'utf8');
const packageJson = JSON.parse(packageJsonContent);
const currentVersion = packageJson.version;

// 更新 package.json 文件中的版本号

packageJson.version = newVersion;
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
fs.writeFileSync(packageJsonPathOut, JSON.stringify(packageJson, null, 2));
console.log(`版本号已从 ${currentVersion} 更新为 ${newVersion}`);

修改脚本运行配置

接下来在 package.json script 配置后可以直接使用 npm run version <version> 中触发变更版本号脚本。当然这个前提是想要让这个脚本保留给开发者命令行使用。

{

    "name": "version workflow",
    "version": "1.0.0",
    "description": "version update demo",
    "main": "index.js",
    "scripts": {
        //...
        "version": "node ./scripts/update-version.js"
    },
    //...

}

如何利用Github Action自动发布版本并且打Tag

接下来算重头戏,如何让发布包的行为直接和代码仓库中的版本号同步?这里我们使用的是github 提供的github action,具体操作和语法可以查看一下官方文档,本文就不过多展开。

我们需要在仓库根目录增加如下路径的文件 .github/workflows/update-action.yml

# action名称
name: Push Release

# 当代码提交到main分支时,执行脚本
on:
  push:
    branches:
      - main
#任务
jobs:
  publish-release:
    runs-on: ubuntu-latest
    steps:
      # 检查并切换到主分支
      - name: 检查分支
        uses: actions/checkout@main

      #安装node
      - name: 设置NodeJS
        uses: actions/setup-node@main
        with:
          node-version: 16

      # npm install
      - name: 读取当前版本号
        id: version
        uses: ashley-taylor/read-json-property-action@v1.0
        with:
          path: ./package.json
          property: version
      - name: npm install and build
        run: |
          cd source
          npm install
          npm run build
          cd ..
          pwd
          tar -zcvf salary_v${{steps.version.outputs.value}}.tar.gz --exclude=./source --exclude=./.git --exclude=./.github --exclude=./.gitignore --exclude=./readme.md ./*
      - 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: 上传Release Asset
        id: upload-release-asset
        uses: actions/upload-release-asset@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          upload_url: ${{ steps.create_release.outputs.upload_url }}
          asset_path: ./salary_v${{steps.version.outputs.value}}.tar.gz
          asset_name: salary_v${{steps.version.outputs.value}}.tar.gz
          asset_content_type: application/tar+gzip

我们在 release hook 中的 released 状态下增加了一个 publish-release job。它会做下面几件事情

  • 检查并切换到主分支
  • 安装nodeJS环境
  • 读取package.json中的版本号
  • 打包代码
  • 创建GitHub Release
  • 上传Release Asset

当你提交代码之后,这个脚本会自动运行。

Salary主题自动打包案例

以上的代码实现的是每次需要先手动运行脚本修改版本号,然后再提交代码到github触发自动发布版本打tag。

看起来好像没什么区别,都是每次都需要运行脚本去修改。

在Salary的开发中,我是这么做的:

{
  "name": "salary",
  "type": "module",
  "version": "0.0.10",
  "private": true,
  "scripts": {
    "tag": "vite build --config ./config/vite.config.prod.ts && node ../update-version.js",
  },
  ...
}

在本地开发主题时,我们经常要做的就是手动打包项目,所以通过把本地打包的命令和修改版本号的命令结合在一起,这样就省去了额外的修改版本号的脚本运行。

只需要在打包的时候运行 npm run tag v0.0.10即可。