ローカルファイルに記載した日付と一致するかどうかを判定して、祝日などにCIをスキップできるシンプルなPythonスクリプトの実装方法と使用方法を記載します。
背景
現在CIで使用しているクラウドサービス上のVMは、稼働時間で課金されるため、休日や祝日などの使用しない日は起動させたくない。しかし、クラウドサービスで設定できるのは、土日などの決まった曜日だけなので、祝日や特定の日付などに起動をスキップできなかった。
内閣府のデータを使用して祝日かどうかを判定できるメンテナンスフリーなツールを公開してくださっている方がすでにいますが、会社独自の休日への対応や、外部のネットワークに依存せずに祝日を判定したかった。
そこで、オフラインで判定できるスクリプトを作成しました。
動作確認環境
- python 2.6.6, 3.7.1
- CentOS release 6.8
- Windows 10 version 1809
実装方法
以下のisholiday.py
とholidays.txt
を同一ディレクトリに配置します。
"""
Check whether holiday or not based on holidays.txt.
"""
import sys, os
def get_holidays_list():
holidays_list = []
target_path = os.path.join(os.path.dirname(__file__), 'holidays.txt')
with open(target_path, 'r') as f:
for row in f:
holidays_list.append(row.strip())
return holidays_list
def is_holiday(date):
if date in get_holidays_list():
return True
else:
return False
if __name__ == '__main__':
if len(sys.argv) >= 2:
if is_holiday(sys.argv[1]):
print("It's a holiday!")
sys.exit(0)
else:
print("It's a business day!")
sys.exit(1)
else:
print('Usage: python isHoliday.py `date --iso-8601`')
sys.exit(2)
2018-07-16
2018-09-17
2018-09-24
2018-10-08
2018-11-23
2018-12-24
2018-12-31
2019-01-01
2019-01-02
2019-01-03
2019-01-14
2019-02-11
2019-03-21
使用方法
python isholiday.py <日付>
<日付>はYYYY-MM-DD形式で指定します。
例:
python isholiday.py `date --iso-8601`
実行した日がholidays.txt
に含まれている場合は終了コード0
を、
含まれていない場合は1
を返します。
CIから呼び出す場合:
#!/bin/sh
python /path/to/isholiday.py `date --iso-8601`
if [ "$?" = "0" ]; then
echo "Skip holiday!"
exit 0
fi
新しい祝日を追加する方法
holidays.txt
にYYYY-MM-DD形式で追加してください。
不要な行は削除してしまって構いません。
注意:
2018-07-16
の行は後述のテストで使っているため、削除してしまうと、テストが失敗します
テストの実行方法
python -m unittest tests.py
import unittest
import isholiday
class TestGetHolidaysList(unittest.TestCase):
def test_file_read(self):
self.assertTrue(len(isholiday.get_holidays_list()) > 0)
class TestIsHoliday(unittest.TestCase):
def test_holiday(self):
self.assertTrue(isholiday.is_holiday('2018-07-16'))
def test_not_holiday(self):
self.assertFalse(isholiday.is_holiday('2018-07-17'))
if __name__ == '__main__':
unittest.main()
問題点
この実装方法では、毎年holidays.txt
を更新する必要があります。そのため、部署異動などでメンテナンスする人がいなくなったりすると、CIをスキップできなくなります。(可能な限りシンプルに実装していますので、後任の方への引き継ぎは比較的容易だと思います)