GitHub Actions で GitHub CLI を使う
GitHub CLI とは
GitHub の操作を提供する公式 CLI コマンドです。
hub
コマンドもありますが比較は gh vs hub を確認してみてください。
インストール
GitHub ホストランナーにはプリインストールされているので何もせずに使えます。
セルフホストランナーにインストールする場合は Installation を参照してください。
sudo yum install -y https://github.com/cli/cli/releases/download/v1.11.0/gh_1.11.0_linux_386.rpm
認証
対話型では gh auth login
でログインしますが非対話型では環境変数 GH_TOKEN
または GITHUB_TOKEN
が使用できます。
ジョブ単位またはステップ単位で指定します。
jobs:
github:
runs-on: ubuntu-20.04
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GitHub Enterprise
GitHub Enterprise の場合は GH_ENTERPRISE_TOKEN
または GITHUB_ENTERPRISE_TOKEN
です。
ホストの指定は GH_HOST
で行います。
env:
GH_ENTERPRISE_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_HOST: github.example.com
値には secrets.GITHUB_TOKEN
を使用します。
Personal Access Token を発行して使用することもできます。
使用例
クローン
# uses: actions/checkout@v2 と同等の clone オプション
- run: gh repo clone $GITHUB_REPOSITORY . -- --depth 1 --branch ${GITHUB_REF#refs/heads/}
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- run: gh repo clone $GITHUB_REPOSITORY . -- --no-checkout --filter=tree:0 --branch ${GITHUB_REF#refs/heads/}
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- run: git sparse-checkout init --cone
- run: git sparse-checkout set $PATTERNS
env:
PATTERNS: |
subdir1
subdir2
- run: git switch ${GITHUB_REF#refs/heads/}
補足:デフォルトシェルの bash
では変数を展開する際に ${変数名#パターン}
とすると先頭がパターンにマッチした場合に最短マッチ部分を削除してくれます。
情報の取得
リポジトリの特定が必要な場合は --repo
オプションまたは GH_REPO
環境変数を使用します。
リポジトリをチェックアウト済みの場合は省略できます。
以下の例で PR 1〜3 は同じ結果を返します。
# バージョン、ヘルプ
- run: gh --version
- run: gh --help
# リポジトリ
- run: gh repo list
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# PR 1
- run: gh pr list --repo $GITHUB_REPOSITORY
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# PR 2
- run: gh pr list
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
# PR 3
- uses: actions/checkout@v2
- run: gh pr list
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# ヘルプ
- run: gh actions --help
# env:
# GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} # なぜか認証が要る => v1.12.0 で修正されました
# ワークフロー
- run: gh workflow list
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
# ワークフロー実行ログ
- run: gh run list --workflow 'GitHub CLI'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
- run: gh run list --workflow gh.yml
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
# 実行中のワークフロー
- run: gh run view $(gh run list --workflow gh.yml --limit 1 | cut -f 7)
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
# # watch は無限ループするので注意(試す場合は要タイムアウト)
# - run: gh run watch $(gh run list --workflow gh.yml --limit 1 | cut -f 7)
# env:
# GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# GH_REPO: ${{ github.repository }}
# timeout-minutes: 1
Draft PR 作成
name: GitHub CLI
on:
push:
branches:
- fix/**/*
jobs:
create-pr:
runs-on: ubuntu-20.04
steps:
# リポジトリがないとなぜかエラーになる
# fatal: not a git repository (or any of the parent directories): .git
- uses: actions/checkout@v2
# title は直近のコミットメッセージで body は空
- run: gh pr create --draft --title "$(git log -1 --oneline --pretty=format:'%s')" --body "" --assignee $AUTHOR
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
AUTHOR: ${{ github.event.pusher.name }}
create-pr-fill:
runs-on: ubuntu-20.04
steps:
# 履歴だけ取得
- run: gh repo clone $GITHUB_REPOSITORY . -- --no-checkout --filter=tree:0 --branch ${GITHUB_REF#refs/heads/}
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# title と body を自動入力
- run: gh pr create --draft --fill --assignee $AUTHOR
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
AUTHOR: ${{ github.event.pusher.name }}
どちらの場合も同じブランチで2回目の push が発生するとエラーになるので要制御。
↑の YAML はそのまま使うと後から実行されたジョブが失敗します。
API リクエスト
octokit/request-action
を使用することが多いと思いますが gh
コマンドでも API を叩くことができます。
# [REST API] Issue のタイトルリスト
- run: gh api repos/${REPOSITORY}/issues --jq '.[].title'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REPOSITORY: ${{ github.repository }}
# [GraphQL] リポジトリのリスト
- run: |
gh api graphql --paginate -f query='
query($endCursor: String) {
viewer {
repositories(first: 100, after: $endCursor) {
nodes { nameWithOwner }
pageInfo {
hasNextPage
endCursor
}
}
}
}
'
env:
# GITHUB_TOKEN だと実行中のリポジトリ情報しか取れないので PAT 発行
GH_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
まとめ
他にも Gist やリリースを扱えたりと様々なコマンドが存在します。
詳しくはドキュメントを読んでみてください。
Discussion