MoriKen's Journal

MoriKen's Journal

アラサー社会人博士による徒然日記。技術についてつらつら。だけだとコンテンツが貧弱なので、会社公認で大学院博士課程に進学した経緯や、独学でTOEICを475→910にしたノウハウを共有します。最近アメリカ MBA(経営学)大学院もはじめました。

Buildfarm+bloomで自作ROS pkg をaptやrosdepで取得可能にする!②リリース編

Sponsored Link


今回は、実際に bloom を使ってリリースを行う手順を示します。

手順の流れは、目次を参照下さい。いっぱいあるように見えますが、かなりの部分は bloom がやってくれるので、そうビビる必要はありません ^^

release 後の作業を事前確認



bloom コマンド実行


$ bloom-release --rosdistro kinetic --track kinetic timed_roslaunch --edit


ROS Distro index file associate with commit '42bdb05c4d8fe3daac5c17751138f88f47b748c8'
New ROS Distro index url: ''
Specified repository 'timed_roslaunch' is not in the distribution file located at ''
Did you mean one of these: 'rgbd_launch'?
Could not determine release repository url for repository 'timed_roslaunch' of distro 'kinetic'
You can continue the release process by manually specifying the location of the RELEASE repository.
To be clear this is the url of the RELEASE repository not the upstream repository.
For release repositories on GitHub, you should provide the `https://` url which should end in `.git`.
Here is the url for a typical release repository on GitHub:

別 distribution 探索


==> Looking for a release of this repository in a different distribution...
No reasonable default release repository url could be determined from previous releases.


Release repository url [press enter to abort]:

release リポジトリの更新



==> Fetching 'timed_roslaunch' repository from ''
Cloning into '/tmp/tmpllWPdK'...
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), done.
Checking connectivity... done.




Creating track 'kinetic'...
Repository Name:
    Default value, leave this as upstream if you are unsure
    Name of the repository (used in the archive name)
  ['upstream']: timed_roslaunch

ソースリポジトリのURIです。 を指定します。

Upstream Repository URI:
    Any valid URI. This variable can be templated, for example an svn url
    can be templated as such: "{version}"
    where the :{version} token will be replaced with the version for this release.


Upstream VCS Type:
    Upstream URI is a svn repository
    Upstream URI is a git repository
    Upstream URI is a hg repository
    Upstream URI is a tarball
  ['git']: git


    This means that the user will be prompted for the version each release.
    This also means that the upstream devel will be ignored.
    This means the version will be guessed from the devel branch.
    This means that the devel branch must be set, the devel branch must exist,
    and there must be a valid package.xml in the upstream devel branch.
    This will be the version used.
    It must be updated for each new upstream version.


Release Tag:
    For svn and tar only you can set the release tag to :{none}, so that
    it is ignored.  For svn this means no revision number is used.
    This means the user will be prompted for the release tag on each release.
    This means that the release tag will match the :{version} tag.
    This can be further templated, for example: "foo-:{version}" or "v:{version}"
    This can describe any vcs reference. For git that means {tag, branch, hash},
    for hg that means {tag, branch, hash}, for svn that means a revision number.
    For tar this value doubles as the sub directory (if the repository is
    in foo/ of the tar ball, putting foo here will cause the contents of
    foo/ to be imported to upstream instead of foo itself).


Upstream Devel Branch:
  <vcs reference>
    Branch in upstream repository on which to search for the version.
    This is used only when version is set to ':{auto}'.
  [None]: kinetic-devel

ROS distribution を指定します。リリースコマンドで指定していたkineticがデフォルトで指定されるので、そのままエンター。

ROS Distro:
  <ROS distro>
    This can be any valid ROS distro, e.g. indigo, kinetic, lunar, melodic


Patches Directory:
    Use this if you want to disable overlaying of files.
  <path in bloom branch>
    This can be any valid relative path in the bloom branch. The contents
    of this folder will be overlaid onto the upstream branch after each
    import-upstream.  Additionally, any package.xml files found in the
    overlay will have the :{version} string replaced with the current
    version being released.

ros-distro への登録




Release Repository Push URL:
    This indicates that the default release url should be used.
    (optional) Used when pushing to remote release repositories. This is only
    needed when the release uri which is in the rosdistro file is not writable.
    This is useful, for example, when a releaser would like to use a ssh url
    to push rather than a https:// url.

以上で、kinetic のトラックが作成されます。

Created 'kinetic' track.

release 前の事前確認


本当に push できるのかまずは確認するっぽい。

==> Testing for push permission on release repository


==> git remote -v
origin (fetch)
origin (push)

push 時の挙動を確認する。

==> git push --dry-run
warning: push.default is unset; its implicit value has changed in
Git 2.0 from 'matching' to 'simple'. To squelch this message
and maintain the traditional behavior, use:

  git config --global push.default matching

To squelch this message and adopt the new behavior now, use:

  git config --global push.default simple

When push.default is set to 'matching', git will push local branches
to the remote branches that already exist with the same name.

Since Git 2.0, Git defaults to the more conservative 'simple'
behavior, which only pushes the current branch to the corresponding
remote branch that 'git pull' uses to update the current branch.

See 'git help config' and search for 'push.default' for further information.
(the 'simple' mode was introduced in Git 1.7.11. Use the similar mode
'current' instead of 'simple' if you sometimes use older versions of Git)

Username for '': MoriKen254
Password for '': 
   19e4882..0df3439  master -> master




==> Releasing 'timed_roslaunch' using release track 'kinetic'


==> git-bloom-release kinetic
Processing release track settings for 'kinetic'
Checking upstream devel branch for package.xml(s)
Cloning into '/tmp/tmp4Jv15O/upstream'...
remote: Enumerating objects: 15, done.
remote: Counting objects: 100% (15/15), done.
remote: Compressing objects: 100% (11/11), done.
remote: Total 162 (delta 6), reused 9 (delta 4), pack-reused 147
Receiving objects: 100% (162/162), 26.16 KiB | 0 bytes/s, done.
Resolving deltas: 100% (73/73), done.
Checking connectivity... done.
Looking for packages in 'kinetic-devel' branch... found 'timed_roslaunch'.
Detected version '0.1.1' from package(s): ['timed_roslaunch']

Executing release track 'kinetic'





これは、実際に Buildfarm が行う作業を真似するために、敢えてアーカイブを作成し、解凍するという冗長な処理をしているのだと思います。

==> bloom-export-upstream /tmp/tmp4Jv15O/upstream git --tag 0.1.1 --display-uri --name timed_roslaunch --output-dir /tmp/tmpl4sxFc
Checking out repository at '' to reference '0.1.1'.
Exporting to archive: '/tmp/tmpl4sxFc/timed_roslaunch-0.1.1.tar.gz'
Cloning into '/tmp/tmpfDAmvC'...
warning: --depth is ignored in local clones; use file:// instead.
md5: 386c49c2a9e913c13f8502c8a30df847

アーカイブ解凍→debian テンプレート 作成

解凍から、debian テンプレート 作成までチェックします。


==> git-bloom-import-upstream /tmp/tmpl4sxFc/timed_roslaunch-0.1.1.tar.gz  --release-version 0.1.1 --replace
Creating upstream branch.
Importing archive into upstream branch...
Creating tag: 'upstream/0.1.1'
I'm happy.  You should be too.

bloom が「私、嬉しいわ」って言ってる。そして「あなたもよね?そうよね?」って言いよってくる。うわーぁぁあああ。


って、まず upstream をソースに新しいブランチを作成している。ほう。

==> git-bloom-generate -y rosrelease kinetic --source upstream -i 0
Releasing package: ['timed_roslaunch']
Releasing package 'timed_roslaunch' for 'kinetic' to: 'release/kinetic/timed_roslaunch'

xenialdebian files を作るとな。そして、'debian/kinetic/timed_roslaunch' を作成。このブランチには、新たにdebian ディレクトリが作成されていて、ここに debian 用のテンプレートが格納されるようです。

==> git-bloom-generate -y rosdebian --prefix release/kinetic kinetic -i 0 --os-name ubuntu
Generating source debs for the packages: ['timed_roslaunch']
Debian Incremental Version: 0
Debian Distributions: ['xenial']
Releasing for rosdistro: kinetic

Pre-verifying Debian dependency keys...
Running 'rosdep update'...
All keys are OK

Placing debian template files into 'debian/kinetic/timed_roslaunch' branch.

==> Placing templates files in the 'debian' folder.

debian モジュール作成

実際に debian モジュールを作成する模様です。

Generating 'xenial' debian for package 'timed_roslaunch' at version '0.1.1-0'
Generating debian for xenial...
No homepage set, defaulting to ''
No historical releaser history, using current maintainer name and email for each versioned changelog entry.
Package 'timed-roslaunch' has dependencies:
Build and Build Tool Dependencies:
  rosdep key           => xenial key
  catkin               => ['ros-kinetic-catkin']
  rospy                => ['ros-kinetic-rospy']
  roslaunch            => ['ros-kinetic-roslaunch']
==> In place processing templates in 'debian' folder.
Expanding 'debian/copyright.em' -> 'debian/copyright'
Expanding 'debian/compat.em' -> 'debian/compat'
Expanding 'debian/rules.em' -> 'debian/rules'
Expanding 'debian/gbp.conf.em' -> 'debian/gbp.conf'
Expanding 'debian/changelog.em' -> 'debian/changelog'
Expanding 'debian/control.em' -> 'debian/control'
Expanding 'debian/source/format.em' -> 'debian/source/format'
Expanding 'debian/source/options.em' -> 'debian/source/options'
Creating tag: debian/ros-kinetic-timed-roslaunch_0.1.1-0_xenial

Successfully generated 'xenial' debian for package 'timed_roslaunch' at version '0.1.1-0'



==> git-bloom-generate -y rosdebian --prefix release/kinetic kinetic -i 0 --os-name debian --os-not-required
No platforms defined for os 'debian' in release file for the 'kinetic' distro. This os was not required; continuing without error.


==> git-bloom-generate -y rosrpm --prefix release/kinetic kinetic -i 0
No platforms defined for os 'fedora' in release file for the 'kinetic' distro.
Not performing RPM generation.


Tip: Check to ensure that the debian tags created have the same version as the upstream version you are releasing.
Everything went as expected, you should check that the new tags match your expectations, and then push to the release repo with:
  git push --all && git push --tags  # You might have to add --force to the second command if you are over-writing existing tags
<== Released 'timed_roslaunch' using release track 'kinetic' successfully

なんかアドバイスされたけど、とにかく release track が正常に作成されたって!なんか、bloom すごい!笑

release リポジトリへ push


ようやく、リモートに push することになります。


==> git remote -v
origin (fetch)
origin (push)
Releasing complete, push to release repository?

Continue [Y/n]? y

おとなしく y と入力です。さぁ、いよいよリリース。

==> Pushing changes to release repository for 'timed_roslaunch'
==> git push --all
Username for '': MoriKen254
Password for '': 
Counting objects: 44, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (43/43), done.
Writing objects: 100% (44/44), 5.43 KiB | 0 bytes/s, done.
Total 44 (delta 12), reused 0 (delta 0)
remote: Resolving deltas: 100% (12/12), completed with 7 local objects.
   9605992..98dcdd5  debian/kinetic/timed_roslaunch -> debian/kinetic/timed_roslaunch
   67e6ee4..59f5b3d  debian/kinetic/xenial/timed_roslaunch -> debian/kinetic/xenial/timed_roslaunch
   ec448c6..073744d  master -> master
   33aaacd..a4919c9  patches/debian/kinetic/timed_roslaunch -> patches/debian/kinetic/timed_roslaunch
   35db813..b34d7e5  patches/debian/kinetic/xenial/timed_roslaunch -> patches/debian/kinetic/xenial/timed_roslaunch
   abc70e3..a63f682  patches/release/kinetic/timed_roslaunch -> patches/release/kinetic/timed_roslaunch
   1362122..1b2d6c3  release/kinetic/timed_roslaunch -> release/kinetic/timed_roslaunch
<== Pushed changes successfully

==> Pushing tags to release repository for 'timed_roslaunch'

よし、リポジトリが push されました!続いて tag を push します。

==> git push --tags
Total 0 (delta 0), reused 0 (delta 0)
 * [new tag]         debian/ros-kinetic-timed-roslaunch_0.1.1-2_xenial -> debian/ros-kinetic-timed-roslaunch_0.1.1-2_xenial
 * [new tag]         release/kinetic/timed_roslaunch/0.1.1-2 -> release/kinetic/timed_roslaunch/0.1.1-2
 * [new tag]         upstream/0.1.1 -> upstream/0.1.1
<== Pushed tags successfully

あぁ、ようやく release リポジトリが完成しました。

ros-distro を fork & PR

ros-distro のリポジトリもクローンして、今回の変更を反映してもらうようにPRを送る処理に進みます。



もう、ひたすらデフォルト、yes で行きましょう。git なので。

==> Generating pull request to distro file located at ''
Would you like to add documentation information for this repository? [Y/n]? y
==> Looking for a doc entry for this repository in a different distribution...
Using defaults from the doc entry of distribution 'indigo'.
Please enter your repository information for the doc generation job.
This information should point to the repository from which documentation should be generated.
VCS Type must be one of git, svn, hg, or bzr.
VCS type [git]: 
VCS url []: 
VCS version must be a branch, tag, or commit, e.g. master or 0.1.0
VCS version [indigo-devel]: kinetic-devel
Would you like to add source information for this repository? [Y/n]? y
==> Looking for a source entry for this repository in a different distribution...
Using defaults from the source entry of distribution 'indigo'.
Please enter information which points to the active development branch for this repository.
This information is used to run continuous integration jobs and for developers to checkout from.
VCS Type must be one of git, svn, hg, or bzr.
VCS type [git]: 
VCS url []: 
VCS version must be a branch, tag, or commit, e.g. master or 0.1.0
VCS version [indigo-devel]: kinetic-devel
Since you are on github we can add a job to run your tests on each pull request.If you would like to turn this on please see for more information. There is more setup required to setup the hooks correctly. 
Would you like to turn on pull request testing? [y/N]? y
Would you like to add a maintenance status for this repository? [Y/n]? y
Please enter a maintenance status.
Valid maintenance statuses:
- developed: active development is in progress
- maintained: no new development, but bug fixes and pull requests are addressed
- unmaintained: looking for new maintainer, bug fixes and pull requests will not be addressed
- end-of-life: should not be used, will disappear at some point
Status: maintained
You can also enter a status description.
This is usually reserved for giving a reason when a status is 'end-of-life'.
Status Description [press Enter for no change]:
Unified diff for the ROS distro file located at '/tmp/tmp3WPuqi/timed_roslaunch-0.1.1-2.patch':

お、ここで実際に ros-distro にPRする差分を確認できます。

--- 42bdb05c4d8fe3daac5c17751138f88f47b748c8/kinetic/distribution.yaml
+++ 42bdb05c4d8fe3daac5c17751138f88f47b748c8/kinetic/distribution.yaml
@@ -12921,6 +12921,22 @@
       version: kinetic-devel
     status: developed
+  timed_roslaunch:
+    doc:
+      type: git
+      url:
+      version: kinetic-devel
+    release:
+      tags:
+        release: release/kinetic/{package}/{version}
+      url:
+      version: 0.1.1-2
+    source:
+      test_pull_requests: true
+      type: git
+      url:
+      version: kinetic-devel
+    status: maintained
       type: git


ros-distro の fork



まずoauth トークン作れって。そらそーですな。

Looks like bloom doesn't have an oauth token for you yet.
Therefore bloom will require your GitHub username and password just this once.
With your GitHub username and password bloom will create an oauth token on your behalf.
The token will be stored in `~/.config/bloom`.
You can delete the token from that file to have a new token generated.
Guard this token like a password, because it allows someone/something to act on your behalf.
If you need to unauthorize it, remove it from the 'Applications' menu in your GitHub account page.

Would you like to create an OAuth token now [Y/n]? 
GitHub username [nishidalab]: MoriKen254
GitHub password (never stored): 
The token 'ad298882a971af397ffbb38e2ac9bfb6094de614' was created and stored in the bloom config file: '/home/hogehoge/.config/bloom'

満を持して fork です。私の個人アカウントに強制的にforkが走ります。

==> Checking on GitHub for a fork to make the pull request from...
==> Using this fork to make a pull request from: MoriKen254/rosdistro
==> Cloning MoriKen254/rosdistro...
==> mkdir -p rosdistro
==> git init
Initialized empty Git repository in /tmp/Vov88B/rosdistro/.git/
Pull Request Title: timed_roslaunch: 0.1.1-2 in 'kinetic/distribution.yaml' [bloom]
Pull Request Body : 
Increasing version of package(s) in repository `timed_roslaunch` to `0.1.1-2`:

- upstream repository:
- release repository:
- distro file: `kinetic/distribution.yaml`
- bloom version: `0.6.7`
- previous version for package: `null`


* Modify travis setting.
* Fix timed_roslaunch to add default values
* Contributors: MoriKen254 hogehoge

ros-distro への PR



Open a pull request from 'MoriKen254/rosdistro:bloom-timed_roslaunch-0' into 'ros/rosdistro:master'?
Continue [Y/n]? y
==> git checkout -b bloom-timed_roslaunch-0
Switched to a new branch 'bloom-timed_roslaunch-0'
==> Pulling latest rosdistro branch
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 118493 (delta 2), reused 1 (delta 1), pack-reused 118490
Receiving objects: 100% (118493/118493), 50.43 MiB | 393.00 KiB/s, done.
Resolving deltas: 100% (75344/75344), done.
 * branch            master     -> FETCH_HEAD
==> git reset --hard 0d0b72dc8853d6aa38e739f761cd7ef2edec30ab
HEAD is now at 0d0b72d rail_face_detection: 1.0.2-0 in 'indigo/distribution.yaml' [bloom] (#19402)
==> Writing new distribution file: kinetic/distribution.yaml


==> git add kinetic/distribution.yaml


==> git commit -m "timed_roslaunch: 0.1.1-3 in 'kinetic/distribution.yaml' [bloom]"
[bloom-timed_roslaunch-0 52a6f41] timed_roslaunch: 0.1.1-3 in 'kinetic/distribution.yaml' [bloom]
 1 file changed, 16 insertions(+)

いけ!push だ!

==> Pushing changes to fork
Counting objects: 29302, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (8667/8667), done.
Writing objects: 100% (29302/29302), 17.12 MiB | 2.67 MiB/s, done.
Total 29302 (delta 17344), reused 28291 (delta 16345)
remote: Resolving deltas: 100% (17344/17344), completed with 38 local objects.

そして PR !

remote: Create a pull request for 'bloom-timed_roslaunch-0' on GitHub by visiting:
 * [new branch]      bloom-timed_roslaunch-0 -> bloom-timed_roslaunch-0
<== Pull request opened at:







  • OpenRobotics の方が ros-distro の PR を承認してくれます。結構レス早いです。
  • Jenkins さんがビルドしてくれます。1, 2日に1回くらい。
  • ドキュメントはでのステータスは ROS Wiki で反映されます。
  • ビルドされたモジュールは、まずは shadow-fixed リポジトリに入ります。
    • 本リリース前に、何かおかしなことが起きないかを確認するためのバッファです。
    • .list を書き換えれば、こちらにあるパッケージを apt で取得できます。
  • 大体2週間くらいすると、本 release されます。
    • ココまでくれば、apt で取得できます。rosdep でも解決できます。気持ちいいです。


sudo apt install ros-kinetic-timed-roslaunch


駆け足でしたが、自作 ROS パッケージのリリース手順を示しました。

あぁ、ros-distro リポジトリも図に示さないと、何やってるのかよくわからない感じになっちゃいましたね汗。