Github Actions を使って dotfiles の CI を Ubuntu/macOS 上で実行する
dotfiles とはホームディレクトリに置かれたいろいろな設定ファイル (.zshrc とか .vimrc とか) を管理するリポジトリのこと。 Github で自前の dotfiles を公開しているエンジニアの方も多いだろう。
私も1年ほど前に自前の dotfiles リポジトリを作成して 各種設定ファイルとそれらの設置スクリプトを用意していたのだが、 それっきり未メンテという状態で、設置スクリプトはテスト不十分で動かないというありさまだった。
ところで最近家の MacBook Pro の調子が悪くて買い替えを決めた。 新しい MacBook Pro での環境構築に向けて dotfiles をメンテすることにした。
メンテが完了したリポジトリはこちら。
Ansible による構成管理
これまでは shellscript で zsh や neovim のインストールスクリプトを用意していたが、 仕事で Ansible を触っていることもあり、Ansible による構成管理に切り替えることにした。
Ansible のタスクを実装するにあたっては冪等性を意識した。 以下は zsh をインストールする例。
Ansible の apt モジュールのように対象がインストール済みか判定する機能があればそれを利用し、 apt などでインストールできない場合は stat モジュールなどを使って自前でインストール済みかチェックをしている。
- name: Install zsh and zplug dependencies using aptbecome: yesapt:pkg:- gawk- zshstate: presentupdate_cache: yeswhen: ansible_os_family == "Debian"- name: Check zplug existencestat:path: ~/.zplugregister: zplug- block:- name: Download zplug installerget_url:url: https://raw.githubusercontent.com/zplug/installer/master/installer.zshdest: /tmp/zplug_installer.zsh- name: Install zplugcommand: zsh /tmp/zplug_installer.zshwhen: not zplug.stat.exists
各設定ファイルの設置も ansible で実行するようにした。
- name: Create dotfiles symbolic linksfile:src: "{{ playbook_dir }}/{{ item.name }}"dest: "{{ item.dest }}"state: linkloop:- { name: .zshrc, dest: ~/.zshrc }- { name: .zshenv, dest: ~/.zshenv }- { name: .vimrc, dest: ~/.vimrc }- { name: .vimrc, dest: ~/.config/nvim/init.vim }- { name: .tmux.conf, dest: ~/.tmux.conf }
Github Actions による CI
テストは bash ベースのテストフレームワークである bats を利用することにした。
Jest などのよくあるテストフレームワークのような書き味でテストを実装することができる。
#!/usr/bin/env bats@test ".zshrc is present" {run ls ~/.zshrc[ "${status}" -eq 0 ]}
Github Actions では上記のようなテストと、 ansible-lint と shellcheck による静的解析を macOS と Ubuntu 上でそれぞれ実行している。
name: macoson:push:branches:- master- feature/*- dependabot/*jobs:test:runs-on: macos-lateststeps:- uses: actions/checkout@v2- uses: actions/setup-python@v2with:python-version: 3.7architecture: x64- name: Prerequisitesrun: |pip install -r requirements.txtgit clone https://github.com/sstephenson/bats.git && sudo bats/install.sh /usr/local- name: Installrun: |make install- name: Deployrun: |make deploy- name: Testrun: |make test- name: Lintrun: |make lint
また、push する前にローカルで CI が通るか確認したかったため、 ローカルにクリーンな docker コンテナを用意し、 コンテナ上で ansible による各ツールのインストールや設定ファイルの設置を実行した後、 各種テストや静的解析を実行するようにした。
ローカルで Github Actions をエミュレートする act というツールも見つけたのだが、 dotfiles リポジトリ自体の依存のダウンロード処理(上記 yaml の Prerequisites の部分)に毎回数分かかりストレスがたまるため、 以下のように依存を予めインストールした docker コンテナ上で確認する方式を採用した。
FROM ubuntu:20.04RUN apt update && apt install -y \aptitude \git \make \python3.8 \python3-apt \python3-pip \sudo \&& rm -rf /var/lib/apt/lists/*RUN git clone https://github.com/sstephenson/bats.git \&& bats/install.sh /usr/local \&& rm -rf batsCOPY requirements.txt ./RUN python3 -m pip install -r requirements.txt
感想
早速上記を使って、会社で使っている WSL2 の Ubuntu 上に環境構築をした。 毎回同じ方法で環境構築できるのは非常に安心感がある。
今後は設定ファイル自体の見直しをしてゆきたい。