ついにGitHub ActionsもGAになりました
という訳で、記念に記事でも書きたいと思います。
前に【GitHub Actions】自作Actionsのリリースを自動化するを書いたのですが、あれからもっと完結にリリースを自動化できるようになったのでご紹介します。
前記事では面倒なことをしていたので、これからリリース自動化したいなと考えている方は本記事を参考にしてください。
使用するActions
リリースの自動化に使用するActionsはactions/create-releaseです。
使用方法
README.mdに使用例が書かれています。
jobs:
build:
name: Create Release
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@master
- name: Create Release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: Release ${{ github.ref }}
draft: false
prerelease: false
with以下のパラメーターの名前から推測できると思いますので特に説明しませんが、action.ymlに使用できるパラメーターと説明が書かれているので一読することをお勧めします。
正常にリリースができればhtml_urlを出力できるのでTwitter APIとかでSNSにリリースを自動で投稿することができます。html_urlの取得方法は上記の例だとsteps.create_release.outputs.html_url
になります。
ソースコード紹介
actions/create-releaseを少し深掘りしてみます。
このActionsは内部的に@actions/githubを使用しています。さらに@actions/githubは@octokit/restと@octokit/graphqlを使用しています。create-releaseではGraphQLのクライアントは使用せず、@octokit/restのoctokit.repos.createReleaseでリリースしています。
actions/create-relaseで実際にリリースをするコアなコードはこちらになります。一応↓にも書いておきます。
const github = new GitHub(process.env.GITHUB_TOKEN);
// Get owner and repo from context of payload that triggered the action
const { owner, repo } = context.repo;
// Get the inputs from the workflow file: https://github.com/actions/toolkit/tree/master/packages/core#inputsoutputs
const tagName = core.getInput('tag_name', { required: true });
// This removes the 'refs/tags' portion of the string, i.e. from 'refs/tags/v1.10.15' to 'v1.10.15'
const tag = tagName.replace('refs/tags/', '');
const releaseName = core.getInput('release_name', { required: true }).replace('refs/tags/', '');
const draft = core.getInput('draft', { required: false }) === 'true';
const prerelease = core.getInput('prerelease', { required: false }) === 'true';
// Create a release
// API Documentation: https://developer.github.com/v3/repos/releases/#create-a-release
// Octokit Documentation: https://octokit.github.io/rest.js/#octokit-routes-repos-create-release
const createReleaseResponse = await github.repos.createRelease({
owner,
repo,
tag_name: tag,
name: releaseName,
draft,
prerelease
});
@octokit/restを@actions/githubでラップしているのでgithub.repos.createRelease
となっていますが、octokit.repos.createRelease
とほぼ同等です。ちなみにoctokit.repos.createRelease
ではbody
というパラメーターがあってリリースの説明を記述できますが、github.repos.createRelease
ではそのパラメーターが実装されていません。2019/11/14時点でプルリクが上がっていたので、そのうちマージされると思います。なるはやでして欲しいところです
リリース名がタグと同じになるようにreplaceされているので、release_nameには${{ github.ref }}
を渡しておけば大丈夫です。
リリース自動化
それでは本題の自動リリースのシンプル化です。最初にworkflowのYAMLを載せておきます。
name: Prepare for release
on:
push:
tags:
- 'v*'
jobs:
release:
name: Build production
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
with:
node-version: '10.x'
- name: Create Release
uses: actions/create-release@v1.0.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: ${{ github.ref }}
draft: 'false'
prerelease: 'false'
- name: Slack Notification
uses: homoluctus/slatify@master
if: always()
with:
type: ${{ job.status }}
job_name: ':rocket: *Publish new release ${{ github.ref }}*'
channel: '#develop'
url: ${{ secrets.SLACK_WEBHOOK }}
各ブロックの説明
トリガー
on:
push:
tags:
- 'v*'
プレフィックスがv
のタグがプッシュされるとworkflowがスタートします。*
は一般的な正規表現で使われる意味と同じです。なので、リリースしたいときはv1.0
みたいな感じでタグ付けしてプッシュすればOKです。
リリース
- name: Create Release
uses: actions/create-release@v1.0.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: ${{ github.ref }}
draft: 'false'
prerelease: 'false'
tag_name
とrelease_name
には${{ github.ref }}
を指定しています。${{ github.ref }}
の実体はref/tags/v1.0
みたいになっています。actions/create-releaseのソースコードの説明でreplaceしていると言った通りref/tags
は取り除かれるので、tag_nameとrelease_nameはv1.0になります。もちろ他の文言にすることもできます。そこは自由です。
おわりに
冒頭でも言いましたが、ついにGitHub ActionsもGAになりました
GitHub Actionsは他のCI/CDにも劣らずかなり優秀です。
これからコミュニティが発展していき、開発者や運用者たちがもっと楽になればいいなと思っています。