GitHub Actionsでリリースを自動化しテーマの品質を高める施策
この記事でいうテーマとはWordPressやGatsbyにおけるデザインテンプレートを指しています。
開発に携わっているテーマ
私は趣味や仕事でNext.jsやWordPress、Reactなど有償、無償テーマの開発をする機会が多くあります。
こういったテーマを開発するにあたって、品質を高めるためのGitHub Actionsの効果的な設定が少しずつ見えてきたので、今回はそれを記事にしたいと思います。
以下は私が開発に携わっているテーマです!
SANGO
WordPressテーマ、装飾が豊富でWordPressのブロックエディターにも完全対応。
カスタマイズのしやすさや表示スピードが高速なことが自慢です!
Awesome (Free)
Next.js製のmdxで動作するブログテーマ。ContentfulやStrapiなどの外部サービスを必要とせずマークダウンだけで動作するブログテーマ。
Vercelにデプロイするだけで簡単にブログが始められます。
Notion Portfolio Site (Free)
Notion Public APIと連携したポートフォリオ用テーマ.
詳しい記事はこちらに書いています。
GitHub Actionsの設定場面
趣味で作っている無償テーマならまだ自由に開発しても許されるのですが、
1万円以上する有償テーマSANGOの場合、利用者も多くいらっしゃることもあり責任重大です。不具合があると使ってくださっているたくさんのユーザーにご迷惑をかけてしまうことになります。
また万が一不具合があった場合でもどこでその不具合を作り込んでしまったのかある程度目処をつけられるようにしておく必要があります。
そこでちょっとでも心の負担を減らすために以下の場面でGitHub Actionsを利用して特にリリース時の作業を効率化しています。
- バージョンごとにどのようなリリースを行なったのか分かるようにする
- バージョンごとの完成系をリリースノートからダウンロードできるようにする
- サポートしているPHPの一番低いバージョンで問題が起こらないか構文チェックを行う
1. バージョンごとにどのようなリリースを行なったのか分かるようにする
以下はGitHubのリリースノートのページなのですが、バージョンごとにどのようなリリースを行なったのか分かるようにGitHub Actionsで自動出力しています。
これによりユーザーさんから質問があった際にどのバージョンで該当の機能がリリースされているか把握しやすくなります。
これによりユーザーさんに利用いただいているテーマのバージョンを尋ねるだけで問題解決の糸口が見つかるケースがもあります。
リリースノートは以下のツールを利用して生成しています。
release-drafter.ymlの設定
このツールを使ってリリースノートを生成するためにはrelease-drafter.ymlの設定が必要です。
自分は以下のような設定を行なっています。
.github/release-drafter.yml
name-template: 'v$RESOLVED_VERSION 🌈'
tag-template: 'v$RESOLVED_VERSION'
exclude-labels:
- 'release'
- 'auto'
categories:
- title: '🚀 Features'
labels:
- 'feature'
- 'enhancement'
- title: '🐛 Bug Fixes'
labels:
- 'fix'
- 'bugfix'
- 'bug'
- title: '🧰 Maintenance'
label: 'chore'
change-template: '- $TITLE @$AUTHOR (#$NUMBER)'
change-title-escapes: '\<*_&' # You can add # and @ to disable mentions, and add ` to disable code blocks.
template: |
## Changes
$CHANGES
この設定では、GitHubのPull Requestにfix
、bug
bugfix
などのラベルがついていると以下のようにリリースノートにBug Fixesというタイトルの下にPull Request時のタイトルが並ぶようになります。
## 🐛 Bug Fixes
- テーマの有効化時にはレガシーウィジェットが有効化されるように調整 @steelydylan (#327)
また、feature
やenhancement
などのラベルがついていると以下のようにFeaturesというタイトルの下にPull Request時のタイトルが並びます。
## 🚀 Features
- カスタマイザーにインフィード広告の設定を追加 @steelydylan (#339)
ただこれを実現するには必ずPull Requestごとに正しいラベルが設定されている必要があります。
ただし、そこは人なので忘れてしまうケースが多いです。
そのためPull Request時にラベルが設定されていないとGitHub Actionsに怒ってもらうように以下のように設定しています。
.github/workflows/pr.yml
name: PR
env:
CI: true
on:
pull_request:
branches:
- master
- development
types:
- opened
- synchronize
- closed
- labeled
- unlabeled
tags:
- "!*"
jobs:
release:
name: Setup
runs-on: ubuntu-latest
steps:
- name: check label
if: |
github.event_name == 'pull_request' &&
!contains(github.event.pull_request.labels.*.name, 'fix') &&
!contains(github.event.pull_request.labels.*.name, 'bugfix') &&
!contains(github.event.pull_request.labels.*.name, 'enhancement') &&
!contains(github.event.pull_request.labels.*.name, 'chore') &&
!contains(github.event.pull_request.labels.*.name, 'feature') &&
!contains(github.event.pull_request.labels.*.name, 'release') &&
!contains(github.event.pull_request.labels.*.name, 'auto')
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
URL: ${{ github.event.pull_request.comments_url }}
run: |
echo "Please add one of the following labels: fix, bugfix, enhancement, chore, feature, release" >> comments
sed -i -z 's/\n/\\n/g' comments
curl -X POST \
-H "Authorization: token ${GITHUB_TOKEN}" \
-d "{\"body\": \"$(cat comments)\"}" \
${URL}
exit 1
これにより下の画像のようにラベルがついていない場合はPR上で注意してくれます。
2. バージョンごとの完成系をリリースノートからダウンロードできるようにする
先程のリリースノートからテーマを完成系でダウンロードできるようにしています。
それまでは手作業でローカルのテーマをzipしたりしていたのですが、それだとヒューマンエラーでテーマのバージョン間違いや、意図しないファイルが混在してしまうケース、zipするフォルダを間違えてしまうといったケースが発生してしまいます。
バージョンごとのリリースノートで完成系のファイルをダウンロードできるようにしておけばそういった誤りを防ぐことができます。
そこでGit Flowの考え方を一部採用し、以下のフローでリリースノートが完成し、そのリリースノートから成果物をダウンロードできるようにしました。
-
develop
ブランチからfeature/***
ブランチを切る -
enhancement
などのラベルをつけてdevelop
にマージする - リリース時は
develop
からrelease/2.11.0
などのブランチ名を作る -
release/2.11.0
からmaster
に向けてPRを作る -
master
にマージされるとリリースノートが生成される
4のステップではPR時に以下のようなワークフローを作っています。
version-check
name: Version Check
on:
pull_request:
branches:
- master
types:
- opened
- synchronize
jobs:
auto-bumping:
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@v1
- name: setup Node
uses: actions/setup-node@v1
with:
node-version: 12.x
registry-url: 'https://npm.pkg.github.com'
- name: install
run: yarn --frozen-lockfile
- name: version check #ここでブランチ名とpackage.jsonのバージョンが一致しているかをチェック
run: BRANCH_NAME=$HEAD_BRANCH node ./tools/version-check.js
env:
HEAD_BRANCH: ${{ github.head_ref }}
const pkg = require("../package.json");
const branch = process.env.BRANCH_NAME;
// 例えば、release/2.11.0というブランチ名の場合、version変数に2.11.0を格納する
const [type, version] = branch.split("/");
console.log(pkg.version, version);
if (pkg.version !== version) {
throw new Error("version not matched");
}
ここではrelease/***
ブランチの***
に当たるバージョンとpackage.json
のバージョンが一致しているかを確認しています。
5のステップにおいてはreleaseブランチのPRがmasterにマージされた際のワークフローを以下のように設定しています。
.github/workflows/publish.yml
name: Publish
env:
CI: true
# masterブランチにpushした時のみ実行するワークフロー
on:
push:
branches:
- master
tags:
- "!*"
jobs:
release:
name: Release
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@v1
- name: setup Node
uses: actions/setup-node@v1
with:
node-version: 12.x
registry-url: 'https://registry.npmjs.org'
- name: install
run: yarn --frozen-lockfile
- name: package-version #ここで環境変数にpackage.jsonのバージョンをセット
run: node -p -e '`PACKAGE_VERSION=${require("./package.json").version}`' >> $GITHUB_ENV
- name: package-version-to-git-tag #ここで先程の環境変数をgitのtagに指定
uses: pkgdeps/action-package-version-to-git-tag@v1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
github_repo: ${{ github.repository }}
git_commit_sha: ${{ github.sha }}
git_tag_prefix: ""
version: ${{ env.PACKAGE_VERSION }}
- name: get-npm-version
id: package-version
uses: martinbeentjes/npm-get-version-action@master
- name: create release draft #ここでリリースノートを作成
id: create-draft
uses: release-drafter/release-drafter@v5.12.1
with:
version: ${{ steps.package-version.outputs.current-version }}
name: ${{ steps.package-version.outputs.current-version }}
tag: ${{ steps.package-version.outputs.current-version }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload Release Asset #ここで成果物をリリースノートにアップロード
id: upload-release-asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create-draft.outputs.upload_url }}
asset_path: ./sango-theme.${{ steps.package-version.outputs.current-version }}.zip
asset_name: sango-theme.${{ steps.package-version.outputs.current-version }}.zip
asset_content_type: application/zip
package.jsonに記述されているテーマのバージョンが自動でgitのタグに設定され、そのgitのタグがリリースノートに自動で記載されるのがポイントです!
また、upload-release-asset
というGitHub Actionを使うことで簡単にRelease Drafterから成果物を受け取ってアセットをリリースノートにアップロードすることができました。
3. サポートしているPHPの一番低いバージョンで問題が起こらないか構文チェックを行う
またWordPressテーマの開発などではレンタルサーバーごとのPHPのバージョンの違いが不具合につながったりするケースが多いです。例えば開発者が最新のPHP8系で開発しているのに対し一般のユーザーの方は5系のレンタルサーバーを使っていたりしてバージョンの違いからエラーになることがあります。
そこでテーマがサポートする最低限のバージョンに合わせてPHPの構文チェックをPull Request時のワークフローの中で取り入れています。
phplintというパッケージが構文チェックにとても便利です!
GitHub Actionsでcomposer install
後にこのphplintを実行し意図しないPHPの構文が存在していないかチェックをします。
まとめ
テーマの開発は大変なことが多いです。特にレンタルサーバーによって色々なPHPのバージョンが存在するWordPressのテーマ開発はとても大変です。WordPress自体の仕様変更に翻弄されるケースも多いです。
またリリースを焦っている時などはテーマの梱包に失敗したりするなどのミスを起こしがちです。
GitHub ActionsやCIの仕組みを利用すればそういったトラブルやストレスを軽減できます。
もしテーマを開発する機会があった際には今回の施策を思い出していただけると幸いです!
Discussion