GitHub Actions 以前調べたのですが、いろいろあって個人プロジェクトでサクッとビルドするのみに使っていました。 今回改めて調べを進めたのでメモ。
幾つかのリポジトリを GitHub Actions に移行したけど、記事にしようとまとめてたらやった内容以上に調べることになってめちゃめちゃ時間かかった。
目次
TL;DR
- とりあえず公式ドキュメント読めばok
- 公式ドキュメントにないのはだいたいフォーラムみればok
- 基本は Azure pipeline だけど、結構使いやすい感じになってる
- Azure Pipelines と違って、step の name を省略するとコマンドがそのまま表示されるので name は基本省略で行ける。 (これ重要)
- public repo なら Github Actions もいい感じ。Windows や macOS 依存はこっちに移植する
- private repo は、GitHub を新料金プランにしているか次第。CircleCI の Performance Plan のユーザー課金が納得いかないのでこっちに移行していきたい
- クラウドホストランナーが基本でよさそうだけど、Kubernetes 上でのCDを考えると セルフホストわんちゃんある
- AppVeyor でやってたことはほぼ移行できる
- CircleCI もだいたい行ける。Orb だけ代替あるかが問題になるぽ
トレンド
GitHub Actions の今のスタイルがブログでアナウンスされた2019/Aug/8 ぐらいからトレンド上がってるんですね。
GitHub Actions の基本
基本的な情報を裏取りする。
使用条件
- Org は新GitHub Pricing に移行していること (旧プランの場合 Actions 自体使えない)
旧プランで使えないのは、最近の GitHub の新サービスあるあるなのですが、なるほど困るケース結構多い。
旧プランと新プランは、リポジトリ数課金 or 人数課金の違い。 小規模な会社で30リポジトリ100ユーザーとかだと、新旧で桁が違うレベルで料金が変わるため移行に踏み切れないのはままある。
- 旧プランは、人数無制限、リポジトリ数で段階的なプラン選択
- 新プランは、人数課金、リポジトリ数制約なし
旧プランのほうがお得なケースは多数あってなかなか新プランに移行が難しいケースも見かけるので実は難しいやつ。
使用制限
並列数やAPI、実行時間で制限がある。
- 1リポジトリあたりの同時並列は20
- 1時間当たり リポジトリの全アクションで1000 APIリクエスト
- ワークフローは実行時間6時間が上限 (指定しないと6時間たつまでタイムアウトしないので長すぎ
- 無料、有料で同時実行上限がある
GitHub plan | Total concurrent jobs | Maximum concurrent macOS jobs |
---|---|---|
Free | 20 | 5 |
Pro | 40 | 5 |
Team | 60 | 5 |
Enterprise | 180 | 15 |
マイニングがダメとかその辺は当然あるので見ておきましょう。 Serverless Computing がダメなのもそれはそうなんだけど、いい感じにやってみた的にやりそうな人も出てきそうなので規約でしばるのでいいですね。
料金
OSS は無料で並列度高いので気軽に利用できていい感じ。CircleCI より緩くて Azure Pipeline や Travis 並みに楽。
会社など Private Repo だと、Team でも 3000min/month (旧:10000min/month) しかつかないので、十分ではなく追加購入必要になる感じ。
従量課金の体系はシンプルで、GitHub ユーザー課金ある前提と合わせて追加なので、もともと GitHub 使ってたこと考えると CircleCI の Performance Plan より納得度は圧倒的にある。だからこそ新料金プランに限定するんでしょうが。
- パブリックリポジトリ : 無料
- プライベートリポジトリ : 含まれる利用時間 + 追加購入
含まれる利用時間
利用時間は毎月リセットされるけど、ストレージはリセットされない。
2020/4/13 までは以下でしたが、2020/4/14~ 変更に
~2020/4/13プラン | 1か月あたり利用時間 | ストレージ |
---|---|---|
Free | 2,000分 | 500 MB |
Pro | 3,000分 | 1 GB |
Team | 10,000分 | 2 GB |
Enterprise | 50,000分 | 50 GB |
2020/4/13~プラン | 1か月あたり利用時間 | ストレージ |
---|---|---|
Free | 2,000分 | 500 MB |
Team | 3,000分 | 2 GB |
Enterprise | 50,000分 | 50 GB |
GitHub One | 50,000分 | 50 GB |
利用時間的には、GitHub Team が 旧Pro 相当になった感じ。
ストレージ価格がおもむろに出てきたけど、public は無料。 private の場合に、アカウントの持つGitHub packages とGitHub Actions アーティファクトの利用合計らしい。 制限を超えてアカウントが利用していて、$0 を超えるLimit spendingを設定していると料金がかかるので注意がいりそう。 そんなに大きなサイズのArtifact を設定するなという話なのですが、要注意。
アカウント > Settings > Billing > Cost management > Limit spending で設定できる。デフォ $0
ビリングの storage に関してを見ておくほうがよさそう。 ちょっと細かいので随時確認しよ。
OS別時間消費
Linux を 1として、Windows や macOS は利用時間の倍率がついているという考え。
Operating system | Minute multiplier |
---|---|
Linux | 1 |
macOS | 10 |
Windows | 2 |
追加購入
倍率に応じてなので、結果としてOS別に価格差が生じる。
Windows たっか。(あるある macOS やばい、これは追加になるとセルフホストまったなしになりそう。
ホストランナー | スペック | 料金 |
---|---|---|
Linux | 2 cores, 7GB | $0.008 1分あたり |
Windows | 2 cores, 7GB | $0.016 1分あたり |
macOS | 2 cores, 7GB | $0.08 1分あたり |
セルフホスト | - | Free |
ホストランナーの指定
GitHub Actions は Azure Pipeline 同様にホストランナー1をどこで実行するか選択できる。
マネージド、セルフホストの選択
ホストランナーはマネージド、セルフホストが選択できる。
- GitHub ホストランナー :マシンメンテナンス、アップグレードがマネージドに提供される
- セルフホストランナー : 物理、仮想、コンテナ、オンプレミス、クラウド に自分でインストールする
通常はクラウドホストランナー (GitHub が提供するホスト) を選ぶし、それが最も手早く楽。
セルフホストランナーは既にビルドを実行する環境がある、けどビルドの管理をしたくない、何かしらマシンに事前にインストールが必要など融通をきかせたいときに便利。ようは Azure Pipeline の Self Hosted Agent と一緒。
例えば、自分たちのKubernetesクラスターにセルフホストランナーを入れてビルドをすることで、クラスターの認証への考慮を減らしてクラスターへのデプロイすることもできる。
個人のプロジェクトで考えるので、ここでは GitHub ホストランナー を前提としてみていく。
ハードウェアリソース
GitHub ホストランナーは、 Azure VM (Standard DS_v2) 上で動作するので、スペックはVMと同じ、素直。
- 2コアCPU
- 7 GBのRAMメモリー
- 14 GBのSSDディスク容量
インストールされるツール
OS 毎に一覧になってるので入ってないツールはインストールして対応で。
IP
GitHub の IP とは違うのが注意で、以下のURL のIPレンジではない。
全て Azure VM でのホスト、かつ現状は us-east-2 region なのでIPもそこ縛り。2
IPレンジは毎週更新してJSONで公開されているが、このリンクはまさかの Download Center で面倒な状況。
サポート回答もこのURLで、常に最新のjsonに直接アクセスできるリンクは用意しない気配。
直URL も日付入りで、決まったURLへ定期取得するのは想定されてなさそう。
100日さかのぼってみたが、今のところ更新ない or URL生成ルール違うのか404。(ルールあるのかなぁ)
OSの選択
GitHub ホストランナーの実行可能な環境は3種類あり、Azure Pipeline と同じ。 ほとんどのケースではLinux 選んでおけばいいけど、.NET Framework のような Windows 固定、Xcode のような macOS 固定もあるので用途に応じて。
- Linux
- Windows
- macOS
Azure Pipeline 同様にマトリックスビルドには対応しているので、OSS で各種OSむけのビルドは CircleCI より書きやすく、Travis CI の代替になりえる筋はある。
実行権限
CIではツールインストールなど権限を必要とすることが多い。 Linux/Windows いずれにおいても管理者権限があるので権限で悩むことはないかな。
- Linux, macOS: パスワードレス sudo 状態
- Windows: UAC無効管理者状態
ファイルパス
実パスを気にせず、GitHub が提供している環境変数でアクセスできる。
$HOME
: ユーザーパス。ログイン認証情報を含めてokらしい$GITHUB_WORKSPACE
: アクションとシェルコマンドの実行パス、変更可能$GITHUB_EVENT_PATH
: webhook イベントのPOSTペイロードへアクセスできる
ホスト仮想マシン
ファイルパスは静的ではないため、GitHub が提供している環境変数を使う必要がある。
- home
- workspace
- workflow/event.json
コンテナ
静的にパスを利用するため、USER
を指定すると $GITHUB_WORKSPACE
にアクセスできなくなる。
/github
Path Prefix を予約しているので自分でボリュームマウントするときは気を付ける。
- /github/home
- /github/workspace
- /github/workflow/event.json
環境変数
CircleCI のように spin up した環境の変数は出してくれない。Azure Pipeline と一緒で不親切、正直なんでやねんっていつも思ってる。
自分で拾う必要があるので、適当にデフォルトの環境変数は把握しておく。
GitHub が使う環境変数は、
GITHUB_
prefixがついており、GITHUB_
prefixを使用して環境変数またはシークレットは設定できない。(エラーになる)
シークレット
Settings > Secrets からシークレットを設定できる。
Azure Pipeline 同様に、ログからは自動的にマスクされる。 制約として、ワークフローで最大100シークレット、容量は64K 。
構造化データを値にするのは避けるべきというのは、あるある注意。
GitHubがログのシークレットを確実に削除するよう、構造化データをシークレットの値として使用することは避けてください。たとえば、JSONやエンコードされたGit blobを含むシークレットは作成しないでください。
GITHUB_TOKEN
GitHub Actions で何気に一番うれしいやつ。GitHub への操作多いので、Token 自動的に生成してくれるの最高。
前提として、write アクセスがあるユーザーになってるので注意。
リポジトリに対してwriteアクセスがあるユーザなら、誰でもシークレットの作成、読み取りおよび使用ができます。
GitHub Apps をインストールするアクセストークンとして、GITHUB_TOKEN
が自動生成される。
ジョブごとに60分後に期限切れになる一方で、ワークフローはデフォルト6hまでタイムアウトにならないので注意がいりそう (このデフォルトが長い)
権限は一通り書き込み権限があり、リリースにパッケージ投げたりコメント書いたりは十分。 逆に言うと結構強いので注意がいりそう。(もちろんOrg / Team はない)
Fork リポジトリからは read があるけど write がない。PRでトリガーされるワークフローで書き込み操作は軽くはまることはあり得る。
Permission | Access type | Access by forked repos |
---|---|---|
checks | read/write | read |
contents | read/write | read |
deployments | read/write | read |
issues | read/write | read |
metadata | read | read |
packages | read/write | read |
pull requests | read/write | read |
repository projects | read/write | read |
statuses | read/write | read |
コンテキスト
コンテキストはかなり便利。
github コンテキストは REST API でとれるレスポンス/webhook レスポンスに近く、そのコミットの情報が結構とれる。
コミットメッセージまででるので、skip ci
に似た処理を自作するときに便利です。
環境変数 GITHUB_
でほとんどとれるとか書いてるけど、取れるのはよくCIにある情報程度で、少し深くなるとコンテキスト触るしかない。
env や secrets もコンテキストの一種なので、めちゃめちゃ使う。
コンテキストは、steps じゃなくても参照できるのが重要で、jobs.if でも利用できるのでコンテキストが一致するかで job自体を実行するかとかも制御できる。
Artifact
なるほど、アーティファクトで job 間のデータ永続は Azure Pipeline まんま。
GitHub Actions のアーティファクトとは、ワークフロー実行中に生成されるファイル、またはファイルのコレクション。
ワークフロー内の各ジョブが異なるインスタンスで実行されるため、ワークフロー内でジョブ間でデータを受け渡すのには必須。 ビルドパッケージを置いたり、ログを置いたり何かと使うやつ。
アーティファクトはアップロードされると zip になるけど、ダウンロードは生データが取れるので取り回しは楽。
- ジョブが終了する前にデータをアップロードして、ワークフロー実行の内部にファイルを保存できる。 アーカイブをアップロードするときは、名前を付ける
- ファイルをアップロードすると、同じワークフロー実行内の別のジョブでダウンロードできる。 アーカイブをダウンロードするとき、アーカイブは名前で参照できます。 アップロードされているアーティファクトをダウンロードできるのは、同じワークフロー実行中だけ
ワークフロー終了後にジョブごとに Artifact をWebから取得できるので便利。
トリガーイベント
1つ以上のイベントをトリガーに設定できる。 pushや Issue、PR、webhookなどの各種イベント以外にも定期実行も可能。 ここが CircleCI では厳しかったので GitHub Actions でうれしいところ。
GITHUB_SHA
や GITHUB_REF
環境変数に現在のイベントに応じた状態がでるのでなるほど。(イベントごとに変わる)
wiki ページの作成、更新は gollum
イベントらしい。
ただ、ワークフローから別のワークフローはトリガーできないので、コメントなり適当なイベントを仲介する必要がある。
実行しているワークフローのアクションからは、新しいワークフローの実行をトリガーできない。
push イベントでファイルの変更を完全に終えず、REST API を使って取得が必要なのもなるほど。
GitHub Actionsが利用できるwebhookのペイロードには、commitオブジェクト中のadded、removed、modified属性は含まれない。
Fork されたリポジトリではデフォルトでは動かない。 もし実行するようにしても、Fork されたリポジトリの GitHub Actions は ベースリポジトリではトリガーされず、Fork先のリポジトリで許可が必要なのは普通のCIでよい。
Cache
なるほど、CircleCI とよく似てるけど、微妙に違う。
マッチングルールは、key で完全一致を見て、失敗したら restore-keys を上から順に前方一致で検索なのでよくあるとおり「長いキーから順に書き並べる」のが王道。さらに restore-keys で複数一致したら最近のキャッシュが利用されるので素直な印象。
- key の完全一致
- restore-keys を上から評価
- より最新のもの
Cache と Restore がセットになってるのはうれしいですね、actions/cache
しておくと、そのパスに変更合った時にJobの終了時に自動的に post action としてキャッシュされるのは普通に便利。
この時キャッシュキーがすでにあればスキップされるので、意図通り。
OS別なら、${{ runner.os }}
をキーに入れるのもあるある。
キャッシュ上書きがなく、7日でキャッシュ消えるものの任意のキャッシュクリアがないので、環境変数などで cache-version
を定義してキャッシュキーに含めるのも王道。
pushとpull_request イベントだけ使えること、7日間以上アクセスされていないキャッシュエントリは削除されることに注意。 また、リポジトリのキャッシュサイズ制限が2GB と小さいのもはまる。
- 400MBを超えないキャッシュ内の個々のファイル。 この制限を超えた場合、400 - Bad Requestが返さる
- リポジトリ内のすべてのキャッシュの合計サイズが2GBを超えない
相変わらず Windows \
と macOS/Linux /
でパス文字 の解釈が違って key の指定がコケるのはつらい。
Actions
CircleCI Orbs じゃないけど、似たような処理の塊は Actions と呼ばれていて、Marketplace で公開されている。
Actionsでやっていることを知りたいときは、追っていくと GitHub リポジトリにたどりつくので、やってることも読めるしいい感じになってる。
Actions について概要はドキュメントがあるのでみればok
Actions を使うときは、GitHub Web 上で YAML を編集する時なら右にポップアップが出る。
シンタックスエラーを検出したり、インテリセンスとかも利くので、こっち使うのが楽。
通知
Web と Email が設定できる。
なるほどビルドがコケると通知される。
YAML
実際書くときは、YAML書いてみて、わからないものを調べるという流れで慣れていっている。 ではYAMLで実際にどう書くのかざくっと使うものを見てみる。
Azure Pipeline 風味が残ってるような感じで、もうちょっと砕けててほど良さもある。
Getting started
はじめての YAML テンプレートは、Actions 選択したときに選択できるテンプレートを使うのが楽。
https://help.github.com/en/actions/automating-your-workflow-with-github-actions/starting-with-preconfigured-workflow-templateshelp.github.com
YAMLシンタックス
どういう要素があるのかは、まずはシンタックスを把握すればok。
最低限の定義はこんな感じ。何の意味もないやつ。
on: push jobs: build: runs-on: ubuntu-latest steps: - run: echo Hello
次の要素が必須なのがわかる。
- name : Workflowの名前でリポジトリのActions画面で表示される名前。省略するとパスになるので付けたほうがいい
- on: 必須。実行するイベントやブランチなどの指定をする
- jobs: 必須。とりあえず
jobs:
でok - jobs.
.runs-on: 動作させるホストランナーの指定。GitHub hosted か Self-hosted かはここで決まる - jobs.
.steps: 必須。とりあえず steps:
でok。jobs を書くときは、最低1つの steps が必要 - jobs.
.steps.step : steps の中は最低1つのstep が必要。例は run step を使っている
on
実行するトリガーの定義をここでする。 GitHub Actions が他のCIと決定的に違うのが、ここでGitHub イベントと楽にバインドできることだと思う。
# push のみ on: push # push と pull request なら on: [push, pull_request]
ブランチも含めた制御ができるのはいい感じ。
on: # Trigger the workflow on push or pull request, # but only for the master branch push: branches: - master pull_request: branches: - master # Also trigger on page_build, as well as release created events page_build: release: types: # This configuration does not affect the page_build event above - created
定期実行は、schedule
イベントで実行できる。
on: schedule: # * is a special character in YAML so you have to quote this string - cron: '*/15 * * * *'
env
グローバルに、全Job、全step から参照する環境変数はここで指定する。
特定のジョブでなら jobs.<job_id>.env
でいいし、特定のStep でなら jobs.<job_id>.steps.env
があるので、あまり使いたくない。
jobs.<job_id>.needs
依存する job を指定できる。大事。 ここで指定しないと並列に回るので、直列で回すときは CircleCI 同様依存関係を作る必要がある。
jobs: prepare: runs-on: ubuntu-latest steps: - run: echo prepare build: runs-on: ubuntu-latest needs: prepare steps: - run: echo build
jobs.<job_id>.runs-on
実行するホストのOSをあらかじめ定義された値から選んで使う。
- Windows Server 2019: windows-latest または windows-2019
- Ubuntu 18.04: ubuntu-latestまたはubuntu-18.04
- Ubuntu 16.04: ubuntu-16.04
- macOS Catalina 10.15: macos-latest, macOS-10.15
jobs: build: runs-on: ubuntu-latest
jobs.<job_id>.container
ジョブをコンテナで実行したいならここで指定する。
jobs: my_job: runs-on: ubuntu-latest container: node:10.16-jessie
何気にイメージ指定するだけじゃなくて、細かくDockerの実行時パラメーターも調整できる。
jobs: my_job: runs-on: ubuntu-latest container: image: node:10.16-jessie env: NODE_ENV: development ports: - 80 volumes: - my_docker_volume:/volume_mount options: --cpus 1
jobs.<job_id>.services
追加のコンテナを動かすときは services を用いる。 例えば、CI上で Database 起動させてテストするとかはこれ。
jobs: container-job: runs-on: ubuntu-latest container: image: node:10.16-jessie services: redis: image: redis ports: - 6379/tcp
job も actionもコンテナで実行しているときに services のコンテナの参照をするときは、ホスト名でok。
そのステップがホストで実行しているときに services のコンテナの参照をするときは、localhost
+ マッピングしているホストのポート
でアクセスする。
ホストでマッピングされたポートは ${{ job.services.<service_name>.ports[<port>] }}
でとれる。
上のredisなら、${{ job.services.redis.ports['6379'] }}
。
jobs.<job_id>.if
ジョブの実行自体をここで制御できる。circleci のwhen を job で指定するみたいなやつ。 if ではコンテキスト参照できるので、特定のコミットメッセージの場合はジョブを実行しないとかが書ける。
jobs: my_first_job: runs-on: ubuntu-latest if: github.event_name == 'pull_request' && github.event.action == 'unassigned'
あと、if ではコンテキスト参照するときに ${{ }}
で囲まなくていい。
演算子とか書式はドキュメント見るのがいい。
job じゃなくて step を 条件で実行制御したい場合は、jobs.<job_id>.steps.if
があるので、step に対して if を付ければok
jobs: my_first_job: runs-on: ubuntu-latest steps: - name: My first step if: github.event_name == 'pull_request' && github.event.action == 'unassigned' run: echo This event is a pull request that had an assignee removed.
jobs.<job_id>.steps
ここにやりたい処理を書いていく。
uses
で、GitHub Actions を利用したり runs
でシェルでコマンド実行したりできる。
uses は、step で特定のコンテナ実行とかもできるのでこれは結構便利。
- パブリック Repository の任意のリリースやブランチ、コミットを指定できる
- 自分のリポジトリで定義した action の参照
- public registory の docker をステップで実行
jobs: my_first_job: runs-on: ubuntu-latest steps: # use GitHub Actions - uses: actions/setup-node@v1 # use a specific version tag of a public repository - name: use AWS Repo uses: actions/aws@v2.0.1 # use a action in workflow repository - uses: ./.github/actions/my-action # use a docker in public registory - uses: docker://gcr.io/cloud-builders/gradle
jobs.<job_id>.steps.run
一行、複数行、所定のパスで実行というのがよく使うパターン。
複数行は、安定の |
なのでまぁ大丈夫そう。
jobs: my_first_job: runs-on: ubuntu-latest steps: # single line - run: sudo apt-get update # multi line - run: | sudo apt-get install google-cloud-sdk && \ kubectl
他のシェルを指定するには shell:
で指定する。
jobs: my_first_job: runs-on: ubuntu-latest steps: - run: sudo apt-get update shell: bash - run: Get-Location shell: pwsh
Windows の run
、あるいはpowershell
や pwsh
などを指定して PowerShell がシェルの場合、自動的に頭に $ErrorActionPreference = 'stop'
が追加されて Fail fast になるのと、末尾に if ((Test-Path -LiteralPath variable:\LASTEXITCODE)) { exit $LASTEXITCODE }
を追加して実行結果でrunステップが失敗するように処理が差し込まれているので注意。
jobs.<job_id>.steps.with
いわゆるパラメーター。
Actions とかでパラメーター渡すときは with の中に map (KeyValue) を書くことになる。
この with で指定したキーは、INPUT_
prefix つきで大文字に変換されて Actions 内部から参照できる。
first_name
というキーで指定したなら INPUT_FIRST_NAME
で値に参照できる。
jobs: my_first_job: runs-on: ubuntu-latest steps: - name: My first step uses: actions/hello_world@master with: first_name: Mona middle_name: The last_name: Octocat
環境変数
step のrun実行時に渡したいなら、env: で指定する。
jobs: my_first_job: runs-on: ubuntu-latest steps: - name: Hello world run: echo Hello world $FIRST_NAME $middle_name $Last_Name! env: FIRST_NAME: Mona middle_name: The Last_Name: Octocat
step のrunの中でいじるなら、シェルに従って環境変数を触ればいい。
# windows $env:PATH += ";$pwd\build\lib"
step 間で環境変数を保持したい場合は、set-env
を echo 出力する。Azure Pipeline に似た感じだけど微妙に違う。
::set-env name={name}::{value}
action_state
という環境変数に yellow
という値をいれる場合はこうなる。
echo "::set-env name=action_state::yellow"
先ほどの PATH をstep間で保持するならこう。
# windows $env:PATH += ";$pwd\build\lib" echo "::set-env name=PATH::$env:PATH"
PATH 環境変数への追加は、 echo "::add-path::/path/to/dir"
が用意されている。
echo "::set-env name=PATH::${PATH}:/path/to/dir"
でも動くけど、楽なほうで。
シークレット
シークレットの利用は、secrets コンテキスト経由で利用できる。 例えば SuperSecret というキーで登録したなら、${{ secrets.SuperSecret }}
。
利用する際は、with
構文か env
など環境変数経由で参照する。
steps: - name: Hello world action with: # Set the secret as an input super_secret: ${{ secrets.SuperSecret }} env: # Or as an environment variable super_secret: ${{ secrets.SuperSecret }}
GITHUB_TOKEN も シークレットコンテキスト経由で利用できます。
name: Pull request labeler on: - pull_request jobs: triage: runs-on: ubuntu-latest steps: - uses: actions/labeler@v2 with: repo-token: ${{ secrets.GITHUB_TOKEN }}
ログの表示で任意の文字列をマスクするために ::add-mask::{value}
もある。
Artifact
アップロード操作は$GITHUB_WORKSPACE
を起点に path で指定できます。
常に相対パスでいいので、絶対パスを気にする機会が減っていい感じです。
アップロードしてダウンロード
jobs: job_1: name: Add 3 and 7 runs-on: ubuntu-latest steps: - shell: bash run: | expr 3 + 7 > math-homework.txt - name: Upload math result for job 1 uses: actions/upload-artifact@v1 with: name: homework path: math-homework.txt job_2: name: Multiply by 9 needs: job_1 runs-on: windows-latest steps: - name: Download math result for job 1 uses: actions/download-artifact@v1 with: name: homework - shell: bash run: cat homework/math-homework.txt
Cache
サンプルはいくつかあるのでそれをみるのが手っ取り早い。
.NET Core の nuget を例で考えます。(.NET Framework は忘れましょう)
.NET Core は Package References にしていると csproj にpackage 情報に入るのが厄介です。 もし csproj が1つならこれでいいでしょう。
steps: - uses: actions/cache@v1 with: path: ~/.nuget/packages key: ${{ env.cache-version }}-${{ runner.os }}-nuget-${{ hashFiles('src/project.csproj') }} restore-keys: | ${{ env.cache-version }}-${{ runner.os }}-nuget-${{ hashFiles(''src/project.csproj') }} ${{ env.cache-version }}-${{ runner.os }}-nuget-
1つだけプロジェクトがあるならならいいのですが、複数の csproj に分離していると当然パッケージとバージョンの同一性を担保する方法が lock ファイルに比べて面倒です。 CirclrCI でやったように、csproj を拾ってきて md5 あたりを拾ってキャッシュキーにする感じになるでしょう。 CircleCI の例を載せておきます。
steps: - run: name: Calculate cache key for csproj command: | { md5sum $(find << parameters.search_path >> -name << parameters.target_file_pattern >> | sort -r) } > ~/cache-key-source-<< parameters.project >> working_directory: << parameters.working_directory >> - save_cache: name: Cache nuget pacakges key: nuget-<< parameters.cache_key >>-<< parameters.project >>-{{ checksum "~/cache-key-source-<< parameters.project >>" }} paths: - "~/.nuget"
なお、nuget は、macOSは Xamarin などでキャッシュサイズが半端なくなるので、こういうのを避けるために NuGet Package のパスを明示的に設定するのはあり。
その場合は、NUGET_PACKAGES
環境変数にパスを指定して、actions/cache の path にも指定する。
env: NUGET_PACKAGES: ${{ github.workspace }}/.nuget/packages steps: - uses: actions/cache@v1 with: path: ${{ github.workspace }}/.nuget/packages key: ${{ env.cache-version }}-${{ runner.os }}-nuget-${{ hashFiles('src/project.csproj') }} restore-keys: | ${{ env.cache-version }}-${{ runner.os }}-nuget-${{ hashFiles(''src/project.csproj') }} ${{ env.cache-version }}-${{ runner.os }}-nuget-
TIPS
細かいけど知っておくといい TIPS がたまってきたのでメモ。
step の name
step ごとに name を指定することで、GitHub 上の表示を設定できる。
省略するとコマンドがそのままでるので、CircleCI のように基本的に name 指定しないのがよさそう。
Azure Pipelie は、コマンドの内容ではなく command@1
とかのモジュール名の表示になってたので、GitHub Actions で改善してて本当に良かった、神。
タイムアウト
timeout-minutes
で指定できる。
デフォルトが 6hour と長いので、指定した方がいいケースが多い。
タイムアウトは、job と step ごとの両方に指定可能。
jobs: build: runs-on: ubuntu-latest timeout-minutes: 15 steps: - run: sleep 300 timeout-minutes: 3
skip ci / ci skip
2021/2/10 に、push/pull_request トリガーで標準サポートされました。
競合でもよく使われる [skip ci], [ci skip], [no ci], [skip actions], or [actions skip]
が網羅されててなるほど。
以前は、job の if で制御してましたがもう不要。
Organization の他の private repo の参照
ssh-agent
Action を使えば SSH キーで known_hosts
設定したりできるけど、あんまり使いたくはない。
自動生成される Token でその制御はできないので、専用の Token を生成するのが一番手っ取り早い。
- uses: actions/checkout@v1 with: repository: organization_name/repo_name token: ${{ secrets.ACCESS_TOKEN }}
Badge
サポートされてた。ドキュメントないけど。
いい感じの Action どこ
安定の awesome で。
ローカルで構文チェックするCLIとかないの
Circle CLI のようなローカル実行向けのCLI はないです。 残念。