Paper2 Blog

ともに、かける

GitHub ActionをTypeScriptのテンプレートを使って爆速でマーケットプレイスに公開する

以前TypeScriptのActionテンプレートを紹介したら結構反響がありました。実際使ってみているのですがコンパイル、テスト、検証ワークフロー、マーケットプレイスへの公開の仕組みなど色々詰まっていて良い感じです。

リポジトリのリンターなどの要素技術は別途紹介するとして、今回は利用方法を丁寧に紹介しようと思います。

GitHub ActionのTypeScriptテンプレートとは

TypeScriptでJavaScriptのActionを作るのに必要な仕組みが色々詰まったテンプレートリポジトリです。

github.com

Actionを作成し、マーケットプレイスに公開すると以下のようなお馴染みの方法でActionが利用できるようになります。

- name: paper2-getting-started-typescript-actions
  uses: paper2/getting-started-typescript-actions@v0.0.1            

テンプレートを利用することで以下のようなメリットがあります。

  • 自作GitHub Action ナニモワカラン状態でも必要なものを早く整えられる*1
  • 慣れた人が使う場合でも、必要なものを毎回用意しなくて済む
  • テストやリントの仕組みが最初から組み込まれているので品質担保しやすくなる ...etc

デメリットを挙げるなら以下でしょうか。

  • CommonJSを前提としているのでもしPureESMを利用しようとすると大幅な変更が必要(基本大丈夫)
    • 私はそれを知らずに挑戦してしまい、かなり時間を消費しました。
    • 勉強にはなるので興味がある人はPureESMしか提供しないoctokitを利用したAction作成に挑戦してみてくださいww
  • リントなどがしっかりしているので作り上げるまでに時間がかかる ...etc

利用方法

テンプレート機能でリポジトリを複製する

リポジトリの上部にある「Use this template」ボタンをクリックし、「Create a new repository」を選択します。

テンプレートの利用

リポジトリを作成します。

リポジトリ作成

初期設定

リポジトリをローカルにクローンしたら、アクションを開発する前にいくつかの初期設定が必要になります。

依存関係のインストール

Node.jsの最新バージョン(20.x以降)が必要です。適宜インストールしてください。

nodenv や nvm のようなバージョン管理ツールを使っている場合、リポジトリルートの .node-version ファイルが参照され、リポジトリに cd したときに自動的に正しいバージョンに切り替わります。

この .node-version ファイルは GitHub Actions の actions/setup-node アクションで使われているので他のバージョン管理ツールを利用している場合適宜バージョンを変更してください。

依存関係を以下のコマンドでインストールします。

$ npm install

action.ymlの変更

マーケットプレイスに公開するためにaction名などを変更します。

例えば以下のように変更しておきます。(nameは一意である必要があります。)

diff --git a/action.yml b/action.yml
index 101186a..87d6187 100644
--- a/action.yml
+++ b/action.yml
@@ -1,6 +1,6 @@
-name: 'The name of your action here'
-description: 'Provide a description here'
-author: 'Your name or organization here'
+name: 'paper2-getting-started-typescript-actions'
+description: 'getting-started-typescript-actions'
+author: 'paper2'
 
 # Add your action's branding here. This will appear on the GitHub Marketplace.
 branding:

これで準備は完了です。次にActionのコードを変更していきます。

Actionのコードを実装する

新しいブランチを作成する

リリースしたいバージョンのブランチを作成します。

$ git checkout -b releases/v0.0.1

バージョンをpackage.jsonに記載する*2

$ vi package.json

diffは以下のようになります。

diff --git a/package.json b/package.json
index 855e61c..c45f754 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
 {
   "name": "typescript-action",
   "description": "GitHub Actions TypeScript template",
-  "version": "0.0.0",
+  "version": "v0.0.1",
   "author": "",
   "private": true,
   "homepage": "https://github.com/actions/typescript-action",

/src にActionのコードを追加する

/src がActionの実装となるTypeScriptのコードです。ここで実装します。

今回は元々ある関数を以下のように少しだけ変更します。

diff --git a/src/wait.ts b/src/wait.ts
index 0ddf692..4185315 100644
--- a/src/wait.ts
+++ b/src/wait.ts
@@ -9,6 +9,6 @@ export async function wait(milliseconds: number): Promise<string> {
       throw new Error('milliseconds not a number')
     }
 
-    setTimeout(() => resolve('done!'), milliseconds)
+    setTimeout(() => resolve('done!!!'), milliseconds)
   })
 }

Actionのインプットなども変える場合はCIのテスト部分も変更が必要になるので注意してください。

__tests__/ にテストを追加する。

変更に応じてテストを実装してください。今回は既存のテストを通るレベルの変更になっています。

以下のコマンドでテストを実行できます。カバレッジレポートなども最初から含まれています。

$ npm test

> typescript-action@0.0.0 test
> npx jest

 PASS  __tests__/index.test.ts
  index
    ✓ calls run when imported (6 ms)

 PASS  __tests__/wait.test.ts
  wait.ts
    ✓ throws an invalid number (10 ms)
    ✓ waits with a valid number (504 ms)

 PASS  __tests__/main.test.ts
  action
    ✓ sets the time output (514 ms)
    ✓ sets a failed status (2 ms)

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------|---------|----------|---------|---------|-------------------
All files |     100 |      100 |     100 |     100 |                   
 index.ts |     100 |      100 |     100 |     100 |                   
 main.ts  |     100 |      100 |     100 |     100 |                   
 wait.ts  |     100 |      100 |     100 |     100 |                   
----------|---------|----------|---------|---------|-------------------
Test Suites: 3 passed, 3 total
Tests:       5 passed, 5 total
Snapshots:   0 total
Time:        3.033 s, estimated 4 s
Ran all test suites.

フォーマット、テスト、ビルド

最後に必要な処理を全部実行します。この処理内ではフォーマットやテスト、TypeScriptをJavaScriptに変換する処理なども行なっているのでコミットの前に実行が必要になります。

$ npm run all

git statusを確認すると、変更したファイルだけでなく dist 配下にコンパイルされたJavaScriptコードが含まれています。

$ git status
On branch releases/v0.0.1
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
    modified:   dist/index.js
    modified:   dist/index.js.map
    modified:   package.json
    modified:   src/wait.ts

no changes added to commit (use "git add" and/or "git commit -a")

このJavaScriptのコードも含めてコミットしてください。

commit and push

$ git add -A
$ git commit -m "test commit"
$ git push --set-upstream origin releases/v0.0.1

PRの作成とmainへのマージ

例えば今回のブログ用に作成したPRはこちらです。デフォルトでリントなどの色々なジョブが実行されているのがわかると思います。

色々なJobが実行されている

CIが全て通っているか確認し、mainにマージします。

Actionをマーケットプレイスに公開する

script/release ヘルパースクリプトを利用してtag付けをする

ヘルパースクリプトではpackage.jsonのバージョンを変更したか確認してくれたり、タグ付けをしてくれます。

$ git switch main
$ git pull
$ ./script/release
fatal: No names found, cannot describe anything.
No tags found (yet) - Continue to create and push your first tag
The latest release tag is: [unknown]
Enter a new release tag (vX.X.X format): v0.0.1
Tag: v0.0.1 is valid syntax
Make sure the version field in package.json is v0.0.1. Yes? [Y/n] Y
Tagged: v0.0.1

以下のようにタグ付けがされます。

commit 129df5cbf6eaf5b4a65b6c683d3b13d922016e81 (HEAD -> main, tag: v0.0.1, origin/main, origin/HEAD)
Merge: 75b6dd5 c49720e
Author: zyoshi (kamitsuk) <35333687+paper2@users.noreply.github.com>
Date:   Sun Sep 22 15:31:14 2024 +0900

    Merge pull request #7 from paper2/releases/v0.0.1
    
    release v0.0.1

リモートにpushします。

$ git push origin v0.0.1      
Enumerating objects: 1, done.
Counting objects: 100% (1/1), done.
Writing objects: 100% (1/1), 187 bytes | 187.00 KiB/s, done.
Total 1 (delta 0), reused 0 (delta 0), pack-reused 0
To github.com:paper2/getting-started-typescript-actions.git
 * [new tag]         v0.0.1 -> v0.0.1

マーケットプレイスに公開する

レポジトリの画面でActionを公開できますよと言われているので公開していきます。「Draft a release」を押下してください。

リポジトリトップ画面

以下のようにaction.ymlやREADME.mdのチェックが行われます。

リリースチェック

tagを選択し、リリースノートを作成します。

リリースノート

必要に応じてpre-releaseのチェックをして「Publish release」を押下します。

プレリリース設定

これでマーケットプレイスに公開されました!!とても簡単ですね。

公開されたアクション

GitHub Actionsで以下のように利用できるようになります。

- name: paper2-getting-started-typescript-actions
  uses: paper2/getting-started-typescript-actions@v0.0.1            

まとめ

actions/typescript-actionを利用してTypeScriptで作成したActionをマーケットプレイスに公開する方法を紹介しました。

*1:一方で実際の作成やトラシューでは基本的なGitHub Actionsの知識やTypeScriptの知識が求められます。

*2:こちらは運用に合わせたタイミングで変更しても良いと思います。例えばmainマージ後に変更でも問題ないはずです。