はじめに
今回はGitHub ActionsからGitHub REST APIを利用してブランチを作成する方法を紹介したいと思います。
概要
GitHub REST API
を利用することで、Repositoryの情報取得・Issue管理・PullRequestの管理・CommitやBranch管理などなど、GitHubの様々な操作を自動化できます。
docs.github.com
詳細は公式ドキュメントを参照してみてください。
やり方
name: test on: workflow_dispatch: inputs: new_branch: description: "New branch name" required: true jobs: create-branch: runs-on: ubuntu-latest permissions: contents: write # GITHUB_TOKENに書き込み権限を付与 steps: - env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} REPOSITORY: ${{ github.repository }} BASE_BRANCH: main NEW_BRANCH: ${{ inputs.new_branch }} run: | # 指定したレポジトリ・ブランチの最新のコミットハッシュ取得 LATEST_COMMIT=$(gh api "repos/${REPOSITORY}/commits/${BASE_BRANCH}" | jq -r '.sha') # ブランチを作成する gh api --method POST "repos/${REPOSITORY}/git/refs" -f "ref=refs/heads/${NEW_BRANCH}" -f "sha=${LATEST_COMMIT}"
gh auth login
コマンドを使用するのでなく、アクセス トークンをGH_TOKEN
という環境変数として渡します。 これでその後の処理ができるようになります。
GitHub REST API のクイックスタート - GitHub Docs
最新コミットSHAの取得
LATEST_COMMIT=$(gh api "repos/${REPOSITORY}/commits/${BASE_BRANCH}" | jq -r '.sha')
指定されたリポジトリとブランチの最新コミットSHAを取得します。
docs.github.com
公式ドキュメントの例
# Request $ gh api \ -H "Accept: application/vnd.github+json" \ -H "X-GitHub-Api-Version: 2022-11-28" \ /repos/OWNER/REPO/commits # Response [ { "url": "https://api.github.com/repos/octocat/Hello-World/commits/6dcb09b5b57875f334f61aebed695e2e4193db5e", "sha": "6dcb09b5b57875f334f61aebed695e2e4193db5e", "node_id": "MDY6Q29tbWl0NmRjYjA5YjViNTc4NzVmMzM0ZjYxYWViZWQ2OTVlMmU0MTkzZGI1ZQ==", "html_url": "https://github.com/octocat/Hello-World/commit/6dcb09b5b57875f334f61aebed695e2e4193db5e", "comments_url": "https://api.github.com/repos/octocat/Hello-World/commits/6dcb09b5b57875f334f61aebed695e2e4193db5e/comments", "commit": { "url": "https://api.github.com/repos/octocat/Hello-World/git/commits/6dcb09b5b57875f334f61aebed695e2e4193db5e", "author": { "name": "Monalisa Octocat", "email": "support@github.com", "date": "2011-04-14T16:00:49Z" }, "committer": { "name": "Monalisa Octocat", "email": "support@github.com", "date": "2011-04-14T16:00:49Z" }, "message": "Fix all the bugs", "tree": { "url": "https://api.github.com/repos/octocat/Hello-World/tree/6dcb09b5b57875f334f61aebed695e2e4193db5e", "sha": "6dcb09b5b57875f334f61aebed695e2e4193db5e" }, "comment_count": 0, "verification": { "verified": false, "reason": "unsigned", "signature": null, "payload": null } }, "author": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/octocat/followers", "following_url": "https://api.github.com/users/octocat/following{/other_user}", "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}", "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/octocat/subscriptions", "organizations_url": "https://api.github.com/users/octocat/orgs", "repos_url": "https://api.github.com/users/octocat/repos", "events_url": "https://api.github.com/users/octocat/events{/privacy}", "received_events_url": "https://api.github.com/users/octocat/received_events", "type": "User", "site_admin": false }, "committer": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/octocat/followers", "following_url": "https://api.github.com/users/octocat/following{/other_user}", "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}", "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/octocat/subscriptions", "organizations_url": "https://api.github.com/users/octocat/orgs", "repos_url": "https://api.github.com/users/octocat/repos", "events_url": "https://api.github.com/users/octocat/events{/privacy}", "received_events_url": "https://api.github.com/users/octocat/received_events", "type": "User", "site_admin": false }, "parents": [ { "url": "https://api.github.com/repos/octocat/Hello-World/commits/6dcb09b5b57875f334f61aebed695e2e4193db5e", "sha": "6dcb09b5b57875f334f61aebed695e2e4193db5e" } ] } ]
新しいブランチの作成
gh api --method POST "repos/${REPOSITORY}/git/refs" -f "ref=refs/heads/${NEW_BRANCH}" -f "sha=${LATEST_COMMIT}"
新しいブランチを作成します。
docs.github.com
公式ドキュメント例
# Request $ gh api \ --method POST \ -H "Accept: application/vnd.github+json" \ -H "X-GitHub-Api-Version: 2022-11-28" \ /repos/OWNER/REPO/git/refs \ -f "ref=refs/heads/featureA" -f "sha=aa218f56b14c9653891f9e74264a383fa43fefbd" # Response { "ref": "refs/heads/featureA", "node_id": "MDM6UmVmcmVmcy9oZWFkcy9mZWF0dXJlQQ==", "url": "https://api.github.com/repos/octocat/Hello-World/git/refs/heads/featureA", "object": { "type": "commit", "sha": "aa218f56b14c9653891f9e74264a383fa43fefbd", "url": "https://api.github.com/repos/octocat/Hello-World/git/commits/aa218f56b14c9653891f9e74264a383fa43fefbd" } }
ちなみに
最近はPowerShell布教活動を行っているので、pwsh
でのやり方も紹介します。
name: test on: workflow_dispatch: inputs: new_branch: description: "New branch name" required: true jobs: create-branch: runs-on: ubuntu-latest permissions: contents: write steps: - env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} REPOSITORY: ${{ github.repository }} BASE_BRANCH: main NEW_BRANCH: ${{ inputs.new_branch }} shell: pwsh run: | $last_commit = gh api "repos/${env:REPOSITORY}/commits/${env:BASE_BRANCH}" | ConvertFrom-Json | Select-Object -ExpandProperty sha gh api --method POST "repos/${env:REPOSITORY}/git/refs" -f "ref=refs/heads/${env:NEW_BRANCH}" -f "sha=${last_commit}"