2020年11月26日木曜日

[C++] -Weverything で得たもの


こちらで紹介した C++ 警告のまとめプロジェクトの作成にあたって、自作テスティングフレームワークの iutest で clang のすべての警告を有効にするオプション「-Weverything」を使って得た知見をまとめます。

-Wdouble-promotion

double 型テストしてたつもりが float になってたのに気づきました。

-Wextra-semi

なぜか二重についてた ; セミコロンに気づきました。

-Wnonportable-system-include-path

Windows 系のヘッダーが全部小文字だったのを修正しました。

-Wshadow-all

マクロ内で使っていた変数名が b とか info とかかぶりやすい名前だったのを修正しました。

-Wdocumentation-unknown-command

こちらはワークアラウンドの紹介になりますが、 Clang は Doxygen のコメントに対しての警告がありますが、対応していない Doxygen コマンドが存在します。

Diagnostic flags in Clang — Clang 12 documentation

その場合、コンパイルオプションに -fcomment-block-commands=private,internal,retval のようにコマンドを教えてあげることができます。
ただし、引数のない private や internal コマンドは別の -Wdocumentation 警告がでるようになってしまいます。

../include/internal/iutest_time.hpp:47:13: error: empty paragraph passed to '@internal' command [-Werror,-Wdocumentation]
 * @internal
   ~~~~~~~~~^

こちらの回避方法はまだ見つけてないので、見つけたら追記します。

以上。


2020年11月16日月曜日

[CI] TeamCity Cloud OpenBeta を使ってみた

 TeamCity のクラウドサービスが始まるようでそのオープンβがやっていたので使ってみました。
TeamCity Cloud



一般リリースは年内を予定しているようです。
登録
まずは TemaCity Cloud にアカウント登録しましょう
トップページからインスタンス名と登録するメールアドレスを記入して「Sign Up」を押し、インスタンスの招待状が届くのを待ちます。



招待状が届いたら、アカウント登録に進みます。
今回は GitHub アカウントで登録します。特に気をつけることなく進めて OK です。

利用規約に同意したら登録完了です。





プロジェクト作成
アカウント登録できたら、最初に決めた「インスタンス名.beta.teamcity.com」が開きます。
ダッシュボードが出るのでプロジェクトを作成しましょう。




GitHub のリポジトリ一覧が出るので CI したいリポジトリを選択します。
今回は C++ 自作テスティングフレームワークの 「iutest」を選択します。
選択すると verify が始まるので少し待ちましょう。



verify 完了すると以下の画面になるので、名前を決めて Proceed します。

ビルドステップの設定では、リポジトリを解析してビルドコンフィグらしきものを自動で収集してくれます。
ビルドスクリプトなどがあればリストアップされるので、ビルドしたいコンフィグを選択しましょう。



iutest は複数プロジェクトファイルがリポジトリに入ってるのでたくさん出てきました。
ビルドコンフィルを選択すると自動でビルドステップが作成されます。
この時点でテスト実行可能になります。

特にない場合は手動でビルドステップを設定します。

iutest では最初 VS2019 のプロジェクトを選択したのですが、 "Microsoft.Cpp.Default.props" がなくてビルド失敗してたので、別のテストをするようにしました。
次の項目で設定した手順をまとめます。

Google Test 互換性テストを構築する
今回ちょうど Wercker でやっていた Google Test 互換性を引っ越したいと思っていたので、そちらを移植したいと思います。

Google Test 互換性テストでは Google Test セットアップ済みの Docker image を使って、ビルドとテストを行います。任意の Docker コンテナ上で処理をする方法が複数あるので紹介します。

Docker runner を使う方法
Docker runner でビルドステップを作成します。
「Runner type」 に「Docker」を選択し、 「Docker command」は「other」を選択します。「Command name」は「run」です。

あとは「Additiona arguments for the command」に docker run コマンドの引数を設定します。 チェックアウトディレクトリが「%system.teamcity.build.checkoutDir%」なのでそこをマウントしましょう。
また Docker run コマンドは実際にはラッパーを経由するようで、「--rm」オプションをそのラッパーが必ずつけるので不要なようです。

Command Line runner を使う方法
Command Line runner でビルドステップを作成します。
「Runner type」 に「Command Line」を選択し「Run step within Docker container」にイメージを設定します。
あとはやりたい処理を「Custom script」に書くだけです。
(「Additonal docker run arguments」に docker run のオプションを設定できるので、Docker runner と同等に使えると思います)

複数の処理を行う場合は Command Line runner を使ったほうが良さそうです。

設定は以上です。
これで Docker イメージを使ってビルド・テストの準備ができました。
プルリクエストでトリガーする
TeamCity Cloud では他の CI サービスと違ってデフォルトでは PR をトリガーにジョブがキックされません。「Build Features」で設定を追加する必要があります。

プロジェクト設定の「Build Features」を開いたら Add します。
Features に「Pull Requests」があるので選択し、必要な項目を設定しましょう。
「VCS Root」に GitHub のリポジトリを選択
「VCS hosting type」を「GitHub」にすると追加の設定項目が出てきます。

「Token」は GitHub で Personal Access Token を作って設定します。
権限は「public_repo」もしくは「repo」が必要になります。
iutest は public なので「public_repo」権限のトークンを設定しました。
「public_repo」の場合はコミットステータスにレポートするためには「repo:status」も必要になるので注意してください。

「By authors」で対象とする PR の範囲を設定します。
iutest では特に制限必要ないので「Everybody」を設定。


以上で設定完了です。「Test connection」で接続確認したら Save しましょう。 
これで PR が来るとビルドが実行されるようになりました。
また、GitHub のコミットステータスに結果を表示するには「Build Features」に「Commit status publisher」を追加してください。こちらも Personal Access Token が必要です(同じトークンで問題ないです)。


設定の仕方は公式ブログでも紹介されています。そちらも参考にしてみてください。

DockerHub login
DockerHub の pull 制限に対応するためにログインしておきます。
まずは、プロジェクト設定の「Connections」で「Docker registry」を選択して「https://docker.io」のアカウントを登録します。(パスワードはアクセストークンで ok)
接続確認して保存しましょう。


続いて、「Build Features」で「Docker Support」を追加します。
レジストリに先程接続した設定を追加しましょう。

設定は以上です。
バッジ
では、パイプラインが完成したのでバッジをつけましょう。
Markdown の場合は以下のようになります。
[![TeamCity Cloud Build Status](https://iutest.beta.teamcity.com/app/rest/builds/buildType:Iutest_GoogleTestCompatibleTest/statusIcon?guest=1)](https://iutest.beta.teamcity.com/viewType.html?buildTypeId=Iutest_GoogleTestCompatibleTest&guest=1)
このままだと自分以外はステータスが見られないので、ゲストアカウントにログイン権限をつけます。「Administration」の「Authentication」に「Guest user login」の項目があるのでチェックを入れましょう。


このように表示されます。

※ブランチごとに表示をしたかったのですがサーバーの設定が必要なようなのでクラウド版では現状できなそうでした。

改善したいところ
TeamCity Cloud で現状可能かわかりませんが以下の対応ができると嬉しいなと思ってます。

* Matrix Build
現状バージョン違いのビルドステップをコピーしているが、マトリックスにしたい。

* as Code

最後に
TeamCity は他の CI as a Service と比較すると設定することが多い印象でした。
その分拡張性も高い感じがするので、Jenkins おじさんを少し思い出しました。
ただ、オンプレではなくクラウド版でどこまで拡張して使えるのかはわからないのと、まだオープンベータであり、料金体系や制限がどうなってくるかが気になるところです。

とはいえ、一般リリースまでまだ少し期間があるのでそれまで使わせていただこうと思います。
一般リリースされたら、パイプラインをより精査していきたいと思います。
では。

2020年11月10日火曜日

Travis CI の新プランについて

 The Travis CI Blog: The new pricing model for travis-ci.com

Travis CI の新しい料金プランが 2020/11/02 より始まり、あっという間にクレジットを使い切りました。


新しいプランでは 10,000 クレジットが毎月与えられ、それを消費するスタイルですが、圧倒的に足りない・・

こちら↑はブログからの抜粋ですが、マイニングとかに悪用されたのが理由のようです。
制限かかっても仕方がないな…とは思います。
が、今まで CI サービスの中でも制限ゆるい方だったのが、一気にキツめの部類になったので辛いですねぇ…
まぁ、今まで無料だからと気にせずマトリックス組んでましたが、このままではキツイので体制を見直すことにしました。(自作 C++ テスティングフレームワークの iutest で主に使ってて、複数パターンでテストしてました↑)
ただ、それでも 10,000 クレジットはあっという間になくなってしまうと予測されるので、サポートに OSS クレジットを申請してみました。

結果が来たら追記したいと思います。

Travis CI のかわりにオススメの CI サービスは?
さて、これを機に Travis CI から引っ越しする方も多いと思います。
GitHub Actions に移る方が多そうですが、別のサービスもオススメしておきます。

  • CircleCI
    まぁこれは知ってる人も使ってる人も多いと思うので、こっちに移る人も多いかも。
    OSS プランであれば 400,000 クレジット使えます。
    iutest の 2020/10 月の利用結果はこちら。まだ余裕あり
  • Drone.io
    Drone (Cloud)は OSS であれば完全フリーで使えます。
    並列数とか制限ありません(ただし、リソースは限られてる)
    iutest では gcc/clang の各バージョンでのテストをしています。
  • Azure Pipelines
    GitHub Actions よりは少ない 10 並列ですが、それでも強力な CI サービスです。
    GitHub Actions は(まだ)YAML のアンカー・エイリアスに対応していないので、独自のテンプレート構文が使える Azure Pipelines のほうが、マトリックスは組みやすいと思います。
    Travis CI でマトリックス組んでた人にはオススメです。
  • その他
    iutest では他にもたくさんの CI サービスを利用しているのでよければ参考にしてください。
最後に
DockerHub の pull rate limit の対応をしてたんですが、これまたインパクトのデカイ変更でした。。。このような CI サービスの悪用は他のサービスでも起こりそうな気がしてますが。。。今後の CI as a Service はどうなっていくんでしょうね。。。

2020年11月2日月曜日

Docker login しているか確かめる方法

前置き

 ダウンロードレート制限 | Docker ドキュメント

いよいよ DockerHub の Download Rate Limit が始まりましたね。
この制限は徐々に導入していくとありますが、さてどんな状況でしょうか?
(この記事は 11/1 に書いています)

特に懸念されていたのは CI サービスでの制限です。
DockerHub にログインしていない場合は IP に対して制限がかかるため、利用者の多いサービスではあっという間に上限越えて、制限がかかってしまうことが予想されました。
これに対し、すでに(期限付きではありますが)制限を受けないようにする交渉が完了しているサービスもあります。

DockerHub による2020/11からのコンテナイメージ Pull 回数制限のCircleCIへの影響 - Build Environment - CircleCI Discuss

ある程度猶予があるかもしれないですが…
何れにせよ、今後 DockerHub からイメージを pull して CI を回す場合は、事前に DockerHub へのログインをするようにパイプラインを更新しておくのが良さそうです。

それらへの対応方法についても、記事冒頭のドキュメントからリンクが貼られていたり、各 CI サービスから案内が出ていると思います。

筆者が開発している C++ テスティングフレームワークの iutest はめちゃくちゃたくさん CI サービスを使っているので(Docker 関係ないものもあるので全部ではないが)絶賛対応中です。

対応方法はログインするだけなんですが、各サービスやり方が異なるのでここでは対応方法は省略します。
一応、状況はこちらの issue で確認できます。
https://github.com/srz-zumix/iutest/issues/519

Docker login しているか確かめる方法

で、ようやく本題。
このログイン対応をしていて思ったのは、「設定したけど本当にログインした状態で pull できているのかをどう確認したらわからなくて不安」でした。

docker のコマンドに「それ」を確認するものがあればよかったのですが、なさそうだったので以下の方法で確認しました。

echo a | docker login

ログイン済みなら以下のように成功となります。

$ echo a | docker login
 Authenticating with existing credentials...
 Login Succeeded
$ echo $?
 0
ログインしてない場合は以下のように失敗になります。
$ echo a | docker login
 Error: Cannot perform an interactive login from a non TTY device
$ echo $?
 1
最後に
この方法をパイプラインに組み込んでみてないので、うまく CI 上で確認できるか未確認ですが、もっと簡単に確認できると嬉しいなと思います。もっと良い方アレば教えて下さい。
てか、直球なコマンドが欲しい。。