GitHub Actionsでリポジトリローカルなactionを実行する

同じリポジトリ内にあるactionを uses: ./.github/actions/my-action のようなかたちで使うやつ。

以下の記事が詳しい:

qiita.com

node_modulesのコミットが必要でactions/toolkitが使いにくいが、素のNode.jsでもいろいろできる。 処理を共通化したいけどサードパーティーのactionを使いたくない…という時に便利。

入出力とか

  • 入力は process.env.INPUT_... という環境変数からとれる
  • 出力は process.stdout.write("::set-output ...") とかでできる
  • もっとスマートなやり方はわからず
  • xxxSyncをrequireすればたいていのことはできる印象

ecspressoのインストール

  • .github/actions/install-ecspresso/action.yml
name: install-ecspresso
description: Install ecspresso
runs:
  using: node12
  main: index.js
inputs:
  version:
    description: ecspresso version
    default: 1.6.2
    required: true
  • .github/actions/install-ecspresso/index.js
const { execSync } = require("child_process");
const { renameSync } = require("fs");

let version = process.env.INPUT_VERSION;
let url = `https://github.com/kayac/ecspresso/releases/download/v${version}/ecspresso_${version}_linux_amd64.tar.gz`;

execSync(`curl -sSfL ${url} | tar zx`);
renameSync("ecspresso", "/usr/local/bin/ecspresso");

uses: ./.github/actions/install-ecspresso みたいな感じで使う

secretのssh keyを~/.sshに置くやつ

name: write-ssh-key
description: Write ssh key
runs:
  using: node12
  main: index.js
inputs:
  ssh_key:
    description: ssh key
    required: true
  file_name:
    description: file name
    default: id_rsa
    required: true
outputs:
  key_path:
    description: ssh key file path
const { execSync } = require("child_process");
const { mkdirSync, writeFileSync } = require("fs");
const os = require("os");

let file_name = process.env.INPUT_FILE_NAME;
let ssh_key = process.env.INPUT_SSH_KEY;

mkdirSync(`${process.env.HOME}/.ssh`);

writeFileSync(`${process.env.HOME}/.ssh/${file_name}`, ssh_key, {
  mode: 0o600,
});

process.stdout.write(
  `::set-output name=key_path::${process.env.HOME}/.ssh/${file_name}${os.EOL}`
);

stepにidをつけておくと steps.{{ id }}.outputs.key_path のようなかたちでファイルのパスを参照できる。