宣伝。日経LinuxにてLinuxの基礎?を紹介する漫画「シス管系女子」を連載させていただいています。 以下の特設サイトにて、単行本まんがでわかるLinux シス管系女子の試し読みが可能!
リリースにまつわる諸々の作業が面倒くさくて、about:newtabには機能ができてすぐ対応したのに、リリースしてなかったせいで今頃「about:newtabを空のタブとして認識してくれないんだが」系の「不具合報告」が届くようになってきていて、他にも障害報告に対して「それmasterのHEADではもう直ってます」な場合が時々あって、あと時々「ナイトリービルドを提供してくれ」っていう声も見かけてはいたので、ちょっと頑張って/xul/xpi/nightly/でそれっぽい物を提供するようにしてみた。
どうやってるかというと、自宅にあるUbuntuマシン(NASも兼ねていて24時間動きっぱなしの自宅サーバ)上でcronjobを動かしているだけ。1点だけ工夫が必要だったのは、update.rdfに署名するという部分。update.rdfのデジタル署名にはMcCoyを使うんだけど、これだとcronjobとして自動実行させるのには都合が悪いので、MDNのページで紹介されてたMX-Toolsというのを使うようにした。
前提はこんな感じ。
特定の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に埋め込む公開鍵が置き換わっていなかったので修正した。
の末尾に2020年11月30日時点の日本の首相のファミリーネーム(ローマ字で回答)を繋げて下さい。例えば「noda」なら、「2012-11-24_nightly.trackbacknoda」です。これは機械的なトラックバックスパムを防止するための措置です。
writeback message: Ready to post a comment.