前言

在github action中使用了sql-lint来分析sql语句, 但是在里面写bash不够优雅,所以尝试根据Github官方提供的Github action教程, 写了一个自己的一个action来调用sql-lint。

实现选择

官方提供了两类action,一类是compose action,即在里面使用bash来执行每步, 还有一类是nodejs action,在里面调用index.js来执行插件操作, 但是bash处理文件流并不优雅了,后续维护也成问题,就决定使用JavaScript写。 毕竟bash能干的,nodejs肯定也能。

但是,sql-lint本身是ts写的,但是没有留出调用的接口,只能被迫偷懒使用nodejs运行 命令来调用sql-lint,所幸sql-lint仓库也有打包出来的excutable版本。

于是,我们的实现就变成了

  • nodejs负责接收action参数,参数处理,和命令执行
  • bash负责下载sql-lint可执行文件,调用sql-lint

具体实现

参考如何创建javascript action,以下是github 官方的模板

const core = require('@actions/core');
const github = require('@actions/github');

try {
  // `who-to-greet` input defined in action metadata file
  const nameToGreet = core.getInput('who-to-greet');
  console.log(`Hello ${nameToGreet}!`);
  const time = (new Date()).toTimeString();
  core.setOutput("time", time);
  // Get the JSON webhook payload for the event that triggered the workflow
  const payload = JSON.stringify(github.context.payload, undefined, 2)
  console.log(`The event payload: ${payload}`);
} catch (error) {
  core.setFailed(error.message);
}
  • actions/core包主要处理github action时的参数传入传出,异常处理。
  • actions/github包主要处理一些调用github api的情况。

我们的需求里面没有跟github相关的,所以只需要用到core包就好。 nodejs的命令执行代码promise写的还是比较舒服的,像下面这样封装一下就好。

	exec(bashcommand, (err, stdout, stderr) => {
		if (err) {
			core.setFailed(err.message);
  	}

		console.log(`stdout: ${stdout}`);
		if (stderr){
			core.setFailed(`stderr: ${stderr}`);
		}
	});

下载的命令部分用来一点点trick来实现,以下是

sudo curl -L https://github.com/joereynolds/sql-lint/releases/latest/download/sql-lint-linux -o  /usr/local/bin/sql-lint &&
sudo chmod +x /usr/local/bin/sql-lint &&
sudo ln -s /usr/local/bin/sql-lint /usr/bin/sql-lint

github的release uri 会重定向成最新的release,保证使用的sql-lint版本是最新的。

同时我们还需要初始化sql-lint的config.json,使用nodejs的fs模块实现即可, nodejs处理json数据也很方便,只需要把object给stringify后写入即可。 不过需要注意用同步阻塞的方式,不然调用的时候这边还没写进去。

writeFileSync('/tmp/config.json',JSON.stringify(config_data),{flag: 'w',overwrite:true})

随后就是打包发布,这里需要使用ncc对引用到的文件license整理,以及把nodejs文件汇总成一个index.js, 同时附带引用的文件的licenses.txt文件。

ncc build index.js --license licenses.txt

剩下的就是发布,只要按照要求写好readme.md,按照并按照github官方的[action 发布流程][action 发布流程]设置release并发布即可。

最终,商店中的action页面如,sql-lint-in-action

总结

这里使用了一些nodejs的命令执行库和文件读写库,总的来说体验还不错。 Github官方提供的workflow工具也很舒服,就是仍有优化的空间, 比如现在要带上node_modules打包就不是很舒服,感觉还可以继续优化, 还有如何用github action来测试action的部分感觉官方也是浅尝辄止, 具体的代码质量还得靠语言本身的一些单测工具来验证。

技术点

  • nodejs的文件读写、命令执行
  • github action的打包发布

留下的坑

  • 把bash部分替换成nodejs实现。
  • 增强错误信息处理部分。
  • 把node_modules移除,在打包发布时再构建。

参考资料