写一个微信小程序快速发版的 Github Action,并发布到 GitHub Marketplace

为什么要做一个 微信小程序快速发版的 GitHub Action?

  • 小程序代码在 GitHub 仓库中,在微信小程序开发中,代码提交后想自动发布体验版。
  • 不想直接在项目代码中去调用 miniprogram-ci
  • 使用其他人写的 Action 跑不通,会报错,比如遇到了 core-js 版本问题,无法定制化。
  • 自己去研究了别人写的 Action,发现原来这么简单,因此就自己写一个吧!

下面会先讲解如何在 GitHub 项目中使用 GitHub Action,然后再带大家去手写一个微信小程序快速发版的 GitHub Action,并发布到 GitHub Marketplace

如何使用

什么是 Github Action

GitHub Actions 是一个 GitHub 提供的自动化和持续集成/持续部署(CI/CD)平台,它允许您在 GitHub 仓库中自动运行工作流程。使用 GitHub Actions,您可以自动化软件开发工作流程,例如构建、测试和部署代码。这个功能直接集成在 GitHub 仓库中,使得自动化流程变得非常方便。

我们只需要在项目根目录下新建 .github/workflows/xxx.yaml,然后根据规则去写构建流程,触发时机,代码提交或者合并后就会自动触发,在这里可以做很多构建,测试,部署之类的工作。

我上面的配置实现的具体步骤:

  • Checkout:切换分支
  • Install:下载依赖
  • Build:打包小程序
  • Upload:上传小程序体验版

这些参数的用法可以直接 ChatGPT,相信它的回答会比我在这里写更清楚,接下来直接上手写一个 Action,其实就是 uses: upJiang/jiang-miniprogram-ci@main,这个东西我们要自己写一个,而不是用别人的。

编写 Action

项目初始化

  • GitHub 中创建一个项目,比如我的 jiang-miniprogram-ci
  • 进入项目,执行 npm init,常规设置不多说,入口文件定义 index.js 就行了
  • 安装依赖
bash 复制代码
yarn @actions/core miniprogram-ci dayjs

获取小程序代码上传密钥、并关联项目

  • 微信公众平台的开发管理中,下载小程序代码上传密钥,并且关闭 IP 白名单
  • GitHub 项目中(非 Action 项目)的 setting 添加一个变量名 PRIVATE_KEY,写入上一步获取的小程序代码上传密钥,这个变量我们后面需要传给 Action

编写代码

思路步骤:

  • 我们需要先拿到用户在 upload.yaml 中写的一些变量,在代码中通过 @actions/core 提供方法去获取
    • project-path (必填):项目路径,比如 distuniapp 项目一般是 dist/build/mp-weixin
    • private-key (必填):前面设置的 PRIVATE_KEY,如:${{ secrets.PRIVATE_KEY }}
    • robot:机器人编号,默认是 1
    • desc:本次提交的修改描述
    • version:本次提交的版本号
  • 然后通过 miniprogram-ci 提供的方法传入参数去上传
  • 期间我们需要下载这个 Action 项目的依赖,在 pre 设置中去提前下载

编写入口文件 index.js

php 复制代码
const core = require("@actions/core");
const fs = require("fs");
const path = require("path");
const ci = require("miniprogram-ci");
const dayjs = require("dayjs");

async function run() {
  try {
    const projectPath = core.getInput("project-path", { required: true });
    const privatekey = core.getInput("private-key", { required: true });

    // 构建完整的 project.config.json 路径
    const projectConfigPath = path.join(projectPath, "project.config.json");
    console.log("projectConfigPath", projectConfigPath);
    // 读取和解析 project.config.json 文件
    const projectConfig = JSON.parse(
      fs.readFileSync(projectConfigPath, "utf8")
    );

    // 从 project.config.json 获取需要的配置,这里拿到 appid
    const appid = projectConfig.appid;

    // 版本信息
    const version = core.getInput("version") || "1.0.0";
    // 本次提交的描述
    const description =
      core.getInput("desc") || `更新于${dayjs().format("YYYY-MM-DD HH:mm:ss")}`;

    // 创建 Project 实例
    const project = new ci.Project({
      appid,
      type: "miniProgram",
      projectPath,
      privateKey: privatekey,
      ignores: ["node_modules/**/*"],
    });

    // 其他配置
    const context = {
      compileOptions: {}, // 编译配置
      robot: core.getInput("robot") || 1, // 机器人编号
      threads: 1, // 线程数
      allowIgnoreUnusedFiles: false, // 允许忽略未使用的文件
    };

    // 上传进度的回调函数
    const onProgressUpdate = (info) => {
      console.log("上传进度:", info);
    };

    // 执行上传
    await ci.upload({
      project,
      version,
      desc: description,
      setting: context.compileOptions,
      robot: context.robot,
      threads: context.threads,
      allowIgnoreUnusedFiles: context.allowIgnoreUnusedFiles,
      onProgressUpdate,
    });
  } catch (error) {
    core.setFailed(error.message);
  }
}

run();

根目录下新建 action.yml,编写这个 Action 中需要做的步骤

  • inputs:定义需要用户传入的字段,以及是否必须
  • runs:定义运行环境,入口文件,pre 预处理,这里直接执行一个 js 文件,用于下载当前项目的依赖
yaml 复制代码
name: "jiang-miniprogram-ci"
description: "Based on the miniprogram-ci.A GitHub Action to automate deploying WeChat MiniProgram. "
author: "jiang"
inputs:
  project-path:
    description: "projectPath"
    required: true
  private-key:
    description: "privatekey"
    required: true
  version:
    description: "Version"
    required: false
  desc:
    description: "description"
    required: false
  robot:
    description: "robot"
    required: false
runs:
  using: "node16"
  main: "index.js"
  pre: "./pre-install.js"

**根目录下新建 pre-install.js,用于下载当前依赖

bash 复制代码
const { execSync } = require("child_process");

function exec(command) {
  execSync(command, {
    cwd: __dirname,
    stdio: "inherit",
  });
}

exec("npm install yarn -g");
exec("yarn --frozen-lockfile");

测试

我们在测试项目中去使用这个 Action,测试项目必须要有 .github/workflows/xxx.yaml,注意 uses 改成自己 Action,规则是:你的 GitHub 名称/仓库名称@分支

yaml 复制代码
name: 上传小程序体验版
on:
  push:
    branches:
      - main
jobs:
  upload:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3
      - name: Install
        run: yarn
      - name: Build
        run: yarn build
      - name: Upload
        uses: upJiang/jiang-miniprogram-ci@main
        with:
          project-path: dist/build/mp-weixin
          private-key: ${{ secrets.PRIVATE_KEY }}

提交代码后,在 GitHub 中去不断重跑就可以快速测试了

发布

你的Action根目录下如果有 action.yml 应该会自动有这个发布提示

发布的前提是必须要有一个 tag,那就添加一个 tag,然后正常发布就行了

css 复制代码
git tag v1.0.0
git push origin --tag

所有东西填完发布后,在 GitHub Marketplace 立马就能搜到了,别人也能使用你的 Action 了。

如果有问题可以直接下载代码尝试,项目代码地址,很基础,但是也挺有用,可以学习一下 CI/CD 的原理,一般公司都会使用 GitLab,其实原理也是一样的。

相关推荐
小镇程序员13 分钟前
vue2 src_Todolist全局总线事件版本
前端·javascript·vue.js
野槐15 分钟前
前端图像处理(一)
前端
程序猿阿伟22 分钟前
《智能指针频繁创建销毁:程序性能的“隐形杀手”》
java·开发语言·前端
疯狂的沙粒24 分钟前
对 TypeScript 中函数如何更好的理解及使用?与 JavaScript 函数有哪些区别?
前端·javascript·typescript
瑞雨溪32 分钟前
AJAX的基本使用
前端·javascript·ajax
力透键背35 分钟前
display: none和visibility: hidden的区别
开发语言·前端·javascript
程楠楠&M1 小时前
node.js第三方Express 框架
前端·javascript·node.js·express
盛夏绽放1 小时前
Node.js 和 Socket.IO 实现实时通信
前端·后端·websocket·node.js
想自律的露西西★1 小时前
用el-scrollbar实现滚动条,拖动滚动条可以滚动,但是通过鼠标滑轮却无效
前端·javascript·css·vue.js·elementui·前端框架·html5
白墨阳1 小时前
vue3:瀑布流
前端·javascript·vue.js