ticktakclockの日記

技術ポエムを綴ったりします。GitHub idも同じです (@ticktakclock)

GitHub Actionsのワークフロー個人的逆引き

こんにちはtkyです。

GitHub Actionsを使い始めて1ヶ月位が経過したのでやったことなどを忘れないようにまとめていこうと思います。

思いつき次第更新してこうと思いますが、大体ドキュメントに書いてあるので基本ドキュメント参考にするのが良いのかと思われます。

とりあえずパッと試してみたい人へ

GitHubのactionタブからポチポチするだけでとりあえずなにかは作れるので雰囲気を理解したい場合一度ブラウザ上で動かしてみると良いです。

f:id:ticktakclock:20191207134645p:plain
ブラウザからActionsを試す

逆引き辞典

できる限りコピペで使えるようにしています。

作業ディレクトを指定したい

cd foo && ( sample.sh args1) みたいなことやりたくないですよね。

.
├── .github
│   └── workflows
│       └── pr-check.yml
└── foo
    └── sample.sh
    steps:
      - name: exec sample.sh
        working-directory: ./foo
        run: sample.sh args1

ワークフローを実行するコンテナを指定したい

通常ubuntu-latest上で動きますが、コンテナを指定したいときがある・・・?はず・・・?

jobs:
  samplejob:
    name: sample job
    runs-on: ubuntu-latest
    container:
      image: node:10.16.0-alpine # Nodeコンテナ上でsteps実行する
    steps:
      - name: Checkout
        uses: actions/checkout@v1
      - run: npm install

PRのIssueにコメントする

github apiを使います。tokenは secrets.GITHUB_TOKEN に格納されているので便利です。

if: failure() で直前のstepが失敗していたとき(=exit status 0以外)に実行という条件分岐が可能になります。 APIたたいたあとに&& exit 1 で失敗に落として次のsuccess()に進まないようにしますが、もっといいやり方があれば教えて下さい。。。

テストにコケたときにIssueにコメントする

    steps:
      - name: Checkout
        uses: actions/checkout@v1
      - name: uint test
         run: .exec_test.sh  # 各プロジェクトのテストを実行してください
      - name: post result if test failure
        if: failure()
        run: |
          curl \
            -X POST \
            ${{ github.event.pull_request.comments_url }} \
            -H 'authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' \
            -H 'content-type: application/json' \
            -d "{ \"body\": \"👮<200d>♂️UnitTestでエラーが発生しています🚧内容を確認してください👮<200d>♂️\" }" \
          && exit 1
      - name: post result if test success
        if: success()
        run: |
          curl \
            -X POST \
            ${{ github.event.pull_request.comments_url }} \
            -H 'authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' \
            -H 'content-type: application/json' \
            -d "{ \"body\": \"おめでとうございます🎉UnitTestは無事通過しました🥳\" }" \

こんな感じで出てきます

f:id:ticktakclock:20191207162046p:plain
テスト通過時

どんな環境変数が使えるのか

ワークフロー上の${{ secrets.github_token }} (小文字でもいけます)などどんなものが使えるのか

help.github.com

ざっくり3つくらいリストアップ。

変数 説明
${{ secrets.github_token }} トーク
${{ secrets.github_sha }} コミットハッシュ
${{ secrets. github_repository }} オーナーとリポジトリ(ower/repo)

${{ github.event.payload }} にも色々と情報が入っています。GitHubAPIのEvent typeと同じものが入るようです。

PRの時に入るイベントは以下を見ると良いです。

PRにコメントするときは ${{ github.event.pull_request.comments_url }} にPOSTするとコメントできます。

developer.github.com

カスタムアクションが必要になるケース

自分のリポジトリだけで使うプライベートなアクションの作成が必要になるケースは、自分で使ってみて以下のような感じでした。

  • 特殊なDocker環境を使っている
    • phppeclで拡張を入れていてワークフロー上の環境では対応しきれなかった
  • shellをぶん回しながら色々と細かいことをやりたい
    • yamlのRUNでかけなくもないけどごちゃるので・・・

DBも絡めたテストがしたい

大体のケースで当てはまるであろうケース。以下のように書くと localhost:portでアクセスできるようになる

  samplejob:
    name: sample job
    runs-on: ubuntu-latest
    services:
      mysql:
        image: mysql:5.7 # dockerhubのイメージを指定する
        env:
          MYSQL_ROOT_PASSWORD: root
          MYSQL_DATABASE: testdb
          MYSQL_USER: docker
          MYSQL_PASSWORD: docker
          TZ: Asia/Tokyo
    steps:
      - name: Checkout
        uses: actions/checkout@v1
      # you can access to localhost:3306

以下のように実行コンテナを指定するとdocker-composeと同じような状況下で動作させることができます。

この時コンテナ間アクセスでは mysql:3066 のようにサービス名でアクセスできるようになります。

  samplejob:
    name: sample job
    runs-on: ubuntu-latest
    container:
      image: php:7.2-fpm # 実行コンテナを指定する
    services:
      mysql:
        image: mysql:5.7 # dockerhubのイメージを指定する
        env:
          MYSQL_ROOT_PASSWORD: root
          MYSQL_DATABASE: testdb
          MYSQL_USER: docker
          MYSQL_PASSWORD: docker
    steps:
      - name: Checkout
        uses: actions/checkout@v1
      # you can access to mysql:3306

その他わかったこと

躓いたところなど記載していきます。

github actionはpublicのみ対応だった

どういうことかというと カスタムアクションで ticktakclock/actions-test@v1 のようなリポジトリをPrivateで作ると、他のリポジトリでこのアクションにアクセスできません(当たり前ですよね)

会社でGithubを使っていて、会社用のアクションを共通で利用できるようにリポジトリを作ってもPrivateなのでアクセスできない事象になるので困る・・・

同一Organization内のリポジトリはアクセスできるようにしてほしい・・・と思いながらも今はリポジトリごとに個別でコピペして入れてます。

ワークフローはgithubにデプロイしてみるしか確認できない

どうしようもない気がしますがなにか手がないか・・・ローカルで確認した後にgit push したいのですが。。。

僕はテスト用にリポジトリ作ってそっちにPushしまくって確認した後 コミットをきれいにしてから開発リポジトリに導入しました。

※Slack等にイベント通知しているので最初は開発リポジトリにpushしまくってタイムラインが一瞬荒れました・・・w