20
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

クラウドワークスAdvent Calendar 2020

Day 5

github-script は便利です

Last updated at Posted at 2020-12-04

前置き

こんにちは Bugfire です。

クラウドワークス Advent Calendar 2020 の5日目になりました。
また GitHub Actions の話題です。

github-script とは?

github-script とは 公式 GitHub Action です。
インラインの JavaScript から、認証済みの GitHub API を呼び出すことができます。

GitHub API は多種多様なことができますが、公式 Actions は全ての機能が定義されているわけではありません。ちょっとした機能を使うために 3rd party の Action を使うのも...という時にこの Action が役立ちます。

もちろん、この環境で書かれたコードで Lint や Test は難しいですし、複雑なことを行うには適していません、ちょっとした条件分岐と API を呼び出す程度にした方がよいでしょう。

注意

Note This action is still a bit of an experiment—the API may change in future versions. 🙂

とあるので、変更の可能性はあります。

使い方 (READMEより)

返値

レポジトリの README から引用します

- uses: actions/github-script@v3
  id: set-result
  with:
    script: return "Hello!"
    result-encoding: string
- name: Get result
  run: echo "${{steps.set-result.outputs.result}}"

簡単ですね。return で返したものを outputs.result で参照できます。
result-encoding の仕様については、 https://github.com/actions/github-script/blob/96374ece582f3d27d61b7def6d0fd209a7058dbc/src/main.ts#L35-L49 をみると、'string' か 'json' とありますね。

object を返す場合は json にしておくと stringify してくれますが、利用するときは、JSON.parse() (or jq コマンドなど)しないといけないので、そこまで便利ではないです。

コメントをつける

on:
  issues:
    types: [opened]

jobs:
  comment:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/github-script@v3
        with:
          github-token: ${{secrets.GITHUB_TOKEN}}
          script: |
            github.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: '👋 Thanks for reporting!'
            })

スクリーンショット 2020-11-28 17.50.39.png

コメントがつきました。

ラベルをつける

on:
  issues:
    types: [opened]

jobs:
  apply-label:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/github-script@v3
        with:
          github-token: ${{secrets.GITHUB_TOKEN}}
          script: |
            github.issues.addLabels({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              labels: ['Triage']
            })

スクリーンショット 2020-11-28 18.57.01.png

ラベルがつきました。

その他の README のサンプル

  • プルリクエストが作成された時に、そのユーザで最初の Issue に紐づくプルリクエストであれば Welcome コメントを出す。
  • プルリクエストの差分を取得する
  • 特定のラベルのついた Issue を検索する
  • script を別ファイルにする

などがあります。README.md はとても参考になります。

その他使い方

Deployment の作成と Status 更新

on:
  push:

jobs:
  test-for-script:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/github-script@v3
        id: create-deployment
        env:
          # オプショナル
          # DEPLOY_ENVIRONMENT: 'production', 'staging' 等。デフォルトは 'production'。
          # DEPLOY_AUTO_MERGE: 'true' の場合は default branch に自動マージされる。デフォルトは 'false'。
          # DEPLOY_DESCRIPTION: 任意のメッセージ。140文字以内。デフォルトはなし。
          DEPLOY_ENVIRONMENT: staging
        with:
          script: |
            const env = process.env;
            const logUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}/commit/${context.sha}/checks`
            // https://octokit.github.io/rest.js/v18
            // https://developer.github.com/v3/repos/deployments/#create-a-deployment
            // required_contexts がなくても良いと書いてあるが、ないと通らない
            const deployment = await github.repos.createDeployment({
              ref: context.ref,
              owner: context.repo.owner,
              repo: context.repo.repo,
              required_contexts: [],
              environment: env.DEPLOY_ENVIRONMENT || 'production',
              transient_environment: true,
              auto_merge: env.DEPLOY_AUTO_MERGE === 'true',
              description: env.DEPLOY_DESCRIPTION
            });
            // https://developer.github.com/v3/repos/deployments/#create-a-deployment-status
            await github.repos.createDeploymentStatus({
              owner: context.repo.owner,
              repo: context.repo.repo,
              deployment_id: deployment.data.id,
              state: 'in_progress',
              log_url: logUrl,
              mediaType: {
                // state を inactive, in_progress, queued にする場合は必要
                previews: ["flash-preview", "ant-man-preview"]
              }
            });
            return deployment.data.id.toString();
          result-encoding: string          
      - uses: actions/github-script@v3
        id: update-deployment
        env:
          # 必須
          # DEPLOY_STATUS: 'error', 'failure', 'inactive', 'in_progress', 'queued', 'pending', 'success'
          # DEPLOY_ID: デプロイメントID
          # オプショナル
          # DEPLOY_TARGET_URL: デプロイ先を指す任意 URL。Deployments ページ上で表示される。デフォルトはなし。
          # DEPLOY_DESCRIPTION: 任意のメッセージ。140文字以内。デフォルトはなし。
          DEPLOY_STATUS: 'success'
          DEPLOY_ID: '${{steps.create-deployment.outputs.result}}'
          DEPLOY_TARGET_URL: https://www.google.com/
          DEPLOY_DESCRIPTION: 'デプロイした'
        with:
          script: |
            const env = process.env;
            const logUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}/commit/${context.sha}/checks`
            // https://developer.github.com/v3/repos/deployments/#create-a-deployment-status
            await github.repos.createDeploymentStatus({
              owner: context.repo.owner,
              repo: context.repo.repo,
              deployment_id: Number(env.DEPLOY_ID),
              state: env.DEPLOY_STATUS,
              log_url: logUrl,
              environment_url: env.DEPLOY_TARGET_URL,
              description: env.DEPLOY_DESCRIPTION,
              mediaType: {
                // state を inactive, in_progress, queued にする場合は必要
                previews: ["flash-preview", "ant-man-preview"]
              }
            });

Deploymentの作成と、Status の作成を行なっています。
デプロイ完了時に 'success' へ変更、if failure() で 'failure' に変更すると良いでしょう。

step のif failure() は同じ job であれば定義された行より上のどこかで失敗すれば必ず呼ばれるので、最後のステップに例外ハンドラ的に書いておくと良いです。job をまたがる場合は面倒です。
(job で if always() or if failure() を指定しておき、他の job の status を取得することで DRY に書くことができるようです)

実行すると、トップに Environments が生成され、

スクリーンショット 2020-11-29 1.00.49.png

Deployments のページで以下の様に表示されます (View deployment のリンク先が、DEPLOY_TARGET_URL になります)

スクリーンショット 2020-11-29 1.01.00.png

Label に応じて自動で Issue を閉じる

on:
  issues:
    types: [labeled]

jobs:
  comment:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/github-script@v3
        with:
          github-token: ${{secrets.GITHUB_TOKEN}}
          script: |
            if (context.payload.label.name !== 'invalid') {
              return;
            }
            github.issues.createComment({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: context.issue.number,
              body: 'Please follow the issue templates.'
            })
            github.issues.update({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: context.issue.number,
              state: 'closed'
            });

特定のラベル(上では invalid)が付与された場合に、自動的にコメントを行い、Close します。

スクリーンショット 2020-11-29 1.33.56.png

まとめ

We're hiring!

いくつかAPIを呼び出したり、それに条件を少し加える程度なら github-script で API を呼び出すことは見通しもよく、便利ではないでしょうか。

20
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?