写一个微信小程序快速发版的 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,其实原理也是一样的。

相关推荐
加班是不可能的,除非双倍日工资2 小时前
css预编译器实现星空背景图
前端·css·vue3
wyiyiyi3 小时前
【Web后端】Django、flask及其场景——以构建系统原型为例
前端·数据库·后端·python·django·flask
gnip3 小时前
vite和webpack打包结构控制
前端·javascript
excel3 小时前
在二维 Canvas 中模拟三角形绕 X、Y 轴旋转
前端
阿华的代码王国4 小时前
【Android】RecyclerView复用CheckBox的异常状态
android·xml·java·前端·后端
一条上岸小咸鱼4 小时前
Kotlin 基本数据类型(三):Booleans、Characters
android·前端·kotlin
Jimmy4 小时前
AI 代理是什么,其有助于我们实现更智能编程
前端·后端·ai编程
草梅友仁4 小时前
草梅 Auth 1.4.0 发布与 ESLint v9 更新 | 2025 年第 33 周草梅周报
vue.js·github·nuxt.js
ZXT4 小时前
promise & async await总结
前端
Jerry说前后端4 小时前
RecyclerView 性能优化:从原理到实践的深度优化方案
android·前端·性能优化