GitHub Actionsで記事サイトを自動検品する|失敗ならデプロイしない設計
Astroの記事サイトを例に、依存関係の固定、静的ビルド、Markdownの独自検算、失敗時の配信停止、同時実行の制御までをGitHub Actionsの設定例で解説します。
GitHub Actionsで依存関係の導入、Astroのビルド、記事独自の検算、デプロイを直列に並べ、失敗したら配信へ進ませない設計を作ります。自動化する作業の選び方は、毎日の繰り返し作業を自動化する考え方も参考になります。
配信前ゲートの全体像
配信前ゲートとは、公開してよい状態かを機械判定する関所です。次の順番を固定します。
- リポジトリの内容を取得する
- 指定したNode.jsを用意する
- lockfileどおりに依存パッケージを導入する
- Astroをビルドする
- 記事固有のルールを検算する
- すべて成功した場合だけデプロイする
ビルドはMarkdownやfrontmatter(記事冒頭のメタ情報)の型エラーを見つけます。文字数、見出し、出典などの編集ルールは独自検算で補います。記事作りを半自動化する手順のように、生成、検品、公開を分けると役割が明確です。
| 関所 | 主なコマンド・設定 | 失敗したとき |
|---|---|---|
| 依存関係 | npm ci | lockfileの不一致や導入エラーで停止 |
| 静的ビルド | npm run build | Astroのビルドエラーで停止 |
| 記事検算 | npm run kensan | 独自ルール違反で停止 |
| デプロイ | 前3段の後ろに配置 | 前段が失敗した実行では開始しない |
| 同時実行 | cancel-in-progress: true | 同じグループの古い実行をキャンセル |
installとbuildを分ける
CI(変更ごとの自動検証)ではnpm ciを使います。既存のpackage-lock.jsonなどが必須で、package.jsonと不一致ならlockfileを更新せず失敗します。導入とビルドを別ステップにすれば、失敗箇所をログで判別できます。
name: 記事サイトの検品と配信
on:
push:
branches: [main]
workflow_dispatch:
permissions:
contents: read
jobs:
verify-and-deploy:
runs-on: ubuntu-latest
steps:
- name: ソースを取得
uses: actions/checkout@v7
- name: Node.jsを準備
uses: actions/setup-node@v7
with:
node-version: 24
cache: npm
- name: 依存関係を固定して導入
run: npm ci
- name: Astroをビルド
run: npm run build
2026年7月23日の公式使用例は両Actionともv7です。メジャーバージョンは固定しつつ、更新時は各Actionのリリースノートとランナー要件を確認します。Node.jsもローカルと同じ版へ固定してください。setup-nodeのnpmキャッシュはパッケージ管理用データを再利用しますが、node_modules自体はキャッシュしません。詳しい使い分けはGitHub Actionsのキャッシュ入門で確認できます。
独自検算を追加する
独自検算は違反時に0以外の終了コードを返します。警告を表示するだけで正常終了してはいけません。たとえば次を確認します。
- frontmatterに必須項目がある
- H1を置かず、H2が一つ以上ある
- 本文が最低文字数を満たす
- 内部リンク先が存在する
違反理由とファイル名をerrorsへ追加します。
const errors = [];
// 各Markdownを検査し、違反があればerrorsへ追加する
if (errors.length > 0) {
console.error(errors.join('\n'));
process.exit(1);
}
console.log('記事検算に合格しました');
package.jsonへ"kensan": "node tools/kensan.mjs"を登録し、ワークフローから呼びます。
- name: 記事ルールを検算
run: npm run kensan
まず必須項目とリンク切れを失敗条件にし、表記揺れなどは警告に分けると段階導入できます。
失敗時に配信を止める
同じジョブのステップは上から実行され、条件式には既定でsuccess()が適用されます。検算の後ろへデプロイを置けば、前段が成功した場合だけ配信されます。
- name: 記事ルールを検算
run: npm run kensan
- name: 本番へデプロイ
run: npm run deploy
検算にcontinue-on-error: true、配信にif: always()は付けません。前者は失敗を許容し、後者は前段の結果にかかわらず実行させるためです。
別ジョブへ分けるなら配信側にneeds: verifyを指定します。依存先が失敗すると配信側も通常はスキップされます。ただし別ジョブへdistを渡す処理が増えるため、小規模サイトは同一ジョブから始めると追いやすくなります。停止時は最後に成功したステップと終了コードを見ます。自動化の失敗を切り分ける基本も確認表になります。
同時実行を制御する
短時間に複数回pushすると、古い配信が後から完了する可能性があります。concurrencyで同じグループの実行を制御します。
concurrency:
group: article-deploy-${{ github.ref }}
cancel-in-progress: true
この例はブランチごとに古い実行をキャンセルします。同じグループの実行順は保証されないため、順番待ちではなく古い配信を残さない用途に使います。
ローカルとCIの差を減らす
CIだけ失敗するときは、コマンド、Node.js、環境変数の差を疑います。
- ローカルでも同じ3コマンドを同じ順序で実行する
- Node.jsの版を合わせる
- 検算をリポジトリ内のスクリプトにする
- 配信の秘密はデプロイだけで参照する
共通入口なら、人とActionsが同じ処理を再現できます。最初は検品だけ動かし、安定後にデプロイを加える方法もあります。
導入後の確認項目
最初から多くの規則を必須にすると、原因の切り分けが難しくなります。次の順で導入すると、どの関所が効いたかを確認しやすくなります。
- pull requestで
npm ci、npm run build、npm run kensanを動かす - 意図的に検算違反を1件作り、ジョブが0以外の終了コードで失敗することを確かめる
- mainへのデプロイを後段へ追加し、検算失敗時に実行されないことを確かめる
- 短時間に2回更新し、古い実行がキャンセルされることを確かめる
ジョブが長引く場合はGitHub Actionsにタイムアウトを追加する方法を、通知まで整える場合はGitHub Actionsの失敗通知を次の手順にできます。
よくある質問
npm installではなくnpm ciを使う理由は何ですか?
npm ciは既存のlockfileを前提にし、package.jsonと内容が合わなければ更新せず終了します。開発者ごとの差を減らし、CIで同じ依存関係を再現したい場合に向いています。
Astroのビルドだけで記事検品は十分ですか?
十分とは限りません。astro buildは配信用ファイルを生成する工程ですが、最低文字数や出典数、独自の見出し規則まで自動で保証するものではありません。サイト固有の編集基準は別の検算スクリプトで補います。
検算だけ失敗してもデプロイを続けられますか?
設定上は可能ですが、配信前ゲートの目的とは合いません。検算ステップへcontinue-on-error: trueを付けず、デプロイを同じジョブの後段に置くか、needsで検品ジョブへ依存させます。
キャッシュを使うとnpm ciは不要になりますか?
不要にはなりません。キャッシュはパッケージ取得を速めるための仕組みで、依存関係をlockfileどおりに導入する処理の代わりではありません。キャッシュが見つからない場合も動く構成にします。
一次情報の確認メモ
確認日: 2026-07-23
- GitHub Actionsのワークフロー構文、
needs、ジョブ依存: https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax - 条件式の既定
success()とステータス関数: https://docs.github.com/en/actions/reference/workflows-and-actions/expressions - concurrencyグループと
cancel-in-progress: https://docs.github.com/en/actions/how-tos/write-workflows/choose-when-workflows-run/control-workflow-concurrency - 終了コード0と0以外の扱い: https://docs.github.com/en/actions/how-tos/create-and-publish-actions/set-exit-codes
npm ciのlockfile要件と不一致時の終了: https://docs.npmjs.com/cli/commands/npm-ci/actions/checkout@v7の公式使用例と推奨権限: https://github.com/actions/checkoutactions/setup-node@v7、Node.js 24、npmキャッシュの公式使用例: https://github.com/actions/setup-node- Astroの
astro build、astro check、終了コードの公式説明: https://docs.astro.build/en/reference/cli-reference/ - GitHub Actionsの依存関係キャッシュの公式説明: https://docs.github.com/en/actions/concepts/workflows-and-actions/dependency-caching
続き(結論と実データ)はnoteに置いています
ここでは手順のところまで書きました。実際に出た数字、うまくいかなかった条件、そのまま使える設定ファイルは、 note の記事にまとめてあります。