Home > Latest topics

Latest topics > アドオンのナイトリービルドのようなものを置くようにした

宣伝。日経LinuxにてLinuxの基礎?を紹介する漫画「シス管系女子」を連載させていただいています。 以下の特設サイトにて、単行本まんがでわかるLinux シス管系女子の試し読みが可能! シス管系女子って何!? - 「シス管系女子」特設サイト

アドオンのナイトリービルドのようなものを置くようにした - Nov 24, 2012

リリースにまつわる諸々の作業が面倒くさくて、about:newtabには機能ができてすぐ対応したのに、リリースしてなかったせいで今頃「about:newtabを空のタブとして認識してくれないんだが」系の「不具合報告」が届くようになってきていて、他にも障害報告に対して「それmasterのHEADではもう直ってます」な場合が時々あって、あと時々「ナイトリービルドを提供してくれ」っていう声も見かけてはいたので、ちょっと頑張って/xul/xpi/nightly/でそれっぽい物を提供するようにしてみた。

  • 毎日定期的にリポジトリの変更をpullして、変更があったらXPIを作りなおしてアップロードする、ということを自動的にやってみてます。
  • 中身はmasterブランチのHEADをそのままパッケージングしただけの物で、typoで動かなくなってるような場合でもそのままアップロードしてしまうから、常用はお勧めしないでおきます。(とはいえ、この状態は僕自身の環境に極めて近いので、僕が常用しているアドオンについては、僕が不具合に遭遇し次第すぐに直すとは思いますが……)
  • 自動アップデートについては、リリース版とは別にこのナイトリービルド専用のupdate.rdfを提供するようにしてます。

どうやってるかというと、自宅にあるUbuntuマシン(NASも兼ねていて24時間動きっぱなしの自宅サーバ)上でcronjobを動かしているだけ。1点だけ工夫が必要だったのは、update.rdfに署名するという部分。update.rdfのデジタル署名にはMcCoyを使うんだけど、これだとcronjobとして自動実行させるのには都合が悪いので、MDNのページで紹介されてたMX-Toolsというのを使うようにした。

前提はこんな感じ。

  • アドオンのリポジトリはgitで管理している。
    • gitリポジトリには、パスワード無しの秘密鍵でSSH接続できる。もしくは、手元にリポジトリをパスワード無しでcloneしている(GitHubなら、httpsのURLを使ってcloneした場合がこれにあたる)。
    • すべてのリポジトリを、1つのディレクトリ(ベースディレクトリ)の中に、プロジェクト名と同じ名前のサブディレクトリでcloneしてある。
  • WWWサーバにはパスワード無しの秘密鍵でSSH接続できる。
  • RDFファイルの署名用にOpenSSLの鍵ペアを作成してある。
    • openssl genrsa -out keyfile.pem 1024
    • openssl rsa -in keyfile.pem -pubout -out keyfile.pub
    • 作成された秘密鍵・公開鍵はどちらもベースディレクトリ直下に置いてある。

特定の1つのアドオンについて「masterのHEADをpullして、変更があったらXPIにして、update.rdfを作って、アップロードする」というスクリプトは、試行錯誤の結果、こんな感じになった。

upload_nightly_xpi.sh:

#!/bin/bash

# MX-Tools等を同じディレクトリに置いているという前提で、
# このファイルのパスを基準にして、他のツールの位置を
# 指定するため、ディレクトリのフルパスを最初に得ておく。
tools_dir=$(cd $(dirname $0) && pwd)

remote_user=piro
remote_host=piro.sakura.ne.jp
remote_dist_dir=~/www/xul/xpi/nightly
actual_dist_dir=http://piro.sakura.ne.jp/xul/xpi/nightly

# ファイルの置き場所等はオプションで得る事にする。
while getopts ab:d:i: OPT
do
  case $OPT in
    # 変更が無くても強制的にアップロードする指定。テスト用。
    "a" ) always=1 ;;
    # keyfile.pem等を置いているディレクトリのパス。
    "b" ) base_dir="$OPTARG" ;;
    # リポジトリをcloneした先のディレクトリ。
    "d" ) project_dir="$OPTARG" ;;
    # SSH接続に使う秘密鍵のパス。
    "i" ) secret_key="$OPTARG" ;; 
  esac
done

if [ "$project_dir" = '' ]; then
  echo "no project directory specified"
  exit 1
fi

if [ "$base_dir" = '' ]; then
  echo "no base directory specified"
  exit 1
fi

if [ "$secret_key" = '' ]; then
  echo "no secret key specified"
  exit 1
fi

# sedのオプションの違いを吸収しておく。
case $(uname) in
  Darwin|*BSD|CYGWIN*) sed="sed -E" ;;
  *)                   sed="sed -r" ;;
esac

# pullした時のメッセージを見て、変更があったかどうかを調べる。
cd $project_dir
pull_result=$(git pull --rebase)
updated=$(if [ "$pull_result" != "Already up-to-date." -a \
               "$pull_result" != "Current branch master is up to date." ];\
          then echo "1"; fi)
if [ "$updated" = "1" -o "$always" = "1" ]; then
  package_name=$(cat $project_dir/Makefile | \
                 grep "PACKAGE_NAME" | \
                 head -n 1 | cut -d "=" -f 2 | \
                 $sed -e "s/\\s*//#")
  public_key=$(cat $base_dir/keyfile.pub | \
               grep -v -E "^--" \
               tr -d "\r" | tr -d "\n")

  # ナイトリービルド用として、install.rdfを書き換える。
  # バージョン番号の末尾に今日の日付を付ける。
  $sed -e "s/(em:version=\"[^\"]+)\\.[0-9]{10}/\\1/" \
       -i install.rdf
  $sed -e "s/(em:version=\"[^\"]+)/\\1.$(date +%Y%m%d)00.$(date +%H%M%S)/" \
       -i install.rdf
  update_rdf=${package_name}.update.rdf
  # 古いupdate.rdfが残っていたら消す。
  rm $update_rdf
  # update.rdfの参照先と、公開鍵を書き換える。
  $sed -e "s#/xul/update.rdf#/xul/xpi/nightly/updateinfo/${update_rdf}#" \
       -i install.rdf
  $sed -e "s#([^/]em:updateKey[=>\"]+)[^\"<]+#\\1${public_key}#" \
       -i install.rdf

  # 自動生成されたバージョン番号は、後で使うので控えておく。
  version=$(cat install.rdf | \
            grep "em:version" | head -n 1 | \
            $sed -e "s#[^\">]*[\">]([^\"<]+).*#\\1#")

  # ビルドした後、リポジトリの内容を元に戻しておく。
  # (次にpullする時に、未コミットの変更があるという
  # 警告が出ないようにする。)
  make
  git reset --hard

  file=$(ls *.xpi | grep -v "_noupdate" | head -n 1)
  # キャッシュが使われる事の無いように、
  # ユニークなダウンロード用URLにする。
  update_link=${actual_dist_dir}/${file}?version=${version}

  if [ "$file" != "" -a -f $file ]; then
    ssh_remote=${remote_user}@${remote_host}
    # 公開先のディレクトリを作っておく。
    ssh -i $secret_key ${ssh_remote} \
        mkdir -p ${remote_dist_dir}/updateinfo
    # XPIをアップロードする。
    scp -i $secret_key ./$file \
        ${ssh_remote}:${remote_dist_dir}/
    # XPIからupdate.rdfを自動生成し、それもアップロードする。
    $tools_dir/mxtools/uhura -o $update_rdf \
      -k $base_dir/keyfile.pem $file $update_link
    scp -i $secret_key ./$update_rdf \
        ${ssh_remote}:${remote_dist_dir}/updateinfo/
  fi
fi

exit 0

uhuraを使うには、依存パッケージを入れておく必要がある。

$ sudo apt-get install openssl unzip libexpat1-dev
$ cpan
(色々セットアップ。基本的には全部YesでOKだと思う。)
$ sudo cpan install  XML::Parser RDF::Core Digest::SHA1 Convert::ASN1

アドオン1つだけでテストしてみた。

$ ./upload_nightly_xpi.sh -b ~piro/xul \
                          -d ~piro/xul/autodisableime \
                          -i ~/.ssh/id_rsa.nopassword \
                          -a

これでうまく動くことを確認できたので、複数リポジトリを全部処理するスクリプトを作って、そちらをcronで走らせるようにした。

upload_nightly_xpis.sh

#!/bin/bash

tools_dir=$(cd $(dirname $0) && pwd)

# 鍵の指定などを丸ごと引き渡すようにしたいので、
# このスクリプト自身では使わないオプションについても
# 受け付けるようにしてる。
while getopts ab:d:i: OPT
do
  case $OPT in
    "b" ) base_dir="$OPTARG" ;;
  esac
done

if [ "$base_dir" = '' ]; then
  echo "no base directory specified"
  exit 1
fi

cd $base_dir
for dirname in *
do
  if [ -d $dirname ]; then
    ${tools_dir}/upload_nightly_xpi.sh -d $base_dir/$dirname "$@"
  fi
done

で、これを日に2回動かすよう、crontabに 0 7,19 * * * upload_nightly_xpis.sh -b ~piro/xul -i ~/.ssh/id_rsa.nopassword とかいう感じで書いてる。

仮想マシンでも何でもいいけど、Linuxな環境があると自動化がはかどるな……と思いました(手前味噌)。

2012年11月26日追記:スクリプトにミスがあってinstall.rdfに埋め込む公開鍵が置き換わっていなかったので修正した。

分類:Mozilla > 拡張機能, , , , 時刻:19:38 | Comments/Trackbacks (0) | Edit

Comments/Trackbacks

TrackBack ping me at


の末尾に2020年11月30日時点の日本の首相のファミリーネーム(ローマ字で回答)を繋げて下さい。例えば「noda」なら、「2012-11-24_nightly.trackbacknoda」です。これは機械的なトラックバックスパムを防止するための措置です。

Post a comment

writeback message: Ready to post a comment.

2020年11月30日時点の日本の首相のファミリーネーム(ひらがなで回答)

Powered by blosxom 2.0 + starter kit
Home

カテゴリ一覧

過去の記事

1999.2~2005.8

最近のコメント

最近のつぶやき