2019年2月25日月曜日

GitHub Actions を試してみた





1ヶ月ほど前から使えるようになったので、ちょこちょこ弄ってました。

割と手こずったのでハマったところを書いておこうと思ったのですが、ちゃんとドキュメント読めよ。に落ち着いたので、ここに書くことはなくなりました。。。
ので、駄文です。

とりあえずやってみた
とりあえず、GitHub Actions でなにかをさせることができました。
「なにか」については、別途ブログにします。
今回は、GitHub Actions を使ってみた感想と、詰まったところを書きます。
使い方とかはすでに書かれている方も多いと思うので、ここでは書きません。


いろいろ手間取った
とりあえず、なにかさせることはできるようになったのですが、そちらは既存のアクションを使っています。最初、アクションを自分で用意してやっていたのですが、いきなり見よう見まねでやったのがよくなかったです。。。

サンプルリポジトリを用意して、ドキュメントを理解しながらやるべきでした。。。
https://github.com/srz-zumix/github_actions_sample


今後やりたいこと
GitHub Actions ならではなことができたらなーと思ってます。
ただ単に他の CI サービスと同じことをさせるのではなく、なにか便利なことができればなと。

では。

2019年2月19日火曜日

[Azure Pipelines] ファイルがなかった場合にステップをスキップする

Add an exists() on Task Custom Condition - Developer Community



とあるファイルがある場合にだけ実行する Job/Step が欲しくなったのですが、condition に簡単に書けたら嬉しかったのですが、今の所ない模様。

こんな感じできたら・・・
- script: |
    echo "xml がある場合にしたいこと"
  condition: exist('./test/*.xml')


状態を variable に記録して条件とする
ワンステップではできないものの、比較的簡単にやりたいことは実現できます。

condition で variables を参照してスキップさせることはできるので、ファイルが存在しない場合にスキップ用の variable をセットするようにしました。

- script: |
    TEST_RESULTS=`find ./test -maxdepth 1 -name *.xml 2>/dev/null`
    if [ $? -ne 0 ] || [ -z "$TEST_RESULTS" ]; then echo "##vso[task.setvariable variable=XmlFileNotExist]true"; fi

- script: |
    echo "xml がある場合にしたいこと"
  condition: ne(variables['XmlFileNotExist'], 'true')



この方法であれば、「ファイルが存在するかどうか」以外でも、条件付けできそうですね。

2019年2月12日火曜日

Windows + Git で実行権限をつけて commit する

何回かハマって、何回も調べ直してるので、記憶の定着・備忘録のために自分のブログにも書き残しておくことにした。

Windows + Git Bash では 644 で commit される
chmod +x としておいても commit したときに書き換えられます。
$ git commit -m 'sample action a'
[master e432bd4] sample action a
 4 files changed, 21 insertions(+), 4 deletions(-)
 create mode 100644 action-a/Dockerfile
 create mode 100644 action-a/README.md
 create mode 100644 action-a/entrypoint.sh

この状態でもう一回 chmod +x しても差分として出てこない。

git update-index --add --chmod=+x
パーミッションの変更は上記コマンドで行います。

しょっちゅう忘れるので alias にしました。
git config --global alias.addx 'update-index --add --chmod=+x'

これで、addx エイリアスから chmod +x できるようになりました。



+x/-x 両方に対応したエイリアス
せっかくなのでもう少し汎用的なエイリアスも用意しました。
git config --global alias.chmod '!f(){ cd ${GIT_PREFIX:-.} && git update-index --add --chmod=$1 ${@:2:($#-1)};};f'

git chmod +x hoge
git chmod -x foo bar
のように使えます。

2019年2月4日月曜日

.editorconfig ファイル自体の Lint を CI で回す



[*.{cpp,hpp,ipp}}
charset = utf-8-bom
単純な typo ですが、今までずーと気づかずに config が仕事してくれてると思い込んでました。。。
直すのは簡単です。簡単ですが、また同じ失敗をする可能性があります。(にんげんだもの)

というわけで、テスト書きました。

テスト方法
.editorconfig の記法は概ね ini ファイルと一致します。
なので、適当な ini ファイルパーサーに読み込ませてエラーが起きないかどうか?で検証できそうです。

iutest は C++ のテスティングフレームワークですが、ツール系には Python も使用しています。
Python には ConfigParser があるのでそちらでテストを書きました。

import sys
import os

try:
    from configparser import ConfigParser
except ImportError:
    from ConfigParser import SafeConfigParser as ConfigParser


class EditorConfig(object):
    def __init__(self, path):
        self.name = os.path.basename(path)
        self.fp = open(path)
        self.first_head = True

    def readline(self):
        if self.first_head:
            self.first_head = False
            return '[global]\n'
        return self.fp.readline()

    def __iter__(self):
        return self

    def __next__(self):
        line = self.readline()
        if not line:
            raise StopIteration
        return line

    next = __next__  # For Python 2 compatibility.


def main():
    path = sys.argv[1]
    ini = ConfigParser()
    if not os.path.exists(path):
        sys.stderr.write('%s not found...' % path)
        sys.exit(2)
    ini.readfp(EditorConfig(path))
    sys.exit(0)

if __name__ == '__main__':
    main()

基本的には ini ファイルをパーサーにかけるだけなんですが、1点だけポイントがあります。
EditorConfig は、ディレクトリを上がって .editorconfig を探索しますが、root = true を最初に書いておくとそこで探索が打ち切られます。
この root = true が ini ファイルとしてはセクションのない要素のためエラーになってしまいます。
そのため、最初に [global] というダミーセクションを挿入して ConfigParser に渡してます

CI に組み込む
Python が実行できる CI サービスであればなんでも問題ありません。
今回 iutest では Codeship で cpplint やインクルードガードのチェックや絶対パスが混入してないかの、雑多なテストを行っているのでそちらに組み込みました。



こんな感じに検出されます!
これでもう安心ですね。