ラベル Codeship の投稿を表示しています。 すべての投稿を表示
ラベル Codeship の投稿を表示しています。 すべての投稿を表示

2021年2月12日金曜日

[CodeShip][Drone.io] DockerHub pull rate limit に対応する

DockerHub の pull rate limit への対応方法メモです。
基本的には DockerHub にログインした状態で pull することになると思います。
ログイン情報のパスワードには DockerHub の設定から API トークンを発行しそれを設定します。


ただ、このユーザー/パスワードを各 CI サービスに適用する方法はサービスによって違います。今回は CodeShip と Drone.io の設定を紹介したいと思います。

CodeShip の場合

CodeShip Pro の場合です。 Basic の場合はコマンドの中で docker login コマンドを実行する方法になると思います。

Using Docker Image Registries | CloudBees Docs
上記リンク先のドキュメントに設定方法が記載されています。

手順としては大きく分けて2つで、Dockerconfig.json の用意とリポジトリ/ YAML の設定になります。

Dockerconfig.json の用意

まず DockerHub にログインするための config.json を生成します。

{
    "auths": {
        "https://index.docker.io/v1/": {
            "auth": "your_auth_string",
            "email": "your_email"
        }
    }
}  

json ファイルの中身は上記のようなものになります。
この json ファイルは docker login したら $HOME/.docker/config.json に保存されるものを使えばよいのですが、macOS の場合保存場所が keychain になっているため、下記方法で取得します。公式ドキュメントでは「Docker Credentials On Mac OSX」のあたりです。

まずは以下のような credentials.evn ファイルを作成します。
USERNAME/PASSWORD は適宜埋めてください(PASSWORD には API TOKEN)

DOCKER_USERNAME=...
DOCKER_PASSWORD=...
DOCKER_REGISTRY=https://index.docker.io/v1/
  

続いて、以下のコマンドを実行します。

mkdir ./dockercfg
docker run -it --rm \
    --env-file=credentials.env \
    -v "$(pwd):/opt/data/" \
    -v "/var/run/docker.sock:/var/run/docker.sock" \
    codeship/dockercfg-generator /opt/data/dockercfg

すると、カレントディレクトリ/dockercfg/ に config.json が出来上がります。

リポジトリ / YAML の設定

config.json が出来上がったらそれをシークレットファイルにして、CI 環境が読み込むように YAML に設定をします。

シークレットファイルの作成のためにプロジェクトの設定ページから codeship.aes をダウンロードしてください。リポジトリのルートに配置したら不用意に commit してしまわないように .gitignore に追加しておきましょう。

aes を配置したら以下のコマンドを実行します。パスは適宜変更してください。

jet encrypt dockercfg/config.json dockercfg.encrypted

出来上がった .encrypted ファイルは git add/commit します。

続いて YAML の設定をします。
追記するのは codeship-steps.yml ファイルの方です。
以下のように encrypted_dockercfg_path を追加してください。

- name: spec
  service: gcc
  command: /work/build.sh
  encrypted_dockercfg_path: ./dockercfg.encrypted
動作確認

これで設定は以上です。変更を commit/push して動作確認してみましょう。
うまく設定できていれば DockerHub の Token 一覧画面で最終アクセス日時が更新されるはずです。

Drone.io の場合

Images | Drone
Drone の公式ドキュメントはこちらです。

CodeShip と同じように Dockerconfig.json ファイルを作成し、それを drone のシークレットファイルとして CLI から登録します。
iutest で生成用に用意した Makefile があるので参考にしてください。
https://github.com/srz-zumix/iutest/tree/master/.ci/drone

json ファイルを作成したら以下のコマンドで登録できます。

	drone secret add --repository srz-zumix/iutest \
		--name dockerconfig \
		--data @dockerconfig.json

シークレットファイルをアップデートする場合は update サブコマンドを使います。

	drone secret update --repository srz-zumix/iutest \
		--name dockerconfig \
		--data @dockerconfig.json

PR でもこのシークレットファイルを利用可能にする場合は --allow-pull-request オプションを追加してください。
シークレットファイルを登録したら以下のように、このファイルを使用するように YAML の設定をします。

kind: pipeline
name: test

image_pull_secrets:
  - dockerconfig

steps:
...


image_pull_secrets に指定するのは secret add/update したときに指定した --name オプションの名前です。

動作確認

設定は以上です。
CodeShip と同様にトークンが利用されたかどうかを確認しましょう。

まとめ

今回対応した CodeShip/Drone どちらも Dockerconfig.json ファイルをシークレットに用意してそれを環境に読ませる方法でした。

最初 Drone の方は

echo -n '<ユーザ名>:<アクセストークン>' | base64

の結果を auth に設定していて、それではうまくいかなくて手こずっていたのですが、CodeShip のやり方を知って助かりました。
(Mac 環境で base64 してるのが原因?)

ともあれ、CodeShip や Drone と同様に Docker の config.json を使った login をする CI サービスではこの方法が使えそうです。

今回は以上です。

2020年5月18日月曜日

[CodeShip] Basic から Pro に移行してみたけど Basic に戻ってきた話

iutest の CI 環境アップデート報告その3です。
その1,2はこちら

今回は CodeShip の環境をアップデートしました。
CodeShip Basic と Pro とは
まずはじめに CodeShip について簡単に紹介します。

CodeShip は CloudBees が提供している CI as a Service です。
Basic はシンプルな機能で GUI Config なサービスです。
Pro は docker-compose のようにサービスコンテナを起動して CI ができるサービスです。

Pro の方が高機能で柔軟ですが、始めるには少し手間がかかります。
Basic はサービスが提供する環境でコマンドを実行する感じなので、すぐに始められます。

Basic と Pro はいつでもプロジェクト単位で移行可能です。
なので、とりあえず始めたい方には Basic がおすすめです。
Pro に移行してみた理由
iutest ではもともと Basic を使っていました。
ビルドや単体テストの実行などは行っておらず、 cpplint などのコーディングルールのチェックや OSDN の svn リポジトリへの同期、GitHub Pages のドキュメント更新を行っていました。
これらのことをする上で Pro の機能は必要なく Basic で十分でしたが、
ブログズミ: chrome://tracing で並列処理の可視化をしてみたらすごく便利だった話」で各 CI サービスの並列化能力を調べたところ、CodeShip Pro では Parallel Steps で多数の並列化(計測した限りでは 50 以上)可能だったため、Pro を使うことにしました。


Pro に移行
Basic から Pro に移行するにあたって必要なのは、YAML config の用意とプロジェクトのタイプ変更です。
YAML を用意する
まずは YAML ファイルを用意しましょう。
下記が iutest の YAML です。


CodeShip Pro で必要な YAML ファイルは2つあります。
services は docker-compose.yml みたいなものです。既存のイメージを pull するか Dockerfile からビルドできます。
steps に Basic で書いていたコマンドを書きます。
Pro の旨味を得るために、 Paralle Steps で並列に実行されるようにしています。

注意が必要なのは、Basic での環境では様々なツールがプリインストールされた環境だったので特にセットアップせずにツールが使えることが多かったですが、 Pro では docker image を使うので必要なツールや環境は自分で整える必要があります。

タイプ変更
YAML が準備できたらプロジェクトを Pro に変更します。
「Project Settings」の「General」にある「Change Project Type」で「Switch to CodeShip Pro」ボタンを押すだけです。

結果

Docker image のキャッシュが効いてる状態で多少速くなったかなーという結果でした。
やってることが軽量なのでこんなもんでしょう。ビルドやテストしてたら並列化の効果は高いと思います。
Basic に戻った理由
つづいて、Pro から Basic に戻った理由です。
Pro の並列化のメリットが iutest での使用例ではあまりなかったという理由もありますが、
一番の理由は「 OSDN の svn リポジトリへの同期処理で、SSH Key の設定を Pro でするのがめんどくさかったから」です。
Basic にはデフォルトで実行環境にプロジェクト固有の SSH Key が設定されており、Public Key をホストサービスに登録するだけで認証通せるので楽なのです。
(ここの設定画面は Pro に移行後も存在するのですが、この鍵は使えないようです。。)

もちろん Pro でも秘密鍵を取り扱う方法はちゃんと用意されています。
ただ、手間に見合うメリットがなかったので戻すことを決めました。
最後に
CodeShip Pro の Parallel Steps は上限がない?(少なくとも 50 並列できた)ので、かなり魅力的です。
CodeShip をメインの CI サービスにする場合は Pro をオススメします。

一方、CodeShip をサブの CI サービスにする場合は Basic で十分といえます。
Basic は並列化はできませんが、(私のように SSH Key の登録とか面倒なことを飛ばして)すぐにサービスを使いたい場合も Basic をオススメします。

Basic と Pro はプロジェクト単位でいつでも移行可能で、Web 上の設定は移行しても残ってたままになっているので気軽に乗り換えができます。
ぜひ一度、どちらも使ってみて使いやすい方を選んでください。

以上。

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 やインクルードガードのチェックや絶対パスが混入してないかの、雑多なテストを行っているのでそちらに組み込みました。



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

2018年3月26日月曜日

Rocro を使ってみた - その2(tidy と scan-build と auto-fix)

前回(ブログズミ: [CI] Rocro 使ってみた)、他の機能(ツール)も使っていきたいといってましたが、その経過報告です。

Tidy
まず1つめは Tidy です。こちらは、HTML 向けのツールです。
開発中の iutest は C++ なのでなぜ?という感じですが、ドキュメント類のチェックもしているので実は関係があります。
というのも、iutest は gh-pages でドキュメントを公開をしています。
Doxygen 生成やドキュメントのみのブランチにする変換を Codeship で行い、自動で gh-pages ブランチに push してます。
そのため、gh-pages ブランチは HTML なブランチになっており、たまたまブランチフィルターをつくる前に INSPECODE がテストくれたので、そのまま使うことにしました。


結論としては、まだうまく使いこなせてない状態です。
こちらが書きたいフォーマットと指摘が少しずれているのを、オプションなどで調整したいのですが、あまりうまくいっていないので別のツールを使ったほうがいいのかもしれません。


auto-fix オプション
auto-fix は INSPECODE 上のツールで検知した問題を、自動修正してくれるオプションです。
(使えないツールもあります。)
こちらを Tidy で有効にしてみました。

auto-fix オプションですが、自動修正されたコードは修正専用のブランチが作成されます。
(マージはされないので安心)
修正ブランチは、もとのブランチ名+@inspecode という名前で push されます。

作成されたブランチ:https://github.com/srz-zumix/iutest/tree/gh-pages%40inspecode

それをプルリクしたやつ:https://github.com/srz-zumix/iutest/pull/31


このとき、ブランチが push されますので他の CI サービスを使っている場合に、CI が回ってしまうので注意が必要です。
(適切に除外設定がされていれば問題なし)
Rocro 自身はデフォルトで除外されます。

※ Rocro への要望としては、auto-fix コミットのコミットメッセージに任意のメッセージを追加できるようにできると嬉しいです。
skip ci または ci skip コメントをつけるだけで他の CI サービスもスキップできるので楽になると思います。

結果としては、Tidy の修正内容は使わないことにしたので、auto-fix は無効にしています。
CI 回してオートマージまでやれればよかったのですが、これはまた別の機会にオアズケ。
(本当はこれを記事のメインにするつもりだったのですが・・・また今度で・・・)

scan-build
こちらは、clang の静的解析ツールです。
iutest では Semaphore CI で実行していましたが、Rocro ではオプション指定のみで簡単に使えたので引っ越しを検討しました。

まず、Semaphore CI でやっていたことをそのままさせたところ、タイムアウトしてしまいました。


この辺は無料ユーザーですし、各サービスで制限時間は異なるので仕方がないことです。
ので、ビルド対象者を絞ってタイムアウトしないようにしました。
ここまでは OK です。

この状態でジョブが走って、ステータスも
Succeeded になり、問題の検出もなかったので良かった良かったと思っていたのですが、勘違いでした。


ログ見たら、ビルド失敗して解析されないだけでした。
Failed にしてくれー

ともあれ、ビルドエラー修正したらちゃんと scan-build の結果が報告されるようになったのでめでたしめでたし。



最後に
記事を書き始めてから大分経ってしまったが、引き続き Rocro は使っていきテストの領域を増やしていきたいと思ってます。

2018年3月19日月曜日

[CI] 各種 CI サービスのビルドスキップコメントまとめ (2018/3)

CIサービスの自動ビルドをスキップする方法まとめ - Qiita
こちらに Travis CI、Circle CI、Appveyor の場合がまとまっていますが、この記事では私が利用している CI サービスすべてをまとめたいと思います。

[ci skip] vs [skip ci]
CI サービスでスキップするためのコミットコメントの定番が [ci skip] と [skip ci] です。どちらにも対応しているサービスもあれば、片方だけだったり、これに加えて独自のメッセージに対応していたりします。

iutest では全部で10以上のサービスを利用しているので、すべてのサービスで共通して使えるコメントでないと困るので今回のまとめに至りました。
また、特定のサービスだけスキップしたいなどの要求もあるかもしれないので、そういった場合にも役立つまとめになっているかと思います。

前置きはこれくらいにして、まとめを見ていきましょう。
まとめ
サービス[ci skip][skip ci]その他ユーザー定義
Travis CI
Circle CI
AppVeyor[skip appveyor]
wercker
Shippable
Codeship--skip-ci,--ci-skip
Semaphore
Codefresh
Bitrise
Scrutinizer[skip Scrutinizer]
Rocro(INSPECODE)

以前は、[ci skip] 派と [skip ci] 派が分かれていたのですが、
現在は [ci skip]/[skip ci] どちらも使える派が主流のようです。
Rocro はスキップできないみたいですね。


ユーザー定義も可能な AppVeyor
AppVeyor ではユーザーが任意のスキップコメントをつけることもできます。
https://www.appveyor.com/docs/how-to/filtering-commits/#skip-commits

やり方は appveyor.yml に以下を追加するだけです。

skip_commits:
  message: /\[no appveyor\]/

これを設定しておけば、AppVeyor だけスキップするような使い方ができます。

自分ですべて設定する Codefresh
https://docs.codefresh.io/docs/build-1
Codefresh にはデフォルトでスキップコメント機能はついていませんでした。
ただ、上記リンクのようにコンディションに書けば対応が可能でした。

steps:
  BuildingDockerImage:
    title: Building Docker Image
    type: build
    image_name: srzzumix/ciskip
    working_directory: ./
    dockerfile:
      content: |-
        FROM ubuntu:latest
        COPY . /usr/src/myapp
        WORKDIR /usr/src/myapp
    tag: '${{CF_BRANCH_TAG_NORMALIZED}}'
    when:
      condition:
        all:
          noSkipCiInCommitMessage: |
            includes(lower("${{CF_COMMIT_MESSAGE}}"), "[ci skip]") == false && includes(lower("${{CF_COMMIT_MESSAGE}}"), "[skip ci]") == false

注意が必要なのは、スキップ設定はすべてのステップに記述しないといけない点です。
(前のステップがスキップされても、後続のステップはスキップされないです。前のステップに依存しているとビルドが失敗します。)

また、スキップしたと言ってもビルド回数はカウントアップされます。。。(フリーアカウントの場合ビルド回数制限があるので気をつけましょう)

Only the head/last commit message is checked!
Bitrise のドキュメントに以下の注意書きがありました。
Only the head/last commit message is checked!
If you push more than one commit,
only the last ("head") commit's message will be checked for the skip ci pattern!
http://devcenter.bitrise.io/tips-and-tricks/skip-a-build/

複数のコミットをまとめて push した場合、コメントは最後のコミットのものしかチェックしないようです。つまり、途中のコミットにスキップコメントを入れてもスキップされないということです。

他のサービスではどうなのか調べてみたところ、(Travis CI を除く)他のサービスも同様の挙動をしてました。

Travis CI は全部にスキップコメントが必要
Travis CI は push したときの head だけでなく、commit 毎にビルドが実行されるようなので、全部のコミットにスキップメッセージを入れないとイケナイようです。
「Auto cancel branch builds」設定ができるようになりましたが、これは新しいビルドがキューイングされたらキャンセルする機能です。
スキップコメントの commit はキューイングされないため自動キャンセルもされません。

なので、Travis CI を使う場合は [ci skip] をスキップしたいコミットにつける必要があります。

Travis CI は、スキップしたいコミットに [ci skip] をつける。
それ以外は、スキップしたいコミットを含む push を行う場合は head のコミットに [ci skip] をつける。
ということになるので、Travis CI の方が直感的かもしれませんね。

最後に
今回調べたことは、こちらのリポジトリで検証・記録として見ることができます。
https://github.com/srz-zumix/ci-skip

他に試して欲しい CI サービスなどありましたら、連絡もしくは PR ください。
では。

2015年11月24日火曜日

Codeship 始めました

先週(ブログズミ: cpplint でコーディングチェック)にも書いたように、またしても CI サービスを使い始めました。
今度は Codeship です。



Codeship の無料プランはこんな感じです。

5 private リポジトリ、100回/月の private ビルド
OSS であればビルド無制限

サポート言語は以下


今回は cpplint.py を実行したいので Python が使えれば OK

プロジェクト作成
Sign Up したらプロジェクトを作ります。
Create a new project を押すと右のようなホスティングサービス選択画面が開きます。
目的のサービスを選択してください。
リポジトリのリストが表示されるので、目的のリポジトリを選択します。

つづいて、右のようなプロジェクト設定が出るので、それぞれ設定をしていきます。

「Select your technology to prepopulate basic commands」でターゲット言語を選択します。
今回は Python を使いたいのでそれを選択しました。

「Setup Commands」で環境のセットアップをします。
通常であれば、cpplint.py を使うためにダウンロードしたりするのですが、 iutest ではテスト用の Makefile で cpplint.py のダウンロードもするようにしているため、ここは空にしています。

「Configure Test Pipelines」でテストパイプラインを設定します。(無料枠だとパイプラインは1つまで、試用はできるみたいです。)
iutest では Makefile で cpplint がかけられるようにしているので、対象のディレクトリに移動して make するだけです。

cd test/cpplint
make

Makefile の中身はこちらから確認できます。
https://github.com/srz-zumix/iutest/blob/master/test/cpplint/Makefile

バッジ
最後に、CI サービス定番のバッジです。
バッジはプロジェクト設定の Notification にあります。


iutest/test/cpplint に貼り付けておきました。