JavaScriptを書いてGitHub Actionsのハッカソンに参加しよう

# はじめに
[GitHub Actions](https://github.co.jp/features/actions)とは[CircleCi](https://circleci.com/ja/)や[Jenkins](https://jenkins.io/)のような**継続的インテグレーション**をGitHub内で行うことができるサービスです。これを使うと外部サービスとの連携を行わずに自動ビルド・デプロイといった設定を組むことができます。
そして今回の内容ですが、実は**3/5~3/31**にかけてこのGitHub Actionsのハッカソンが開催されています。参加方法は、じぶんのGitHubレポジトリに`action.yml`を用意して何かしら動作するGitHub Actionsを用意して、[ここのエントリーページ](https://githubhackathon.com/)にアクセスして提出します。

# GitHub Actionsってどうやって作るの？
おそらく多くの方がこのGitHub Actionsを作成する方法にハードルを感じるような気がします。実際私も同じく難しそうだなと思ってました。しかし実際やってみると２時間くらいで何かしら動作するアクションを作成することができました。
まず、GitHub Actionsを作るために`Dockerfile`を作る必要があるのかなと思ってましたが、実際はなくても良くて**JavaScriptを書くだけ**で作成できるということを今回初めて知りました。実は公式のヘルプページで[JavaScriptでアクションを作成する方法](https://help.github.com/ja/actions/building-actions/creating-a-javascript-action)が書いてあります。

# とりあえず作ってみた
今回初めて自分のアクションを作ってみました。[ここで公開](https://github.com/marketplace/actions/line-push-message)しています。使い方は以下のような感じです。

1. [デベロッパーサイト](https://developers.line.biz)で適当なLINE botを作成してUserIdとChannel access tokenを取得する
2. ワークフローを書く。`user-id`と`channel-access-token`という必須パラメーターがあるので`1.`で用意したものを入れる
3. LINEにプッシュ通知が行く

以下は、レポジトリにpushしたときにLINE通知を送るワークフローです。

```yml
on: [push]

jobs:
  line_push_message_job:
    runs-on: ubuntu-latest
    name: LINE push message
    steps:
    - name: Push LINE message
      uses: ufoo68/line-push-message@v1.4
      with:
        user-id: ${{ secrets.USER_ID }}
        message: 'test'
        channel-access-token: ${{ secrets.CHANNEL_ACCESS_TOKEN }}
```

`uses: ufoo68/line-push-message@v1.4`でアクションを呼んで、`with:`でパラメーターを入力します。`message`が実際に送るメッセージになり、特に用意していない場合は**You are commited on repository**というメッセージを送ります。
とりあえずこれをどうやって作ったのかを次から説明していきます。

## action.ymlを書く
このファイルだけはどうしても必要なので用意します。

```yml
name: 'LINE push message'
description: 'LINE push message action using GitHub actions'
branding:
  icon: message-square  
  color: green
inputs:
  user-id:
    description: 'User ID to push message'
    required: true
  message:
    description: "Text message to push message"
    default: "You are commited on repository"
  channel-access-token:
    description: "Channel access token"
    required: true
runs:
  using: 'node12'
  main: 'dist/index.js'
```

`inputs:`で`with`を使って与えてほしいパラメーターを定義します。`branding:`はアイコンの形とか色を定義します。マーケットプレイスへの公開をするためには必須となるので用意しましょう。後は`runs:`で実行環境とかファイルをしていします。

## JavaScriptを書こう
ここでようやく**JavaScriptの出番**になります。本当はTypeScriptでやりたかったですがコードの記述量もそんなになかったのでやめときました。書いたコードはこれだけです。

```javascript
const core = require('@actions/core')
const line = require('@line/bot-sdk')
const { buildReplyText } = require('line-message-builder')

const client = new line.Client({ channelAccessToken: core.getInput('channel-access-token') })

try {
  const userId = core.getInput('user-id')
  const message = core.getInput('message')
  client.pushMessage(userId, buildReplyText(message))
} catch (error) {
  core.setFailed(error.message)
}
```

なんとなくコードを見てわかると思いますが、`@actions/core`というパッケージを使って先程の`inputs:`で定義したパラメーターを呼び出します。後はそれを使って自由きままにコードを書くだけです。

## distにパッケージをまとめる
今回、いくつかのパッケージを使ったので本当は`node_modules`もコミットする必要があるのですが、個人的にもあまりやりたくはないので公式のヘルプページを参考に[zeit/ncc](https://github.com/zeit/ncc)を使って直接`index.js`ファイルを実行できるようにコンパイルしました。
とりあえず最初はインストールから

```bash
npm i -g zeit/ncc
```

あとはコンパイルを実行します。

```bash
ncc build index.js
```

これで`dist/`というディレクトリが作成されてコンパイルされた`index.js`が置かれているはずです。そして最初に書いた`action.yml`も`main: 'dist/index.js'`として`dist`直下の`js`ファイルを読むように指定していたはずです。

## GitHubへプッシュ！
後は`tag`をつけてレポジトリにプッシュします。コマンドの例はこんな感じです。

```bash
git add action.yml dist/index.js node_modules/*
git commit -m "Implemented action"
git tag -a -m "My first action release" v1
git push --follow-tags
```

とりあえずこれで提出できる形のものは作成できました。

# さいごに
思ったよりGitHub Actionsを作成するのは簡単でした。みなさんも是非これを機にアクションを作ってみてはどうでしょうか。