概要
本稿は、GitHub などの Git リポジトリで公開されているソフトウェアの Debian パッケージを、git-buildpackage パッケージによって提供される gbp コマンドを使って、Git 上で管理する方法のメモです。
前提として、git-buildpackage パッケージの gbp コマンドを使います。また、リモートリポジトリが2つ登場します。
- 上流リポジトリ: パッケージ対象のソフトウェアが公開されているリポジトリ
- 管理リポジトリ: 主として
debian/
配下のパッケージ用ファイルを管理する目的のリポジトリ
まだ誤りや勘違いが残っていそうな気がするので、コメントよろしくお願いします。
最初のバージョンのパッケージを作成する時
最初に、空の作業用リポジトリを用意します。
mkdir pkg-sentencepiece
cd pkg-sentencepiece
git init
git commit --allow-empty -m "first commmit"
次に、上流リポジトリをダウンロードします。
git remote add upstream https://github.com/google/sentencepiece.git
git fetch upstream
以下のコマンドで、上流リポジトリに相当する upstream
ブランチを作成しておきます。
git checkout -b upstream upstream/master
upstream
ブランチは、上流のソースコードを追跡するためのブランチなので、debian/
配下のパッケージ用ファイルやパッケージ用改変を混入させないように気をつけてください。
パッケージ作成の対象とする upstream
ブランチにタグを付与しておきます。タグ名の内、upstream/
は gbp コマンドが使っている固定文字列です。0.0.0+20170516
の部分は、パッケージメンテナが自由に選べるバージョン文字列です。
git tag upstream/0.0.0+20170516
master
ブランチに戻って、上流のソースコードをマージします。
git checkout master
git merge --allow-unrelated-histories upstream
debian/
配下の必要なファイルを作成したり、パッケージ用改変を行います。パッケージが正しく作れるようになるまで、各種ファイルを修正しながら以下のコマンドを繰り返し実行します。
gbp buildpackage
なお、Debian10 (Buster) 以後の gbp は、パッケージビルド時に cowbuider を自動的に呼び出すようになったので、初回のみ cowbuilder の設定が必要です。設定せずにパッケージをビルドすると、以下のようなエラーになります。
$ gbp buildpackage
(略)
Base directory /var/cache/pbuilder/base-stable-amd64.cow does not exist
このエラーメッセージは cowbuilder 用の chroot 環境が存在しないということを意味していますので、以下のコマンドを実行して、クリーンな chroot 環境を作成します。
sudo env DIST=stable ARCH=amd64 git-pbuilder create
なお、作成した chroot 環境を更新するには、以下のコマンドを実行します。
sudo env DIST=stable ARCH=amd64 git-pbuilder update
筆者の場合は、stable 用のパッケージを作ることがほとんどなので、以下のコマンドでパッケージをビルドしています。
gbp buildpackage -us -uc --git-dist=stable --git-arch=amd64
正しく作れるようになったら、以下のコマンドでリリース用パッケージを作成します。このコマンドは、master
ブランチ上で、リリース用パッケージに対応するタグも付与します。
gbp buildpackage --git-tag
パッケージ用ファイルとパッケージ用に改変したソースコードなど一式を、管理リポジトリに格納しておきます。
git remote add origin ssh://git@bitbucket.org/tsuchm/pkg-sentencepiece.git
git push -u origin master
git push -u origin --tags
上流の更新に追従する時
upstream
ブランチに移動して、上流リポジトリの更新を取得します。
git checkout upstream
git pull
パッケージ対象の上流ソースコードにタグを付与しておきます。
git tag upstream/0.0.0+20170829
master
ブランチに戻り、上流ソースコードの更新をマージします。
git checkout master
git merge upstream
必要な改変を行って、パッケージを作成します。
作業用ローカルリポジトリを作り直す時
最初に、管理リポジトリを複製します。
git clone ssh://git@bitbucket.org/tsuchm/pkg-sentencepiece.git
次に、上流リポジトリを追加します。
cd pkg-sentencepiece
git remote add upstream https://github.com/google/sentencepiece.git
git fetch upsteream
上流リポジトリの最新に相当する upstream
ブランチを作成しておきます。
git checkout -b upstream upstream/master
上流ソースコードが tarball で公開されている時
本稿の主題とは異なりますが、上流ソースコードが tarball で公開されている場合の git-buildpackage の使い方も、ついでに紹介しておきます。まず、tarball を upstream
ブランチに import します。
tar xzf crfsuite-0.12.tar.gz
cd crfsuite-0.12
git init
git commit --allow-empty -m "first commit"
git branch upstream
git checkout upstream
git add *
git commit "Import crfsuite-0.12"
git tag "upstream/0.12"
後は master
ブランチに戻って通常のパッケージ作成手順となります。
git checkout master
git merge upstream
dh_make
gbp buildpackage
パッケージが構築できることを自動的に確認する
最近の Git リポジトリサービスでは、継続的インテグレーション(CI)を行うために、git push 後に自動的にコマンドを実行する仕組みがあることが多くなっています。この仕組みを使うと、パッケージがビルドできるかどうか?をチェックすることができます。例として、BitBucket Pipelines を使って、パッケージがビルドできるかどうかをチェックする手順を以下に示します。
まず、以下のようにパッケージのビルド手順を記述した bitbucket-pipelines.yml
というファイルを用意します。ここでは、Docker Hub から unstable な debian コンテナをダウンロードし、ビルドに必要なパッケージをインストールしてから、gbp を実行しています。
image: debian:unstable
pipelines:
default:
- step:
script:
- apt update
- env DEBIAN_FRONTEND=noninteractive apt upgrade -y
- env DEBIAN_FRONTEND=noninteractive apt install -y build-essential git-buildpackage
- env DEBIAN_FRONTEND=noninteractive apt install -y `perl -ne 's/#.*$//;if(s/^Build-Depends:\s*//){$p=$_;}elsif($p){if(/^\s/){$p.=$_;}else{$p=~s/\(.*?\)//g;$p=~s/[,\s]+/ /g;print $p;undef $p}}' debian/control`
- gbp buildpackage -us -uc
下から2行目の perl を使っているワンライナーは、debian/control
ファイルから Build-Depends で指定されているパッケージリストを取り出してインストールしています。なお、単純に全てのパッケージをインストールしようとしますので、アーキテクチャ別の条件分岐や複数のパッケージのどちらかが入っていれば良いなどの論理式を使っている場合は、適切に記述を変更する必要があります。
DEBIAN_FRONTEND 環境変数の設定を行わないと、apt 実行時にエラーになります。また、gbp コマンドに -us
オプションと -uc
オプションを渡さないと、署名に失敗してエラーになります。
単に bitbucket-pipelines.yml
というファイルを置いておくと、debian/
ディレクトリ以外に変更が生じていることになるため、dpkg-source コマンド実行時にエラーになります。そのため、以下のような内容の debian/source/options
ファイルを作成しておき、bitbucket-pipelines.yml
の変更を無視するようにしておきます。
extend-diff-ignore = "^bitbucket-pipelines\.yml$"
適切に設定すると、gbp コマンドまで正常に実行される(つまり、パッケージが正常にビルドできる)と、Pipelines の実行結果に Successful と表示されるようになります。