rcmdnk's blog
Last update

20200423_actionhero_200_200

GitHub Actionsで自作アクションを作る際に気づいた点など。

GitHub Actions

GitHub ActionsはGitHubで使えるCI/CDツールです。

アクションの使い方

自分のWorkflowの中で人が作ったものや自分が作ったアクションを使いたい場合には jobs.<jobid>.stepsの中で

jobs:
  myjob:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v2
      with:
        submodules: recursive

    ...

の様にusesに該当のレポジトリ名を記入することで使えます。 また、最後に@の後ろにリリース番号やコミット番号を指定することで バージョン指定することが可能です。

また、withは、そのアクションが用意しているパラメーターを設定する項目で、 ここではsubmodulesというパラメーターにrecursiveという値を設定しています。

アクションの作り方

アクションを作る際にはDockerilsを使ったものかJavaScriptを使ったものを作ることになります。

DockerはLinuxのみ、JavaScriptはLinux、macOS、Windowsでも使えます。

このどちらかを選んで作ることになります。

Dockerファイルを使った方法

Docker コンテナのアクションを作成する - GitHub ヘルプ

基本的にはDockerファイルを用意して、その中で実行するべきスクリプトを用意する、と言った感じ。

GitHubのレポジトリに

  • action.yml
  • Dockerfile
  • entrypoint.sh (Dockerfileの中で呼ぶもの)

を用意します。

action.ymlには最小限以下の様な物を書きます。

action.yml
1
2
3
4
5
6
7
8
9
name: 'my action'
description: 'my action unit'
author: 'rcmdnk'
branding:
  icon: 'meh'
  color: 'gray-dark'
runs:
  using: 'docker'
  image: 'Dockerfile'

namedescriptionは適当に好きなものを。

authorには自分の名前を。

brandingですが、これはアクアションを公開する時に表示されるアイコンを指定します。

Feather – Simply beautiful open source icons

にあるIconマークと、背景カラーをバッジの背景カラー。 カラーはwhite、yellow、blue、green、orange、red、purple、gray-darkのいずれか。

Dockerに関しては一番簡単にはrunsでDockerfileを指定するだけ。

簡単なコマンドを実行するだけならDockerfileの中で実行ファイルを呼ぶ様に

entrypoint.sh
1
2
3
4
5
FROM ubuntu:latest

COPY entrypoint.sh /entrypoint.sh

ENTRYPOINT ["/entrypoint.sh"]

としてentrypoint.shを呼ぶようにします。

JavaScriptを使った方法

JavaScript アクションを作成する - GitHub ヘルプ

こちらで用意する必要があるのは

  • action.yml
  • index.js (action.ymlで呼ぶもの)

を用意します。

action.yml
1
2
3
4
5
6
7
8
9
name: 'my action'
description: 'my action unit'
author: 'rcmdnk'
branding:
  icon: 'meh'
  color: 'gray-dark'
runs:
  using: 'node12'
  main: 'index.js'

runsの所でusingnode12を指定し使うJavaScriptファイルをmainで指定します。

あとはJavaScriptでの処理をindex.jsに書いておけばOK。

Composite run (シェルスクリプトなどを直接走らせる)を使う方法

追記: 2021/08/23

2020年中頃にComposite runという方法が加わりました。

Dockerを使う際はそのActionがDocker内で行われるため、閉じた作業をするには良いですが、 他のActionと組み合わせる際にはあまり使い勝手がよくありません。

一方で、JavaScriptを使う方法は、色々セットアップしたりしたいだけだったり、 他の言語の処理をしたい場合、結局JavaScriptの中からコマンドを呼ぶ様な形になり ただ面倒なだけです。(JavaScriptでやるのは設計上の都合…?)

シェルスクリプトとか、Pythonのスクリプトを直接流すことが面倒でしたが、 このComposite runによってそれらが簡単にできるようになりました。

用意するのは基本的には

  • action.yml

のみです。

シェルスクリプトやPythonスクリプトなどを走らせたい場合には レポジトリ内に置いておいてシェル的に呼び出すような感じで使います。

action.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
name: 'my action'
description: 'my action unit'
author: 'rcmdnk'
branding:
  icon: 'meh'
  color: 'gray-dark'
runs:
  using: 'composite
  steps:
    - run: echo Hello world
      shell: bash
    - run: ${{ github.action_path }}/myscript.sh
      shell: bash
    - run: ${{ github.action_path }}/myscript.py
      shell: python

な感じで、 まずusingcompositeを指定します。

そして、stepsのブロックを作り、runにコマンド、shellに走らせるのに使う コマンドを指定します。

使えるshell: Workflow syntax for GitHub Actions - GitHub Docs

2, 3番目のrunでは、自身のレポジトリへのPATHは${{ github.action_path }}で参照できるので、 レポジトリに置いたスクリプトを参照して呼ぶようにしています。

Creating a composite run steps action - GitHub Docs

Metadata syntax for GitHub Actions - GitHub Docs

追記ここまで

Inputsパラメーター

inputsは最初の例であったwithでユーザーが設定できる様にするためのaction.yml内の設定です。

GitHub Actionsのメタデータ構文 - GitHub ヘルプ

inputs:
  numOctocats:
    description: 'Number of Octocats'
    required: false
    default: '1'
  octocatEyeColor:
    description: 'Eye color of the Octocats'
    required: true

のような感じで指定すると、numOctocatsoctocatEyeColorという値を withで設定できる様になります。

これらの値は環境変数として使える様になり、 先頭にINPUT_を付けてすべて大文字、空白は_に変換した状態になります。 numOctocatsならシェルスクリプトとかで$INPUT_NUMOCTOCATSと呼べば値が読めます。

ここでrequireddefaultという設定があるのですが、 これら設定がいまいちちゃんと動いてないように見えます。

追記: 2024/02/26

2024年現在も実際まだ機能してないようです。

Validate required inputs are set before invoking an action · Issue #1070 · actions/runner

追記ここまで

Documentの記述と、自分的な感覚では

  • requiredtrue: ユーザーが必ず指定しなくてはいけない
  • defaultが設定されている: requiredfalseでユーザーが指定しないときにはその値が使われる

と言ったものだと思ってました。

ただ、実際動かしてみると、

  • requiredtruedefaultの値が設定してあるとユーザーが指定しない場合にdefaultの値が使われる
    • defaultが無くてもから変数として生成される(エラーにはならない)
  • requiredfalseの場合、ユーザーが指定しないとdefaultの値があってもそれは無視される
    • 厳密にはそのinputパラメーターが環境変数として生成されない

という感じでした。なのでdefaultを指定したい場合には必ずrequired: trueにする必要があります。

もしかしたら何か勘違いしてるかもしれないのですが、結構色々確かめた上で今の所こんな感じでした。

なので今の所READMEとかに書く際にはrequiredの値は関係なしに、必ずユーザー側で指定してもらいたいものかどうか を書く必要があります。

逆にREADMEがちゃんと無いと、action.ymlを見ただけだとその変数を自分で設定する必要があるかどうかがちょっと分からない状態です。

Secrets

各レポジトリでSettingsSecretsというセクションに行くと 秘密のワードを暗号化して保存しておくことが出来る様になっています。

これを

- name: ssh test
  env:
    MY_SSH_KEY: ${{secrets.SSH_KEY}}
  run: ssh -i $MY_SSH_KEY example.sh echo test

のような形でaction.ymlの中で使うことが出来ます。

action.ymlの中では${{ }}で囲った形でsecrets.というprefixを使って参照することが出来ます。

上の例ではそれをbashのコマンドで呼びたいので一度環境変数に入れて、環境変数の形で runの中で使うようにしています。

アクションのwithに直接渡す事もできます。

暗号化されたシークレットの作成と保存 - GitHub ヘルプ

アクションを公開する方法

パブリックレポジトリでaction.yml(もしくはaction.yaml)がルートディレクトリにある場合、 そのレポジトリでリリースを作ろうとすると自動的に GitHub Marketplace に登録するかどうかの項目が出る様になっています。

GitHub Marketplaceでのアクションの公開 - GitHub ヘルプ

action.ymlの中で指定するnameに関して、他のアクションとかぶってはいけなかったり ユーザー名やOrganization名、またはGitHubの機能名など予約されているものと一致してしまうと 公開できないので、あまり簡単なユニークでなさそうな名前だと出来ないのでちょっと注意が必要です。

あと2要素認証を使っていないと出来ないようになっているので、 してない人はしましょう。

リリースを作るだけでMarketplaceに公開されるので 公開する敷居はかなり低い感じがしました。

一つ公開してみた際、上にあるようなMarketplaceへの公開の機能が リリースを作ろうとしても出てこなくて困ったことがありました。

これはaction.ymlではなく、actions.ymlという名前でアクションファイルを置いていたからでした。

ただ、これでも他のレポジトリから

- uses: rcmdnk/octopress-action

みたいな感じでレポジトリを指定すると使えてました。 Marketplaceに公開するのでなければアクションを定義するYAMLファイルの名前は何でも良い?様です。

アクションのバージョンの付け方

バージョンの付け方は Semantic Versioning が推奨されています。

アクションについて - GitHub ヘルプ

vX.Y.Zで

  • X: メジャーバージョン。後方互換性が無いアップデートを含む場合に上げる。上げた際はY、Zは0に戻す。Xが0の時は開発段階。1以降で正式リリース。
  • Y: マイナーバージョン。後方互換性のある機能追加等を行った場合に上げる。上げた場合はZは0に戻す。
  • Z: パッチバージョン。後方互換製のあるバグフィックスを行った場合に上げる。

といった定義。

さらに、破壊的変更がない場合(メジャーバージョンが変わらない場合)メジャーバージョンを指定するだけで自動で追いかけられるよう、v1などのタグを作り、 マイナー/パッチバージョンを上げた際にv1などのタグをそのGit refに移動させることが推奨されています。

ただ、アクション側でその様に用意してなければ使えないわけなので、 各アクションのREADMEなどを読んで使えるものを使う必要があります。

Sponsored Links
Sponsored Links

« Windows 10でスタートメニューが開かなくなったときの対処法 Gmailで外部SMTPサーバーが'TLS Negotiation failed, the certificate doesn't match the host. 'を出したときの対処法 »

}