Circle CI では様々なビルドが可能となるため、 HexoJekyll など静的なサイトジェネレーターを使用して Web ページを生成することが可能となります。 もちろん、サイトジェネレーターを使用せずとも静的ページをホスティングすることも可能です。

更に、そのビルド結果を GitHub Pages で Web ページを公開するための自動デプロイを行うことが可能となります。

これらは全て無料で行えるため、お財布にも優しいです。

GitHub Pages

GitHub PagesGitHub が提供している、GitHub 上のリポジトリにアップされたコンテンツを利用して Web ページとして公開することができるホスティングサービスです。

また、カスタムドメインも使用でき、更には 2018 年 5 月にカスタムドメインの HTTPS での配信がサポートされました。

private リポジトリも GitHub Pages が使用できますが、指定した配下以下は全て公開されてしまうため、 くれぐれも公開の際にはご注意ください。

このブログも GitHub Pages を使用しています。

ドメイン名

個人リポジトリは [user name].github.io、組織アカウントは [organization name].github.io/リポジトリ名 となります。

また、 CNAME ファイルを用意して中身に独自ドメインを記載すると独自ドメインの設定が可能となります。

Circle CI

Circle CI は、継続的インテグレーションサービスです。 継続的な統合や配信が可能となり、ソフトウェア開発プロセスを自動化することができます。

1 Container が無料で使用でき、1 Container 増設毎に $50/月 かかります。 また、GitHub や Bitbuket と柔軟に連携が可能であり、 private リポジトリの区別もありません。

GitHub Pages をデプロイする際には 1 Container で十分なため、無料で始めることが可能です。

公開方法の選択

GitHub Pages は

  • master ブランチ配下を全て公開
  • master ブランチの docs ディレクトリ以下を全て公開
  • gh-pages ブランチ配下を全て公開

のどれかを 1 つ選択することが可能です。

つまり、公開する方法を選択したら、それに応じてブランチまたはディレクトリ配下にビルド成果物を入れて、 GitHub のリポジトリに push することで Web ページを公開することができます。

ご自身のユースケースにマッチする方法を選択しましょう。

リポジトリに mastergh-pages ブランチが存在しない場合は、該当する公開方法が選択できないようになっています。

公開タイミングの選択

公開タイミングも人それぞれですが、大きく分けて以下から選択することとなります。

  1. 選択した公開方法のブランチまたはディレクトリに、直接成果物を push する方法
  2. GitHub のイベントを利用し、成果物をビルドして、選択した公開方法のブランチまたはディレクトリに push する方法
  3. Circle CI の API を呼び出し、成果物をビルドして、選択した公開方法のブランチまたはディレクトリに push する方法

パターン 1: 選択した公開方法のブランチまたはディレクトリに、直接成果物を push する方法

この方法はビルド環境がローカルにある必要がありますが、公開タイミングを自分で選択することができ、かつ CI を使用なくても実現できます。

しかし、複数人でメンテナンスを行う場合は、全員が同じ環境でビルドを行う保証がなく、下書きなど公開前の管理が難しくあまり向いていません。

パターン 2: GitHub のイベントを利用し、成果物をビルドして、選択した公開方法のブランチまたはディレクトリに push する方法

この方法はビルドをローカル環境で行わずよく、公開前にテストなど様々なビルドが可能となります。

この中でも一般的に多く取られる方法は、 「とあるブランチに merge されたら、選択した公開方法のブランチまたはディレクトリに push する」です。

パターン 3: Circle CI の API を呼び出し、成果物をビルドして、選択した公開方法のブランチまたはディレクトリに push する方法

この方法は GitHub のイベント以外を利用したい場合、例えばチャットボットなどで取られることが多い方法です。

もちろんビルドをローカル環境で行わずよく、公開前にテストなど様々なビルドが可能となります。 また、任意のタイミングで公開ができるのも大きな強みです。

公開の準備

例として以下の方法とタイミングで VuePress で作成した静的ページを公開するようにしてみます。

今回使用しているサンプルはこちらです。

公開方法 公開タイミング
master ブランチの docs ディレクトリ以下を全て公開 GitHub のイベントを利用し、成果物をビルドして、選択した公開方法のブランチまたはディレクトリに push する方法

VuePress の成果物の生成先の変更

VuePress はデフォルトで .vuepress/dist にビルドされます。 しかし、 config.jsdest を設定することで、ビルド先を変更できるようになります。

今回はこの destdocs/ を指定することにします。

// src/.vuepress/config.js

const title = 'GitHub Pages VuePress Sample!';
const description = 'Just play VuePress for kenchan0130 blog.';

module.exports = {
  title: title,
  description: description,
  dest: 'docs/'
};

これで vuepress build のビルド先が docs/ になりました。

Circle CI の設定

Circle CI で build を行うので、.circleci/config.yml にビルドの設定を記述していきます。

version: 2

jobs:
  build:
    working_directory: ~/github-pages-vuepress-example
    docker:
      - image: node:9.11
        environment:
          TZ: "/usr/share/zoneinfo/Asia/Tokyo"
          LANG: ja_JP.UTF-8
          LC_ALL: C.UTF-8
          LANGUAGE: ja_JP.UTF-8
          DEPLOY_BRANCH: master

    steps:
      - checkout

      #### Node dependencies ####
      - restore_cache:
          keys:
            - yarn-packages-{{ .Branch }}-{{ checksum "yarn.lock" }}
            - yarn-packages-{{ .Branch }}
            - yarn-packages-master
            - yarn-packages-

      - run:
          name: Install Node dependencies
          command: yarn install

      - save_cache:
          paths:
            - node_moduels
          key: yarn-packages-{{ .Branch }}-{{ checksum "yarn.lock" }}
      #### Node dependencies end ####

      - run:
          name: Deploy development branch to master
          command: |
            if [ "${CIRCLE_BRANCH}" = "${DEPLOY_BRANCH}" ]; then
              chmod +x deploy.sh
              ./deploy.sh
            fi

steps が実際に行っている処理です。具体的には、

  1. working_directory に設定したディレクトリに対象のコミットをチェックアウト
  2. キャッシュの呼び出し
  3. node の依存をインストール
  4. node_moduels をキャッシュ
  5. 今ビルドしているブランチが master だったらデプロイスクリプト( deploy.sh )を走らせる

を行っています。

今回のポイントは「今ビルドしているブランチが master だったらデプロイスクリプト( deploy.sh )を走らせる」です。 これにより、 master に変更があった時のみデプロイが行われます。

デプロイスクリプトの用意

Circle CI のビルド設定で deploy.sh を走らせるようにしましたが、ここでは実際にその中身を用意します。

#!/bin/bash -e

# build
yarn run --silent build

if [ "$(git status --porcelain | wc -l | xargs)" -eq 0 ]; then
  echo "Not exist deploying contents."
  exit 0
fi

git config --global user.name "Circle CI"
git config --global user.email "<>"
git add -A
git commit -m "[ci skip] Deploy by CI"

git push -f $(git config --get remote.origin.url) master:master > /dev/null/ 2>&1

echo "Deploy a site!"

cd -

やっていることは単純で、

  1. VuePress のビルド
  2. デプロイ内容物かあるかの確認
  3. ビルド結果をコミット
  4. GitHub のリモート master ブランチにコミットを push

を順に行っています。

重要なのはコミットメッセージに [ci skip] を含めていることです。

このコミットがマージされた際のビルドでは CI が走りません。 もし CI を走らせてしまうと、無限にデプロイ処理が行われてしまいます。

他にも Slack 通知など行うなど、ご自身で自在にカスタマイズが可能です。

Circle CI の連携

Circle CI と連携されていないと GitHub のリポジトリにコミットをプッシュしてもビルドは走りません。 まずは Circle CI にログインをします。

プロジェクトの追加を選択して、今回連携したいリポジトリを選択して Set Up Project をクリックします。

Circle CI のプロジェクトの追加

ビルドの設定方法などが記載されていますが、もう既に設定済みなので Start building をクリックするだけです。

Circle CI のプロジェクトの設定

これで、リポジトリに変更があるたびに Circle CI のビルドが走るようになります。

GitHub Pages の公開

master ブランチの docs/ ディレクトリに成果物がプッシュされるようになったので、 git リポジトリの Settings より、 GitHub Pages の公開方法を指定します。

GitHub Pages 公開方法選択

今回は関係しませんが、カスタムドメインを設定する場合、 「 master ブランチの docs ディレクトリ以下を全て公開」を選択していると、 CNAME ファイルは docs/CNAME に設置する必要があります。

ディレクトリルート直下に CNAME ファイルを設定しても反映されません。 意外とハマりどころなのでご注意ください。

まとめ

GitHub Pages を Circle CI を使用してデプロイする方法を紹介しました。

公開方法と公開タイミングをどう選択するかで、 若干 Circle CI の設定やデプロイスクリプトの内容が変わりますが、 基本的にやることは変わりません。

GitHub Pages と Circle CI でお手軽にかつ、お金をかけずに静的サイトホスティングしていきましょう!