6. 发布到 github marketplace
在手机上下载微软的 Authenticator 软件 , 然后扫描 Github 的 Two factor 绑定的二维码 , 这样你的 Github Action 就被顺利的发布到了 插件市场 里了 。
庆祝一下你的成功吧!
开始进阶之旅
当然笔者远不止想介绍这么多 , 不然标题的 多用途 三个字就没提现出来 。
接下来我们同时要把这个包的主逻辑抽离出来 , 发布成 npm 包 , 再通过 mock 的上下文 , 构建单元测试用例 。 具体怎么做呢?
核心其实很简单:代码分割 和 条件编译
0. 条件编译
我们开发者对这个再熟悉不过了 , 通过条件编译可以直接去除一些 unreachable code , 比如我们发布成 npm 包给用户用 , 自然是不需要 @actions/core 和 @actions/github 的 。那么就可以在打包时直接把它们干掉 。
实现它的手段很多 , 比如 webpack.DefinePlugin , @rollup/plugin-replace , esbuild#define 等等 。
1. 代码分割
这个借助打包工具也很容易实现 , 比如我们原先引入是用静态写法:
import { getActionOptions from './action'
接下来我们改为 async/await动态引入
async function mian() { const { getActionOptions = await import('./action')
通过这种方式 , 打包工具除了默认的 output 配置 , 会生成 [name
.js 的 entryFile 外 , 还会生成一些 [name
-[hash
.js 的 chunkFile , 来交给运行时动态加载 。
2. 添加条件变量 , 并统筹
这里我们添加一个 __isAction__ 的布尔值变量
declare var __isAction__: boolean
对于 action 和 npm 的不同 , 主要在于它们的入参出参方式不同 , 还有上下文不同 。
那么我们就可以根据这 2 点 , 进行编译时重载:
3. 重载获取参数
我们获取参数就可以这么写:
export async function getOptions ( options?: UserDefinedOptions): Promise<UserDefinedOptions> { let opt: Partial<UserDefinedOptions> if (__isAction__) { const { getActionOptions = await import('./action') opt = getActionOptions() else { opt = options return defu<Partial<UserDefinedOptions> UserDefinedOptions>( opt getDefaults() ) as UserDefinedOptions
这样在打包时就能确定代码的走向 。
4. 重载获取
我们获取 Octokit 实例就可以这么写:
const { token = optionslet octokitif (__isAction__) { const { github = await import('./action') octokit = github.getOctokit(token) else { const { Octokit = await import('@octokit/rest') // require() octokit = new Octokit({ auth: token )
这样 action 走 @actions/github , 默认情况下走 @octokit/rest , 获得的 Octokit 也是一致的 。
5. 更改打包配置
我们添加 BUILD_TARGET 环境变量 , 当值为 action 打包 Action , 默认为 npm 包 。
这样我们很容易可以编写出这样的 rollup.config.js:
import typescript from '@rollup/plugin-typescript'import { nodeResolve from '@rollup/plugin-node-resolve'import commonjs from '@rollup/plugin-commonjs'import json from '@rollup/plugin-json'import pkg from './package.json'import replace from '@rollup/plugin-replace'import { terser from 'rollup-plugin-terser'const isDev = process.env.NODE_ENV === 'development'const isAction = process.env.BUILD_TARGET === 'action'/** @type {import('rollup').OutputOptions */const npmOutput = { file: pkg.main format: 'cjs' sourcemap: isDev exports: 'auto'/** @type {import('rollup').OutputOptions */const actionOutput = { dir: 'lib' format: 'cjs' exports: 'auto'/** @type {import('rollup').RollupOptions */const config = { input: 'src/index.ts' output: isAction ? actionOutput : npmOutput plugins: [ isAction ? terser() : undefined replace({ preventAssignment: true values: { __isAction__: JSON.stringify(isAction) ) json() nodeResolve({ preferBuiltins: true ) commonjs() typescript({ tsconfig: isAction ? './tsconfig.action.json' : './tsconfig.build.json' sourceMap: isDev )
- QQ音乐11.5.5全新升级,一起看见音乐之美
- 小米|12年前和雷军一起喝小米粥的员工再聚首 雷军:谢谢大家
- 雷军:在一起就有动人故事,小米12周年致米粉的信
- 我国原来还有这么多领域被卡脖子,你还知道哪些?一起盘点一下
- 一起守沪上海加油——友谊路街道综合行政执法队抗疫日记
- 华为荣耀|如果当时余承东跟着荣耀一起离开了华为,离开后会产生什么后果
- “回宿舍吗?”“一起走吧!”
- 电子商务|让我们一起去T I K tok淘金吧
- GitHub|重磅升级!iPhone16系列引入屏下Face ID,安全又美观?
- 网友热议|袁隆平夫人口罩上的话让人泪目:一起回顾袁爷爷说过的那些话