読者です 読者をやめる 読者になる 読者になる

tjinjin's blog

いつかすごいエンジニアになることを目指して、日々学んだことを書いていきます。

CircleCIを使ってbuildしたパッケージを自動でgithub releaseに公開する

CircleCI docker 運用

About

CircleCIとdockerを使ってrpmパッケージをビルドする仕組みはすでにあったので、それを少し改良してgithub releaseに自動で公開するところまでやってみました

Special Thanks

dockerを使ってrpmパッケージをビルドする仕組みはこちらを参考にしました。ForkするとCircleCIが動かなかったので、自分でリポジトリを作成し検証しました。

github.com

全体の流れ

今回のお題とし、rubyrpmパッケージを作ってみます。

  1. CircleCIでdockerを起動
  2. CentOS6.6/7.1のコンテナを起動
  3. コンテナ内でrubyをbuildするスクリプトを実行
  4. できたrpmパッケージをgithub releaseに公開

ソースはこちらにあります。

github.com

個々の処理の確認

rubyをbuildするスクリプトについて

rpmbuildコマンドを使ってrpmパッケージを作成しています。参考にしたスクリプトにはSRPMをアップロードする仕組みがなかったので、追加しました。

dockerでできたrpmをどうやって共有するか

こちらはdocker volumeを使って、ホストコンテナのディレクトリにマウントしています。CircleCIにはbuildした成果物を保存してくれる仕組みがあるので、そちらに共有させています。

Continuous Integration and Deployment

CircleCIからgithub releaseに公開する方法

今回はdescriptionの情報を修正したかったので、下記を利用しました。

github.com

似たようなことができる tcnksm/ghr · GitHub というものもあるのですが、上述の通りdescriptionも修正したかったので前者を利用しました。要件に応じて使い分けると良いと思います。

仕組みとしては簡単でcircle.ymlで下記のように指定します。

deployment:
  master:
    branch: master
    commands:
      - go get github.com/aktau/github-release
      - cp $CIRCLE_ARTIFACTS/*.rpm .
      - ./github-release.sh

masterにマージされた際に、$CIRCLE_ARTIFACTSに出来たrpmパッケージを作ったシェルスクリプトでアップロードしています。

#!/bin/bash

VERSION=$(cat ruby-version)
USER="tjinjin"
REPO="automate-ruby-rpm"

# create description

# create release
github-release release \
  --user tjinjin \
  --repo automate-ruby-rpm \
  --tag $VERSION \
  --name "Ruby-$VERSION" \
  --description "not release"

# upload files
echo "Use at your own risk!" >> description.md
echo "" >> description.md
for i in $(ls -1 *.rpm)
do
  echo "* $i" >> description.md
  echo "  * $(openssl sha256 $i)" >> description.md
  github-release upload --user tjinjin \
    --repo automate-ruby-rpm \
    --tag $VERSION \
    --name "$i" \
    --file $i
done

# edit description
github-release edit \
  --user $USER \
  --repo $REPO \
  --tag $VERSION \
  --description "$(cat description.md)"

github-releaseを使うに当たってGITHUB_TOKENが必要なので、事前に作成しCircleCIのEnvironment Variablesから環境変数として登録しています。

まとめ

このスクリプトは若干無駄があって、PRを出した際にもbuildが走り、それがmasterにマージされた際にもまたbuildをしてしまいます。PRで出来たrpmをmasterで使えればいいのですが。。。

参考

https://github.com/tjinjin/automate-ruby-rpm