BLOG
GitHub ActionsでGitHub Pagesに自動デプロイする
Astro製のポートフォリオサイトを、GitHub Actionsを使ってGitHub Pagesに自動デプロイする方法を解説します。push するだけで本番に反映される CI/CD パイプラインを丁寧に説明します。
はじめに
このポートフォリオサイトはAstroというフレームワークで構築しており、GitHub Pagesでホスティングしています。
最初は記事を書くたびに次のような手順を踏んでいました。
- ローカルで
astro buildを実行する - 生成された
dist/フォルダを手動でアップロードする - GitHub Pagesに反映されたことを確認する
この作業を毎回手で行うと、「ビルド忘れ」や「アップロードし忘れ」が起きやすくなります。
そこでGitHub Actionsを導入し、mainブランチにgit pushするだけで自動的にビルドからデプロイまで完結する仕組みを構築しました。
本記事では、GitHub Actionsを初めて使う人でも流れを追えるように、設定ファイルの役割を順に解説します。
設定手順のみを知りたい方はこちらからジャンプしてください。
GitHub Pagesとは
まず、GitHub Pages と GitHub Actions の役割を簡単に整理します。
GitHub Pagesは、GitHub が無料で提供する静的サイトのホスティングサービスです。
リポジトリに HTML・CSS・JavaScript ファイルを置くだけで、https://ユーザー名.github.io/ というURLでウェブサイトを公開できます。 独自ドメインの設定も可能で、個人ポートフォリオやドキュメントサイトによく使われています。
ただし、GitHub Pages はあくまで「静的ファイルを配信するサービス」です。 Astro のようなフレームワークで作ったサイトは、公開前にビルドして HTML・CSS・JS に変換する必要があります。
GitHub Actionsとは
次に、GitHub Actionsは、GitHubに組み込まれた自動化ツールです。
「リポジトリにpushされた」「PRが作成された」といったイベントをトリガーに、 あらかじめ定義したワークフローを自動で実行してくれます。
今回のケースでは次のように使います。
- トリガー:mainブランチへの push
- 自動実行する処理:ビルド → GitHub Pages へのデプロイ
このように、コードを変更したら自動でテスト・ビルド・デプロイする仕組みを CI/CD(継続的インテグレーション / 継続的デリバリー) と呼びます。
このサイトの構成と自動デプロイの仕組み
次に、自動デプロイがどのような流れで実行されるのかを確認します。
参考までに、このサイトの技術スタックを簡単に紹介します。
| 項目 | 内容 |
|---|---|
| フレームワーク | Astro 5 |
| スタイリング | Tailwind CSS v4 / DaisyUI |
| ホスティング | GitHub Pages |
| デプロイ | GitHub Actions |
| Node.js | 20.x |
GitHub Actions の設定が完了すると、次の流れで自動デプロイが動きます。
- ローカルで
git push origin main - GitHubがイベント検知
- GitHub Actionsがワークフローを起動
buildジョブで以下が実行- リポジトリのコードを取得
Node.jsをインストールnpm installnpm run build- 生成された
dist/を一時保存
- ビルドが成功したら
deployジョブに移る- 保存されていた
dist/を取り出す - GitHub Pagesに展開
- 保存されていた
- https://username.github.io/に反映される
ここで、ビルドとデプロイを別々のジョブに分けているのがポイントです。
ビルドが失敗した場合、デプロイジョブは実行されません。 これにより、壊れた状態のコードが誤って公開されることを防げます。
設定手順
ここから実際の設定手順に入ります。
1. GitHub Pages のデプロイ元を変更する
まず、GitHub Pagesがどこからファイルを取得するかを設定します。
リポジトリのページを開き、Settings → Pages → Build and deployment → Source と進みます。
ここを GitHub Actions に変更してください。
2. ワークフローファイルを作成する
リポジトリのルートに .github/workflows/ フォルダを作成し、その中に deploy.yml を作ります。
my-portfolio/├── .github/│ └── workflows/│ └── deploy.yml ← このファイルを作成する├── src/├── astro.config.mjs└── package.jsondeploy.ymlの内容は次のとおりです。これがこのポートフォリオで実際に使用しているワークフローです。
name: Deploy to GitHub Pages
on: push: branches: [main] workflow_dispatch:
permissions: contents: read pages: write id-token: write
concurrency: group: "pages" cancel-in-progress: false
jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: "20" cache: "npm" - uses: actions/configure-pages@v4 - name: Install dependencies run: npm install - name: Build with Astro run: npm run build - uses: actions/upload-pages-artifact@v3 with: path: ./dist
deploy: needs: build runs-on: ubuntu-latest environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} steps: - id: deployment uses: actions/deploy-pages@v4手順 3:astro.config.mjs に site を設定する
Astro では、astro.config.mjs の site プロパティにサイトの公開 URL を設定します。
export default defineConfig({ site: "https://username.github.io", // ...})site を設定することで次のことが正しく動作します。
- サイトマップの URL:
sitemap.xmlに記載される URL が正しいドメインになる - OGP タグ:SNS でシェアしたときに表示されるサムネイル・URL が正しくなる
Astro.site:テンプレート内でAstro.siteを使ってサイトの URL を取得できる
ユーザーページとプロジェクトページの違い
GitHub Pages には2種類の公開形式があります。
- ユーザーページ:リポジトリ名が
ユーザー名.github.ioの場合。URL はhttps://ユーザー名.github.io/になります(サブパスなし)。- プロジェクトページ:それ以外のリポジトリ名の場合。URL は
https://ユーザー名.github.io/リポジトリ名/になります。このサイトはユーザーページとして公開しているため、URL にサブパスが入りません。もしプロジェクトページとして公開する場合は、
astro.config.mjsにbase: '/リポジトリ名/'を追加する必要があります。この設定を忘れると、CSS・画像・リンクのパスが壊れ、デプロイ後に画面が真っ白になります。
手順 4:push してデプロイを確認する
ファイルを保存したら、リポジトリに push します。
git add .github/workflows/deploy.ymlgit commit -m "ci: add GitHub Actions deploy workflow"git push origin mainpush 後、GitHub のリポジトリページで Actions タブを開くと、ワークフローの実行状況を確認できます。
確認の手順:
buildジョブが黄色のスピナー(実行中)→ 緑のチェック(完了)に変わることを確認しますdeployジョブが完了したら、ログの最後に表示される URL をクリックします- サイトが正しく表示されれば成功です
両ジョブのアイコンが緑になれば、デプロイ完了です。
次回からはmainブランチにプッシュするだけで、このワークフローが自動で動きます。
トラブルシューティング
| 症状 | 原因 | 対処法 |
|---|---|---|
Permission denied でデプロイが失敗する | permissions の設定漏れ | pages: write と id-token: write を追加する |
| Actions タブにワークフローが表示されない | ブランチ名の不一致 | branches: [main] をデフォルトブランチ名に合わせる |
| CSS・画像が読み込まれない | base の設定漏れ(プロジェクトページの場合) | astro.config.mjs に base: '/リポジトリ名/' を追加する |
build が成功しても deploy が動かない | needs: build の記述漏れ | deploy ジョブに needs: build を追加する |
| 古いコンテンツが表示され続ける | ブラウザのキャッシュ | ハードリロード(Ctrl+Shift+R / Cmd+Shift+R)を試す |
configure-pages ステップでエラーが出る | Settings で Source が「GitHub Actions」になっていない | GitHub の Settings → Pages → Source を「GitHub Actions」に変更する |
| ビルドが成功するのにサイトが真っ白になる | site や base の設定が間違っている | astro.config.mjs の site プロパティを確認する |
ワークフローファイルの詳細解説
ここからは、deploy.ymlが何をしているのか知りたい人向けです。
name:ワークフローの名前
name: Deploy to GitHub PagesGitHubのActionsタブに表示される名前です。複数のワークフローを管理するときに区別できるよう、わかりやすい名前をつけましょう。
on:ワークフローをいつ実行するか
on: push: branches: [main] workflow_dispatch:ワークフローを起動するトリガーを定義します。
push: branches: [main]
main ブランチにpushがあったときに自動で実行されます。
workflow_dispatch:
GitHub のリポジトリページから、手動でワークフローを起動できるようにします。 設定を変えた直後など、pushせずにGitHubのUIから再実行したい場合に使えます。
permissions:権限の設定
permissions: contents: read pages: write id-token: writeGitHub Actions が何をできるかの権限を定義します。 デフォルトではリポジトリの読み取りしか許可されていないため、GitHub Pagesへのデプロイに必要な権限を明示的に追加します。
| 権限 | 意味 | なぜ必要か |
|---|---|---|
contents: read | リポジトリのファイルを読み取る | ソースコードを取得するため |
pages: write | GitHub Pages にファイルをアップロードする | デプロイ自体に必要 |
id-token: write | OIDC 認証トークンを発行する | GitHub が「このデプロイは正規のものか」を検証するために使用 |
pages: writeとid-token: writeの2つは省略するとPermission deniedエラーでデプロイが失敗します。 この3行はセットで必ず記述してください。
concurrency:同時実行の制御
concurrency: group: "pages" cancel-in-progress: false短時間に複数回 push した場合など、ワークフローが重複して起動したときの挙動を定義します。
たとえば、タイポを直すために2回連続でpushしたとします。 このとき2つのデプロイが同時に走ると、後から来たデプロイが先のデプロイを上書きしてしまうなど、 予期しない競合が起きることがあります。
group: "pages":同じグループ名のワークフローは、同時に1つしか動きません。cancel-in-progress: false:現在実行中のワークフローをキャンセルせず完了を待ちます。trueにすると後から来た push が優先され、実行中のジョブが中断されます。
jobs:実際に実行する処理
ここからが実際の処理の定義です。今回はbuildとdeployの2つのジョブに分かれています。
build ジョブ:ビルド処理
jobs: build: runs-on: ubuntu-latestruns-on: ubuntu-latest では、このジョブをどのOSで実行するかを指定します。
ここでは、GitHubが無料で提供するUbuntu Linuxの仮想マシンを使います。 ワークフローが起動するたびに、クリーンな状態の新しい仮想マシンが用意されます。
steps: - uses: actions/checkout@v4stepsはジョブ内の個々の処理です。上から順番に実行されます。
actions/checkout@v4はGitHubが公式に提供するアクションで、リポジトリのコードをランナーにダウンロードします。
このステップがないと、ランナー上にはファイルが何もない状態なのでビルドできません。
- uses: actions/setup-node@v4 with: node-version: "20" cache: "npm"Node.jsをランナーにインストールします。 with以下はアクションへのオプション(引数)です。
node-version: "20":Node.js のバージョンです。ローカル環境に合わせてバージョンを設定しましょう。cache: "npm":node_modulesの内容をキャッシュします。2回目以降のワークフロー実行ではnpm installがキャッシュから読み込まれるため、実行時間が大幅に短縮されます。
- uses: actions/configure-pages@v4GitHub Pages向けにビルド環境を設定するアクションです。
具体的には、Astro がビルド時に参照するサイトURLやベースパスを、GitHub Pagesの設定に合わせて環境変数として自動的にセットします。
このステップはnpm installやnpm run buildより前に置きましょう。
後に置いてしまうと、Astroがビルド時に正しいURL情報を取得できないため、リンクやアセットのパスがずれることがあります。
- name: Install dependencies run: npm installnpm installでpackage.jsonに記載された依存パッケージをすべてインストールします。
name は任意のラベルで、GitHub の Actions タブでステップ名として表示されます。
- name: Build with Astro run: npm run buildnpm run build(= astro build)を実行します。
Astroがすべての .astro ファイルや .md ファイルを処理し、最終的な HTML・CSS・JavaScript を dist/ フォルダに出力します。
- uses: actions/upload-pages-artifact@v3 with: path: ./distビルドで生成されたdist/フォルダをアーティファクトとしてGitHubに一時保存します。
アーティファクトとは、ジョブ間でファイルを受け渡すための一時的なストレージです。build ジョブと deploy ジョブは別々の仮想マシンで動くため、そのままではファイルを共有できません。アーティファクトを介することで、build ジョブの成果物を deploy ジョブに渡せます。
deploy ジョブ:デプロイ処理
deploy: needs: build runs-on: ubuntu-latest environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} steps: - id: deployment uses: actions/deploy-pages@v4needs: build
build ジョブが成功したときだけこの deploy ジョブを実行する、という依存関係を定義します。ビルドが失敗した場合はデプロイジョブはスキップされます。
environment
GitHub の Environments 機能と連携します。これを設定すると、Deployments タブに「どのコミットをいつデプロイしたか」の履歴が残り、公開 URL も GitHub UI 上に表示されます。${{ steps.deployment.outputs.page_url }} はデプロイ後の URL を取得するための変数です。
actions/deploy-pages@v4
build ジョブがアップロードしたアーティファクト(dist/ フォルダ)を取り出し、GitHub Pages に展開します。これがデプロイの本体です。
おわりに
.github/workflows/deploy.yml を1ファイル追加すれば、git push のたびにビルドとデプロイが自動で実行されます。最初の設定さえ終われば、記事を書いて push するだけで公開まで進みます。
さらに発展させたい場合は、以下を検討してみてください。
- 型チェックの追加:デプロイ前に
astro checkで TypeScript の型エラーを検出する - Lint の追加:ESLint や Biome でコード品質を自動チェックする
- プレビュー環境の生成:Pull Request ごとにプレビュー URL を自動発行する(Netlify / Vercel との連携など)
- 通知の設定:デプロイの成否を Slack や Discord に自動通知する
- スケジュール実行:
schedule: cronで毎朝定時に自動デプロイする(外部 API のデータを定期更新するケースなど)
参考
RELATED POSTS
コメント
GitHub Discussions のコメント欄は、開いたときだけ読み込みます。