こんばんは。インサイトテクノロジー札幌R&Dセンターの笹谷です。
好きなボトラーはモリソン&マッカイとエリクサーディスティラーズ、好きなカスクタイプはEXバーボンカスクとPXカスクです。
業務ではGitlabを用いたCI/CDの構築、開発部門の業務プロセスの改善タスクを担当しております。
前回は、Gitlabが持つCI/CDの機能であるGitLab CI/CD
について、基本的な使い方と最小限の例についてお話しました。
今回はその続きで、実践編と称し、GitLab Pages
と組み合わせることで、
- テストのcoverageをHTMLを公開
- markdown文章をHTMLに変換して公開
する流れについてそれぞれお話します。
シーン1: テストのcoverageのHTMLを公開する
概要説明
ローカルのgit repositoryからGitlabのremote repositoryへのpushをトリガに、ドキュメントをホストするjobが動きます。
jobの内部では、
- pytestを実施、code coverageをHTML出力
- 出力されたHTMLを
GitLab Pages
の仕組みで公開
の2つがそれぞれ実行されています。
ディレクトリ構成
GitLab CI/CD
をお試しするために、最低限必要なレポジトリのディレクトリ構成は以下です。
main/以下のtestをするtest/以下があり、pytest実行時にpytest-covを使い、
pytestの実行結果からcoverageを算出し、HTMLで出力します。
job内でpublic/という名前でディレクトリを作成し、そちらに上記で出力されたcoverageの結果をコピーし配置します。
以下のツリーの点線以下はそれを示しています。
sample-repository/
├── .gitlab-ci.yml
├── main/
│ ├── module.py
│ └── main.py
│
├── tests/
│ ├── pytest/
│ │ ├─── test_module.py
│ │ └─── test_main.py
│ ├── coverage/
│ │ └─── coverage.html
│ └── coverage_utils/
│ └─── heatmap.js
:
:
└── public/
└── coverage/
└─── coverage.html
.gitlab-ci.yml
GitLab CI/CD
の設定ファイルは以下のように記述します。
# .gitlab-ci.yml
stages:
- test
- deploy
unittest-master-with-coverage:
stage: test
script:
- pip install pytest-cov==2.10.0
- pytest -v ./tests/ --cov-report html:cov_html --cov-report term --cov=.
# - ここで一部生成されたhtmlにheatmap.jsが使えるようsedで追記する行を入れる
- mkdir coverage/
- cp -R cov_html/ coverage/
- mv coverage/cov_html coverage/coverage
- cp tests/coverage_utils/heatmap.js coverage/coverage
artifacts:
paths:
- coverage/
rules:
- if: '$CI_COMMIT_REF_NAME == "master"'
when: on_success
- when: never
pages:
image: centos:7.7.1908
stage: deploy
dependencies:
- unittest-master-with-coverage
script:
- mv coverage/ public/
artifacts:
paths:
- public/
# pages上のartifactsを期限付きで削除する場合コメントを外す
# expire_in: 30 days
rules:
- if: '$CI_COMMIT_REF_NAME == "master"'
when: on_success
- when: never
GitLab Pagesについて:
上記jobの設定の説明に入る前に、job内で利用しているGitLab Pagesについてお話します。
かいつまんで言うと、”GitLab CI/CD
の枠組みから利用できる、静的サイト公開機能”です。
静的サイトを気軽に公開する仕組みとしては、GitHub Pagesや、Netlifyなどがありますね。
Netlifyは、それ自身がリモートレポジトリを有していないため、GitHubと連携した上で、変更が加えられると都度更新する点で、GitLab Pagesとは(GitHub Pagesとも)大きく異なります。
また、GitHub Pagesは、リモートレポジトリを有しているのは同様ですが、GitHub Pages上で、特定のディレクトリ以下を対象にGitHub Pagesで公開する、というような、設定変更だけで静的ホストを公開できるポイントです。
対して、GitLab Pagesは、設定変更だけでリモートレポジトリから静的サイトの公開ができるわけではありませんが.gitlab-ci.yml
に正しい設定を加え、リモートレポジトリへのpushやWeb UI上での操作をトリガにCIを実施することで、静的なHTMLサイトが公開できます。
もちろん、GitHub Pagesでも、GitHub Actionsと組み合わせることで、GitLab Pagesと同様のことが可能です。 (参考:GitHub Actions for GitHub Pages)
GitHub Pagesは、既存のレポジトリのHTMLから静的サイトを公開できる手軽さと、GitHubActionsと連携することによりCI/CDも可能になるフレキシブルな点が長所です。
一方、GitLab Pagesは、デフォルト使用の時点で、公開する静的サイトについての設定がコード化され、リモート/ローカルレポジトリ自身で管理できる点が長所と言えるでしょう。
説明
それでは設定内容の説明に戻ります。
stages:
では、test
に関するjobとdeploy
に関するjobの2種類を使う設定をし、実行順序をtest -> deploy
の形で定義しています。
(.yml上の記述に関する詳細な説明は、前回をご参照ください。)
unittest-master-with-coverage:
は、master
branch へのmergeをトリガに、coverage付きのtestが実施され、結果が入ったcoverage/
ディレクトリをartifactsにuploadします。
pages:
は、先述したGitLab Pages
の設定の具体例にあたります。 unittest-master-with-coverage:
jobで出力され、pagesのartifactとしてディレクトリに出力されたcoverage.htmlを、publicディレクトリ以下に配置し、jobを実行することで、coverage.htmlが公開されます。
ここで注意が必要なのは、
GitLab Pages
に静的サイトを公開するためのjob名はpages
でなければならないGitLab Pages
に静的サイトを公開する対象ディレクトリのrootはpublic
でなければならない
以上の2点です。
ちなみに、artifactsにuploadするだけであれば、job名もroot dir名も任意のものが設定可能ですが、artifacts単体では、個別のファイルをブラウザ上で確認できるだけで、ページ遷移などはできないようです。
成果物
こうして、GitLab Pages
を利用することで、testのcoverageは以下のようなイメージでチームメンバーに公開されます。
ちなみに、pytest-cov単体ではgcovのように色分けされないので、元のcoverage.htmlにjsをちょっと噛ませています。
備考
なお、GitLab Pagesを利用した静的サイトの公開範囲は、Setting -> General -> Visibilityから、Pagesの項目において、プルダウンにて設定できます。デフォルトはレポジトリにアクセス可能なメンバー限定になっています。
シーン2: markdown文章をHTMLに変換して公開
概要説明
ローカルのgit repositoryから、Gitlabのremote repositoryへのpushをトリガに、ドキュメントをホストするjobが動きます。GitLab CI/CD
では、特定のディレクトリ(ここでは)docs以下への変更を含むpushを対象にjobが動くよう、ymlファイルで設定します。
jobの内部では、
- 指定ディレクトリ以下に差分があった場合、
*.md
に対し、mkdocsを実行し、Markdown文章をHTML変換する - 出力されたHTMLを
GitLab Pages
の仕組みで公開
の2つがそれぞれ実行されています。
ディレクトリ構成
GitLab CI/CD
をお試しするために、最低限必要なレポジトリのディレクトリ構成は以下です。
変換対象は、docs/markdown/
以下で、後ほどご紹介する.gitlab-ci.yml
にて、docs
ディレクトリ以下に変更があった場合のみ、mkdocsによるHTML変換が実施されたものを、シーン1と同様、public
ディレクトリ以下に配置し、GitLab Pagesの仕組みで静的サイトを公開するイメージとなります。
sample-repository/
├── .gitlab-ci.yml
├── docs/
│ ├── mkdocs.yml
│ └── markdown/
│ ├── README.md
│ ├── requirements.md
│ └── specification.md
│
:
:
└── public/
└── markdown/
├──README.HTML
├── requirements.HTML
└── specification.HTML
.gitlab-ci.yml
GitLab CI/CD
の設定ファイルは以下のように記述します。
# .gitlab-ci.yml
# 実行するjobをカテゴライズ
stages:
- test
- deploy
before_script:
- pip install -r docs/requirements.txt
- pip install mkdocs-material
# test jobでuploadされたartifactsをbrowseすることで.mdから生成されたhtmlを確認する
test:
image: python:3.8-buster
stage: test
script:
- cd docs/
- mkdocs build --strict --verbose --site-dir test
- cd ../
- cp -r docs/test ./test
- cp -r docs/data ./test/data
- cd test && ls -al
# artifact/testディレクトリ
artifacts:
paths:
- test
rules:
- if: $CI_MERGE_REQUEST_ID
when: never
- if: '$CI_MERGE_REQUEST_EVENT_TYPE == "detached"'
when: never
- changes:
- "docs/*"
- "docs/markdown/*"
- "docs/markdown/**/*"
if:$CI_COMMIT_REF_NAME == "master"'
when: never
- changes:
- "docs/markdown/*"
- "docs/markdown/**/*"
- "docs/*"
when: on_success
# Pagesへのdeployのjob定義
pages:
image: python:3.8-buster
stage: deploy
script:
# mkdocsの設定ファイルはひとまずdashboard prjのものを一括して利用する形
# 指標の反映もAPIcallのタイミングと合わせる設定
- cd docs/
- mkdocs build --strict --verbose --site-dir public
- cd ../
- mkdir public/
- cp -r docs/public ./public/documents/
- cp -r docs/data ./public/data
- cd public && ls -al
artifacts:
paths:
- public/
rules:
- if: $CI_MERGE_REQUEST_ID
when: never
- if: '$CI_MERGE_REQUEST_EVENT_TYPE == "detached"'
when: never
- changes:
- "docs/*"
- "docs/markdown/*"
- "docs/markdown/**/*"
if: '$CI_COMMIT_REF_NAME == "master"'
when: on_success
説明
stages:
では、シーン1と同様に、test
に関するjobとdeploy
に関するjobの2種類を使う設定をしています。
tests
およびpages:
のmkdocs build --strict --verbose --site-dir ****
の部分で、mkdocsを使い、指定したディレクトリにmarkdownからHTMLを生成しています。これ以降に関しては、artifactsにuploadする、あるいはGitLab Pages
でHTMLを公開するための処理です。
最後にrules:
節ですが、この節のchanges:
で、「docs
ディレクトリ以下に変更があった場合」、「masterへのpush時以外のタイミングに」(test job)または「masterへのpush時に」(pages job)jobが動くように制限しています。
成果物
mkdocsがmarkdownからHTMLに変換してくれたものは、以下の画像のようにGitLab Pages
で公開されます。
備考
rules:
- if: $CI_MERGE_REQUEST_ID
when: never
- if: '$CI_MERGE_REQUEST_EVENT_TYPE == "detached"'
when: never
上記のrules:
直下の2つのif:
節は、特定条件下でjobが二重に動く問題に暫定的に対処するための記述です。
終わりに
今回は実践編として、GitLab Pages
の仕組みを使って、テスト結果のcoverageと、markdownをベースにしたHTMLを公開する流れをご紹介しました。
次回はGitlabRunnerの使い方をメインに投稿いたします。