MoriKen's Journal

MoriKen's Journal

アラサー社会人博士による徒然日記。技術についてつらつら。だけだとコンテンツが貧弱なので、会社公認で大学院博士課程進学したで経緯や、独学でTOEICを475→910にしたノウハウを共有します。気が向いたらエッセイとかも。

【ROS2】Windows 10+Ubuntu 18.04 in VMWare 上の Gazebo で Turtlebot3 を動かす!

こんにちは。ROS に触れたのは10年ぶりくらいかと思ったら、50日ぶり程度だった MoriKen です。

ROS に関心があるんですー、とおっしゃる方が増えてきたなぁと思う今日このごろ。

一方、大抵行き着くのが環境の話です。Windows で動きやしないか?と。動くみたいですけど、Ubuntuの方が安定しますよ^^ とお伝えすると、苦い顔をされてしまうことが多々ありまして。

そんなこんなで、初学者でもサクッと Windows で ROS を検証できる環境はないかなーと模索しております。

もちろん、頑張れば動くんですよね。素晴らしき先人がたくさんいらっしゃる。

gbiggs.github.io

demura.net

qiita.com

Windows ネイティブでやる方法って、Gazebo とか RViz の方どうなっているんだろう?という疑問があります。

WSL (Windows Subsystem for Linux) を利用して GUI だけは X サーバに飛ばすって構成もあるみたいで、こちらだと Gazebo でのデモを紹介しているブログがありまして。

私も先人にあやかりWindowsで!と思って色々試したのですが、出るわ出るわ、エラーのお祭り笑。 腰を据えて取り組むことができればもう少しお付き合いしたかったのですが、ちょっとそれどこじゃない (T_T;)笑。

また、ROS Kyushu ユーザグループにて、集団でハンズオン講習会をすることを狙っているので、あまり環境に依存せず、エラー処理があっても短時間で解決が見込まれる、できるだけ安定した環境が欲しいという背景がありました。

そこで、Windows で手早く ROS2 で遊べる環境として、実績のある VMWare を選定しました。 本エントリは、上記講習会の事前演習+当日のトラブルシューティング向けの情報を掲載することを意図してます。 最低限 Turtlebot3 のナビゲーションチュートリアルで遊ぶところまでの手順を、簡潔にまとめておきたいと思いますので、ご参考になれば幸いです。

環境

  • ホストOS: Windows 10
  • 仮想マシンツール: VMWare Workstation Player 15.5
  • ゲストOS: Ubuntu 18.04
  • ROS2 distribution: Dashing Diademata

仮想マシン環境の構築

VMWare のインストール

ホスト OS に VMWare Workstation Player をインストールします。下記サイトからインストーラをダウンロードして、実行して下さい。

www.vmware.com

本エントリ執筆時点では、15.5 が最新でした。Player は、非商用利用であれば無料です。

Ubuntu 18.04 イメージの作成

インストールが完了したら、VMware を利用して、ROS2 を動かす Ubuntu 18.04 の仮想マシンイメージを作成します。

Ubuntu のインストーラ(ISO)のダウンロードと、仮想マシンイメージの作成手順については、下記事をご参照下さい。

qiita.com

「VMware Player と Device/Credential Guard には互換性がありません。」というエラーが出たら

作成したイメージを起動しようとする際、新しい Windows 10 だと、このようなエラーが出る場合があります。

その場合は、下記事の手順に従って、諸々の設定を行ってから、イメージを起動し直して下さい。

www.wareko.jp

ROS 2 のセットアップ

ROS2 のインストール

ようやく ROS 2 です。仮想イメージ内で、ROS 2 をインストールして下さい。

手順は、下記事を参考にして下さい。

gbiggs.github.io

Talker & Listener の確認

基本的なサンプルコードの動作確認を行います。

こちらについても、ジェフさんの記事を参考にして下さい。

gbiggs.github.io

Turtlebot 3 のセットアップ

下記の本家サイトを参考にしてインストールするのが確実です。

emanual.robotis.com

英語は嫌!という場合に備え。ちょっとだけ翻訳+補足。

事前準備

# ビルドシステムのColconをインストール
$ sudo apt install python3-colcon-common-extensions
# SLAM パッケージである Cartographer の依存パッケージをインストール
$ sudo apt install -y \
 google-mock \
 libceres-dev \
 liblua5.3-dev \
 libboost-dev \
 libboost-iostreams-dev \
 libprotobuf-dev \
 protobuf-compiler \
 libcairo2-dev \
 libpcl-dev \
 python3-sphinx
# シミュレータ Gazebo9 のインストール
$ curl -sSL http://get.gazebosim.org | sh
$ sudo apt install ros-dashing-gazebo-*
# SLAM パッケージ Cartographer のインストール
$ sudo apt install ros-dashing-cartographer
$ sudo apt install ros-dashing-cartographer-ros
# ナビゲーションパッケージ Navigation2 のインストール
$ sudo apt install ros-dashing-navigation2
$ sudo apt install ros-dashing-nav2-bringup
# バージョン管理ツールのユーティリティ vcstool のインストール
$ sudo apt install python3-vcstool

もしバージョン管理ツール git をインストールしていないなら、ここで入れておきましょう。

$ sudo apt install git

Turtlebot 3 関連パッケージのインストール

# ワークスペースの作成
$ mkdir -p ~/turtlebot3_ws/src
$ cd ~/turtlebot3_ws
# 関連パッケージの取得
$ wget https://raw.githubusercontent.com/ROBOTIS-GIT/turtlebot3/ros2/turtlebot3.repos
$ vcs import src < turtlebot3.repos
# ビルド
$ colcon build --symlink-install

環境変数の設定

$ echo 'source ~/turtlebot3_ws/install/setup.bash' >> ~/.bashrc
$ echo 'export ROS_DOMAIN_ID=30 #TURTLEBOT3' >> ~/.bashrc
$ source ~/.bashrc

シミュレータのセットアップ

下記の公式ドキュメントを参考に、Gazebo によるシミュレーション環境を構築します。

emanual.robotis.com

環境変数の設定

下記の環境変数を設定して、Turtlebot3 のモデルを読み込めるようにします。

$ echo 'export GAZEBO_MODEL_PATH=$GAZEBO_MODEL_PATH:~/turtlebot3_ws/src/turtlebot3/turtlebot3_simulations/turtlebot3_gazebo/models' >> ~/.bashrc
$ source ~/.bashrc

これは好みですが、毎度ロボットモデルを指定し直すのは面倒なので、ここでは比較的軽めと思われる Waffle のモデルを呼ぶように環境変数を自動で設定するようにします。

毎回起動するロボットを変えたい場合は、.bashrc には記述せず、都度ターミナルから入力して下さい。

$ echo 'export TURTLEBOT3_MODEL=waffle' >> ~/.bashrc
$ source ~/.bashrc

起動確認

empty world

なにもない空間に Waffle を登場させます。

$ ros2 launch turtlebot3_gazebo empty_world.launch.py

初回は、必要なファイルを Gazebo のサーバからダウンロードして取得するため、少し時間がかかる場合があります。画面が止まっても、根気強く辛抱して下さい。そのうち表示されます。

f:id:MoriKen254:20200209150558p:plain

Turtlebot3 world

少し特徴のある環境に Waffle を登場させます。

$ ros2 launch turtlebot3_gazebo turtlebot3_world.launch.py

f:id:MoriKen254:20200209150641p:plain

地図作成やナビゲーションをするなら、こういう環境のほうが良いです。

キーボードで操縦

シミュレータ上のロボットをキーボードで操縦(teleop: 通称 テレオペ、テレオプ)します。ターミナルを別途開き、下記コマンドを実行します。

$ ros2 run turtlebot3_teleop teleop_keyboard

コマンドは速度形式なので、あまり調子に乗って加速すると制御しにくくなります笑。

  • 前進: w
  • 後退: x
  • 左旋回: a
  • 右旋回: d
  • 停止: s

可視化ツール RViz の起動

便利な可視化ツール RViz が起動できるか確認します。また別ターミナルを開き、下記コマンドを実行します。

$ ros2 launch turtlebot3_bringup rviz2.launch.py

起動が確認できたら、RViz を閉じて下さい。

SLAM (地図作成) の検証

下記のコマンドで Cartgrapher を起動します。

$ ros2 launch turtlebot3_cartographer cartographer.launch.py use_sim_time:=True

もし起動が不安定な場合は、Gazeboのシミュレーションを一時停止にしてから起動すると、上手く立ち上がる場合があります。数の赤枠内のボタンを押すことで、再生・一時停止を制御できます。

f:id:MoriKen254:20200209151401p:plain

RViz も同時に立ち上がりますので、正常起動を確認したら、シミュレータを再生状態に戻して下さい。

そして、先に起動した teleop のターミナルを開き、いろいろな方向に動かしながら、RViz上で地図が徐々に作成されている様をお楽しみ下さい。

f:id:MoriKen254:20200209151447p:plain

満足したら、下記コマンドで地図を保存します。

$ ros2 run nav2_map_server map_saver -f ~/map

地図を保存したら、一旦全てのプログラムを閉じておきましょう。きれいにしていたほうが、次のナビゲーションが安定しやすいです。

ナビゲーションの検証

シミュレータを立ち上げ直します。

$ ros2 launch turtlebot3_gazebo turtlebot3_world.launch.py

別ターミナルを立ち上げ、ナビゲーションプログラムを起動します。この時、先程保存した地図のファイルを読み込むように、引数で指定します。

$ ros2 launch turtlebot3_navigation2 navigation2.launch.py use_sim_time:=True map:=$HOME/map.yaml

もし、シミュレータ上でのロボットの位置、RViz上でのロボットの位置がずれていたら、画面右上の2D Pose Estimateを選択して、シミュレータ上のロボットと同じ位置になるように、地図上にマウスで指定して下さい。

f:id:MoriKen254:20200209152047p:plain

これからロボットを動かします。右上にあるNavigation2 Goalを選択し、移動させたいと思う位置と姿勢を、地図上にマウスで指定して下さい。

f:id:MoriKen254:20200209151818p:plain

あとは、自動的に経路が探索され、ロボットが障害物を回避しながら動き始めるはずです。

ここまでできたら、WindowsでROS2お試しナビゲーション祭りとしては成功です!(なんだそれ笑)

おわりに

Windows 上で、(初学者でもあまり手間をかけることなく)ROS2 を検証する方法を紹介しました。

VMWare というリッチな仮想環境を利用するので、動作は軽くはないですが、ユーザが複雑な設定をすることなく手軽に検証できるという点では、利点があると思います。

Windows でサクッとお試ししたい方のご参考になりましたら幸いです。

ROS2勉強合宿 @別府温泉 活動レポート

Qiita ROS2 Advent Calendar 2019 8日目の記事です。

題記の通り、ROS2勉強会のレポートです!

ROS Kyushu UG について

はじめに、少しご紹介を。

九州を拠点に ROS に関する活動を行うユーザグループROS Kyushu UGが発足されました!

産学、社会人学生問わず、勉強会や講演会、情報交換会や、飲み会、それから飲み会とか飲み会をゆーるくできたらいいな、と思っています。

興味の有る方は、下記のSNSでグループを形成しているので、ご参加下さい。

Slack

Facebook

Twitter

  • ハッシュタグ #q_ros

直近の活動

「新春ROS合同勉強会2020」@九州大学 を開催します。

京都大学の高瀬先生より、「組込み研究者から見たROS(Robot Operating System)」というタイトルでご講演いただきます。

ご興味のある方は、ぜひご参加下さい!

www.moriken254.com

合宿の概要

そんな我々の活動の一環として、題記合宿を企画しました!

別府温泉で、浴衣姿で酒飲みながら勉強会しました。途中で卓球もしました。

ハードだったけど、楽しかったですね!

広報チラシ

f:id:MoriKen254:20191207172115p:plain

要項

  • 日程:10/5 (土)~6 (日) 1泊
  • 場所:別府の温泉宿
  • 概要:ROS2の副読書を一気通読
  • 形態:輪行形式

副読本

かの近藤さん著、下記書籍を副読本とさせていただきました!

タイムスケジュール

下記の通り進行しました。

f:id:MoriKen254:20191207173002j:plain

発表者は九工大(西田研、田向研)、北九州高専の学生、計9名でした。ありがとうございます。

どの発表もしっかり作成され、質疑も活発に行われる、とてもエキサイティングが会でした!

勉強会資料の公開

合宿での発表で使用された資料を公開します!

先述の書籍を副読本としておりますので、その内容を大いに参考にしております。 詳細な記述や、背景なども含めたコンテンツを確認したい方は、ぜひ書籍の方をご参照下さい。

また、概論やROS1の復習に相当する第1章/第2章は割愛し、本格的にROS2のコンテンツが盛り上がる第3章以降を対象としました。

その代わり、冒頭でサーベイという形で、ROS2の概要について扱う枠を設けました。

1人目:ROS2 実用化に向けたサーベイ

ROS2の実用化という観点で雑多にサーベイをしました。(私見も入れています。)

言い訳をしておくと、情報は少し古いです(この分野、数ヶ月で陳腐化するの辛い涙)。ROSCon(or JP)2019 の情報は反映されていないので、より最新の情報はそれらのホームページを参照して下さい。(タイミングが微妙だった笑)

  • ROS2 の特長
  • ROS2 の実社会応用に向けて

www.slideshare.net

2人目:第3.1節-第3.5節 ROS2の基本機能(1/2)

  • ROS1とROS2の違い
  • ROS1とおアーキテクチャの違い
  • Data Distribution Service
  • ROS2のフロントエンドツール
  • ROS1/2パッケージ ビルドツール "colcon"

www.slideshare.net

3人目:第3.6節-第3.8節 ROS2の基本機能(2/2)

  • トピック
  • サービス
  • パラメータ

www.slideshare.net

4人目:第4.1節-第4.3節 ROS2の応用機能(1/2)

  • launch システム
  • アクション
  • ライフサイクル

www.slideshare.net

5人目:第4.4節-第4.8節 ROS2の応用機能(2/2)

  • QoS
  • DDSベンダの変更
  • セキュリティ
  • ROS1ノードの互換性
  • リアルタイム制御

www.slideshare.net

6人目:第5.1節-第5.7節 ROS2に対応したツール/パッケージ

  • rosbag2
  • rviz2
  • ros2_intel_realsense
  • navigation2
  • cartgrapher
  • moveit2
  • Gazebo
  • Ignition Acropolis

www.slideshare.net

7人目:第6.1節-第6.5節 Roomba用ROS1ドライバのROS2移行(1/2)

  • RoombaとROSの歴史
  • シリアル通信ケーブルの入手
  • RoombaのROS1ドライバ
  • 著者作ROS2版パッケージ
  • package.xmlの更新

www.slideshare.net

8人目:第6.6節-第6.9節 Roomba用ROS1ドライバのROS2移行(2/2)

  • メッセージ,サービス,アクション定義の更新
  • ビルドシステムの変更
  • ソースコードの更新
  • まとめ

www.slideshare.net

9人目:第7.1節-第7.5節 Pythonクライアントライブラリ rclpy

  • ROS2のクライアントライブラリ
  • パッケージ構成
  • トピック実装
  • サービス実装
  • アクション実装

www.slideshare.net

おわりに

合宿に参加した皆さん、お疲れさまでした。私の頭がおっついてないところがありますが、おかげでROS2の全体像を掴むことができました。

中々ハードでしたが、学生で集まってワイワイ勉強するの、楽しかったです!

何より、やらされ感ではなく、自主的に参加してくれたのが嬉しいです。

そんな学生さんたちの純粋で高いモチベーションからできあがった勉強会資料を共有致した次第です。少しでも他のデベロッパに貢献できればと思います。

下書籍にはかなり助けれらました。本内容について、より詳細な解説が欲しい方は、ぜひ下書籍をご参照下さい!

【ROS】「新春ROS合同勉強会2020」@九州大学のご案内

概要

題記の通り、九州大学で勉強会が行われますので、ご案内です!

京都大学の髙瀬英希先生をお招きして講演会を行います. ご興味のある方は是非,ご参加ください.

日時

2020年1月8日(水) 16:40 - 17:50

会場

九州大学伊都キャンパス ウェスト2号館3階 システム情報大講義室(W2-313)

キャンパスマップ「31番」

https://www.kyushu-u.ac.jp/f/37269/2019ito_3.pdf

会場アクセス

https://www.kyushu-u.ac.jp/ja/campus/ito/ 注:イベントに関する案内板はありません.

講演者

高瀬英希 准教授(京都大学/JSTさきがけ)

講演タイトル

組込み研究者から見たROS(Robot Operating System)

講演概要

ロボットシステムは多機能/高機能を求められつつも多品種少量生産のドメインであるため,開発を効率化するプラットフォームの活用は不可欠です.Robot Operating System(ROS)は,ロボットソフトウェアの開発を加速できるプラットフォームとして非常に注目されています.本講演の前半では,ROSの生まれた背景や目指すところを俯瞰したのち,ROSの提供する機能や採用すべき利点について解説します.また,現在開発が急ピッチで進んでいる次世代のROS2についてもその新機能と利点を紹介します.時間が許せば,マカオで開催されたROSCon2019の概要を紹介しながら,世界的なROS communityの動向についても紹介できればと思います.講演の後半では,講演者らが研究開発に取り組んでいるROS関連の活動について紹介します.組込みマイコン向けのROSノードの軽量実行環境「mROS」,ROS対応ロボットへのFPGA技術の統合を実現する「ZytleBot」,IoT/自動運転時代の仮想シミュレーション環境「箱庭」,これらを駆け足で紹介しながら,ロボット分野におけるこれからの組込み分野の役割について議論してみます.

講演者略歴

京都大学 大学院情報学研究科 通信情報システム専攻 准教授 国立研究開発法人 科学技術振興機構 さきがけ研究者(兼任) 組込みシステムの省電力設計ならびに協調設計技術,IoT/ロボットシステム向け開発プラットフォーム技術の研究に従事.

参加費:無料

問い合わせ: 九州大学・後藤まで takayuki.goto at cpc.ait.kyushu-u.ac.jp

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

前回の記事で、ようやくリリースの前準備が完了しました。

www.moriken254.com

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

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

release 後の作業を事前確認

いよいよリリースツール、bloomを使います!

f:id:MoriKen254:20190609211332j:plain


bloom コマンド実行

さ、bloomのリリースコマンドを叩きます。

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

初めてなので、timed_roslaunchのリリースリポジトリなんてねーよゴルァ!と言われます。お初なんですから当然です。気にせず眺めてみましょう。

ROS Distro index file associate with commit '42bdb05c4d8fe3daac5c17751138f88f47b748c8'
New ROS Distro index url: 'https://raw.githubusercontent.com/ros/rosdistro/42bdb05c4d8fe3daac5c17751138f88f47b748c8/index.yaml'
Specified repository 'timed_roslaunch' is not in the distribution file located at 'https://raw.githubusercontent.com/ros/rosdistro/42bdb05c4d8fe3daac5c17751138f88f47b748c8/kinetic/distribution.yaml'
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: https://github.com/ros-gbp/rviz-release.git

別 distribution 探索

別distributionでも探してくれます。すげー。まぁ、いないんですけど。

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

というわけで、諦めてくれたようなので、ここで地道に手打ちでリリースリポジトリを指定します。指定するリリースリポジトリは空のものを作っておきましょう。一般的にリリースリポジトリ名は、pkg名-releaseです。

Release repository url [press enter to abort]: https://github.com/MoriKen254/timed_roslaunch-release.git

release リポジトリの更新

何やらローカルのtmpの下にクローンし始めます。

f:id:MoriKen254:20190609212535j:plain


==> Fetching 'timed_roslaunch' repository from 'https://github.com/MoriKen254/timed_roslaunch-release.git'
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.

ここからが本番です。リリースするリポジトリの情報をbloomに教えてあげましょう。

f:id:MoriKen254:20190609213208j:plain


アーカイブ上の名前はtimed_roslaunchとします。

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

ソースリポジトリのURIです。https://github.com/MoriKen254/timed_roslaunch.git を指定します。

Upstream Repository URI:
  <uri>
    Any valid URI. This variable can be templated, for example an svn url
    can be templated as such: "https://svn.foo.com/foo/tags/foo-:{version}"
    where the :{version} token will be replaced with the version for this release.
  [None]: https://github.com/MoriKen254/timed_roslaunch.git

先程指定したリポジトリのバージョン管理システムを指定します。timed_roslaunchの場合はgitです。

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

バージョン番号の指定方法です。デフォルトのautoにしておけば、package.xmlから勝手に抽出してくれますので、ここはデフォルトのまま未入力でエンター。

Version:
  :{ask}
    This means that the user will be prompted for the version each release.
    This also means that the upstream devel will be ignored.
  :{auto}
    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.
  <version>
    This will be the version used.
    It must be updated for each new upstream version.
  [':{auto}']: 

リリースタグの指定です。基本はバージョンのタグと同一で良いので、ここもデフォルトのversionのまま無記入でエンター。

Release Tag:
  :{none}
    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.
  :{ask}
    This means the user will be prompted for the release tag on each release.
  :{version}
    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).
  [':{version}']: 

リポジトリのブランチです。今回のケーススタディでのtimed_roslaunchの場合はkinetic-develという名称のブランチです。

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
  ['kinetic']:     

パッチのディレクトリを指定できるらしい。基本はデフォルトで良いらしいので、エンター。

Patches Directory:
  :{none}
    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.
  [None]: 

ros-distro への登録

ここまで登録した内容をros-distroにプッシュします。

f:id:MoriKen254:20190609212928j:plain


ここも基本はデフォルトで良いらしいので、エンター。

Release Repository Push URL:
  :{none}
    This indicates that the default release url should be used.
  <url>
    (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.
  [None]: 

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

Created 'kinetic' track.

release 前の事前確認

f:id:MoriKen254:20190609213500j:plain


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

==> Testing for push permission on release repository

リモートリポジトリの情報を確認します。

==> git remote -v
origin  https://github.com/MoriKen254/timed_roslaunch-release.git (fetch)
origin  https://github.com/MoriKen254/timed_roslaunch-release.git (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 'https://github.com': MoriKen254
Password for 'https://MoriKen254@github.com': 
To https://github.com/MoriKen254/timed_roslaunch-release.git
   19e4882..0df3439  master -> master

実際のリリース処理を開始する

ようやくリリースです笑。

f:id:MoriKen254:20190609213858j:plain


==> 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'

アーカイブの作成

まだローカルでの作業です。

f:id:MoriKen254:20190609220219j:plain


ソースリポジトリを「tar.gz」形式でアーカイブしている模様です。

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

==> bloom-export-upstream /tmp/tmp4Jv15O/upstream git --tag 0.1.1 --display-uri https://github.com/MoriKen254/timed_roslaunch.git --name timed_roslaunch --output-dir /tmp/tmpl4sxFc
Checking out repository at 'https://github.com/MoriKen254/timed_roslaunch.git' 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.
done.
md5: 386c49c2a9e913c13f8502c8a30df847

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

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

f:id:MoriKen254:20190609220634j:plain


==> 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 することになります。

f:id:MoriKen254:20190609221033j:plain


==> git remote -v
origin  https://github.com/MoriKen254/timed_roslaunch-release.git (fetch)
origin  https://github.com/MoriKen254/timed_roslaunch-release.git (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 'https://github.com': MoriKen254
Password for 'https://MoriKen254@github.com': 
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.
To https://github.com/MoriKen254/timed_roslaunch-release.git
   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)
To https://github.com/MoriKen254/timed_roslaunch-release.git
 * [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を送る処理に進みます。

f:id:MoriKen254:20190609222424j:plain


設定

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

==> Generating pull request to distro file located at 'https://raw.githubusercontent.com/ros/rosdistro/42bdb05c4d8fe3daac5c17751138f88f47b748c8/kinetic/distribution.yaml'
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 [https://github.com/MoriKen254/timed_roslaunch.git]: 
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 [https://github.com/MoriKen254/timed_roslaunch.git]: 
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 http://wiki.ros.org/buildfarm/Pull%20request%20testing 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 @@
       url: https://github.com/ROBOTIS-GIT/ROBOTIS-THORMANG-Tools.git
       version: kinetic-devel
     status: developed
+  timed_roslaunch:
+    doc:
+      type: git
+      url: https://github.com/MoriKen254/timed_roslaunch.git
+      version: kinetic-devel
+    release:
+      tags:
+        release: release/kinetic/{package}/{version}
+      url: https://github.com/MoriKen254/timed_roslaunch-release.git
+      version: 0.1.1-2
+    source:
+      test_pull_requests: true
+      type: git
+      url: https://github.com/MoriKen254/timed_roslaunch.git
+      version: kinetic-devel
+    status: maintained
   timesync_ros:
     doc:
       type: git

うん、いいんじゃないですかね笑。次!

ros-distro の fork

ここからros-distroのリポジトリをforkしてPRって流れに。

f:id:MoriKen254:20190609222745j:plain


まず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: https://github.com/MoriKen254/timed_roslaunch.git
- release repository: https://github.com/MoriKen254/timed_roslaunch-release.git
- 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

はぁ、ようやくPRです。

f:id:MoriKen254:20190609222815j:plain


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.
From https://github.com/ros/rosdistro
 * 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:
remote:      https://github.com/MoriKen254/rosdistro/pull/new/bloom-timed_roslaunch-0
remote: 
To https://ad298882a971af397ffbb38e2ac9bfb6094de614:x-oauth-basic@github.com/MoriKen254/rosdistro.git
 * [new branch]      bloom-timed_roslaunch-0 -> bloom-timed_roslaunch-0
<== Pull request opened at: https://github.com/ros/rosdistro/pull/19405

おお!リリースできた!やった!やった!

bloom:「私、嬉しいわ。あなたもよね?」
MoriKen:「えぇ、まじで嬉しいっす!」

どうでもいいっすね笑。

この先は?

これ以降は、以下のような流れです。

f:id:MoriKen254:20190609223743j:plain


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

今は、ここで扱ったtimed_roslaunchを下記コマンドで取得可能です。

sudo apt install ros-kinetic-timed-roslaunch

おわりに

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

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

とりあえずたたき台ということで、まずは公開です!

より多くのROSデベロッパの皆さまが、bloomを活用できるようになることを願っています。

www.moriken254.com

Buildfarm+bloomで自作ROS pkg をaptやrosdepで取得可能にする!①前準備編

ある程度ROSでのアプリケーション開発に慣れてくると、aptでインストールしたり、rosdepで依存関係を解決したくなりますよね(なりません?なりますよね。)。

それを楽ちんにしてくれるのがbloomというツールです。

とはいえ、実際にやってみようと思うと、結構心理的障壁が高かったりします。

もちろんROS Wikiをみれば情報はあるし、ご丁寧に日本語訳まであります。

あとはこれに従えばいいのですが、それでも実際にやるにはどうにもハードルが高い気がして、手が伸びないというのが、多くの方にとっての本音ではないでしょうか。

かく言う私自身、本当に大丈夫だろうかとヒヤヒヤしながらbloomでリリース作業をしました。

自分がその時のヒヤヒヤ感をもう二度と味わいたくないのと笑、同じような思いを抱えてらっしゃるROSデベロッパの方と情報を共有できたらなと思いまして。

というわけで、その手順を記していこうと思います。

大枠の流れは、目次を参照下さい。作業順に沿って並んでいます。

ケーススタディのネタ

今回ケーススタディとする対象のネタは、小生が開発した timed_roslaunch というパッケージです。指定秒だけ launch ファイルの実行タイミングを遅らせることができるユーティリティです。

github.com

wiki.ros.org

概念図

私が実際に作業してみた経験を元に、このようになっているのだろうというイメージを作成してみました。(誤りがございましたらご指摘頂けましたら幸いです。)

f:id:MoriKen254:20190609204332j:plain


自作パッケージを完成させる

まずは、自作パッケージを作りましょう(当たり前笑)。

f:id:MoriKen254:20190609210459j:plain


そして、以下の点に注意しましょう。

依存関係を正確に記述する

パッケージには、マニフェスト情報であるpackage.xmlと、cmake用の設定ファイルであるCMakeLitst.txtが格納されており、これらに自作パッケージの依存関係を正確に記述する必要があります。

なぜなら、Buildfarmに登録された場合、CIによるビルドジョブが走るので、依存関係をしっかりかかないとビルドステータスがFailになってしまいます。

これは、配布先のユーザ側でも、せっかくインストールしたのに自分で依存関係を解決しなければならないという辛い状態になりますし、自分自身が使うときにも苦労するでしょう。

ここではその設定方法について細かく書くつもりはありませんが、最低限依存関係だけでも確認は必須です。駆け足ですが、概要だけ。

package.xml
  • 〈depend〉タグ

    • ビルド時、実行時、エクスポート時で必要なパッケージ。
  • 〈build_depend〉タグ

    • ビルド時に必要なパッケージ。でもエクスポートがいらないならこれだけでいいです。
  • 〈exec_depend〉タグ

    • 実行時に必要なパッケージ。
  • 〈test_depend〉タグ

    • テスト時に必要なパッケージ。
CMakeLists.txt
  • find_package

    • パッケージの存在確認をします。
    • catkin に含まれるパッケージを確認します。
    • find_package はされているけど、catkin_package内でCATKIN_DEPENDSされていないものは、エクスポートが不要なので、package.xmlで〈build_depend〉と〈exec_depend〉に加えます。
  • catkin_package

    • catkinでビルドする際の依存パッケージの設定をします。
    • CATKIN_DEPENDS されているパッケージはエクスポートが必要なので、〈depend〉 に入れます。
  • install

    • down_stream パッケージが利用する際に必要なファイルは全て install 指定します。
参考ドキュメント

詳細は公式をご参照下さい。

docs.ros.org

※正直依存関係周りは、このネタだけで記事が一本書けるくらいの話です。分からなくてもとにかく、ここではもう作業として割り切って、必要な依存関係を記述しきっちゃて下さい。最悪全部〈depend〉 にしちゃっても、ビルドは通ってしまうはずですので(気持ちは悪いですが笑)。

CHANGELOG.rstの登録

f:id:MoriKen254:20190609210523j:plain


作業がローカルなのに、なんで図でリモートを指しているのかと思われた方がいらっしゃったら、ちょっと待ってください。

Push するところまで含めてCHANGELOG.rstの登録とさせて下さい。(この作業におけるワークスペースまで図示すると、図全体の均衡が保てなくなるので、少々ご辛抱を ^^;)

generate

まずはCHANGELOG.rstを作成します。

$ catkin_generate_changelog --all
Found packages: timed_roslaunch
Querying all tags and commit information...
Generating changelog files with all versions...
- creating './CHANGELOG.rst'
Done.
Please review the extracted commit messages and consolidate the changelog entries before committing the files!

差分を確認してみましょう。

$ git status 
ブランチ kinetic-devel
追跡されていないファイル:
  (use "git add <file>..." to include in what will be committed)

    CHANGELOG.rst

nothing added to commit but untracked files present (use "git add" to track)

CHANGELOG.rst が作成されているのが分かります。中身も確認しておきます。

$ git diff
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 2b3320..7100568 100644
--- a/CHANGELOG.rst
--- b/CHANGELOG.rst
@@ -2,6 +2,13 @@
 Changelog for package timed_roslaunch
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
<br>
+Forthcoming
+-----------
+* Merge pull request
+  Modify CMakeLists for launch  and test dir install
+* Modify CMakeLists for launch  and test dir install
+* Contributors: MoriKen254
+
 0.1.2 (2018-11-09)
 ------------------
 * Fix install scripts in CMakeLists

コミットログが入ります。変なコミットメッセージを入れると、恥を晒すことに…(オイ)。

commit & push

上記の差分をコミットし、リモートにプッシュします。

$ git add --a

$ git commit -m "Add CHANGELOG.rst"
[kinetic-devel 45a9cf9] Add CHANGELOG.rst
 1 file changed, 75 insertions(+)
 create mode 100644 CHANGELOG.rst

$ git push origin kinetic-devel 
Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 1.92 KiB | 0 bytes/s, done.
Total 3 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
To https://github.com/MoriKen254/timed_roslaunch
   57a995e..45a9cf9  kinetic-devel -> kinetic-devel

releaseの前準備

package.xml 内の ver. 番号をインクリします!

f:id:MoriKen254:20190609210908j:plain


以下のコマンドを打ちましょう。

$ catkin_prepare_release 

すると、現在のpackage.xmlを解析して、リリースバージョンをインクリするコミットが生成されます。

Prepare the source repository for a release.
Repository type: git
Found packages: timed_roslaunch
Prepare release of version '0.1.3' [Y/n]?y
Trying to push to remote repository (dry run)...
Everything up-to-date
Checking if working copy is clean (no staged changes, no modified files, no untracked files)...
Rename the forthcoming section of the following packages to version '0.1.3': timed_roslaunch
Bump version of all packages from '0.1.2' to '0.1.3'
Committing the package.xml files...
[kinetic-devel 46cfd23] 0.1.3
 2 files changed, 3 insertions(+), 3 deletions(-)

次に、インクリ後のリリースバージョンのタグも生成します。

Creating tag '0.1.3'...

先程のコミットとタグを両方リモートにプッシュしても良いかを尋ねられます。もちろんyes!

The following commands will be executed to push the changes and tag to the remote repository:
  /usr/bin/git push origin kinetic-devel
  /usr/bin/git push --tags
Execute commands to push the local commits and tags to the remote repository [Y/n]?y

まずはコミットをプッシュ。

Counting objects: 4, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 377 bytes | 0 bytes/s, done.
Total 4 (delta 3), reused 0 (delta 0)
remote: Resolving deltas: 100% (3/3), completed with 3 local objects.
To https://github.com/MoriKen254/timed_roslaunch.git
   45a9cf9..46cfd23  kinetic-devel -> kinetic-devel
Total 0 (delta 0), reused 0 (delta 0)

次にタグをプッシュ。

To https://github.com/MoriKen254/timed_roslaunch.git
 * [new tag]         0.1.3 -> 0.1.3
The source repository has been released successfully. The next step will be 'bloom-release'.

おわりに

これにて、①前準備編は完了です。

実際のリリース作業は次回の記事で記述します。次回の方がちとややこしいのですが。ま、ぶっちゃけ bloom が勝手にやってくれるので、こっちは眺めているだけなのですが笑。便利なものです。

www.moriken254.com

GitLab CI を使って GitHub の Private Repository を無料で CI ③SSH 編

はじめに

さて、前回まででミラーリングの設定が完了しました。

www.moriken254.com

ここからは、SSH の設定に入っていきます。外部の Private Repository に依存している場合には、SSH 認証によってクローンするしか術がないからです。

f:id:MoriKen254:20190601192608p:plain


GitLab CI はそんなこともあろうかと言わんばかりに、WEBシステムから環境変数を設定できるような仕様になっています。(さもないと、.gitlab-ci.ymlに秘密鍵を直書きしなければならなくなり、いくらPrivateリポジトリとは言え、さすがにそれは品位を欠くわけでして汗。)

てなわけで、その辺の設定方法を含めて、ノウハウを共有します。

今回は、GitLab CI 側から、GitHub の Private Repository をクローンするという構成を取ります。

よって、GitLab CI に秘密鍵を、GitHub の Private Repository に公開鍵を渡すように設定を行っていきます。

SSH 鍵ペアの作成

まずは、秘密鍵と公開鍵のペアを作成します。

f:id:MoriKen254:20190601225508p:plain


GitLab の公式ドキュメントを参照します。

docs.gitlab.com

ローカルで以下のコマンドを実行します。当方ではRSAでの実績があります。

メアドはなくてもいけるみたいですが、公式に従って入れておきます。GitHubに登録しているメールアドレスを入力します。

パスフレーズは無しで。

$ ssh-keygen -o -t rsa -b 4096 -C "email@example.com"
Generating public/private rsa key pair.
Enter file in which to save the key (/home/karuma/.ssh/id_rsa): ← Enter
Created directory '/home/yourname/.ssh'.
Enter passphrase (empty for no passphrase): ← Enter
Enter same passphrase again: ← Enter
Your identification has been saved in /home/yourname/.ssh/id_rsa.
Your public key has been saved in /home/yourname/.ssh/id_rsa.pub.

これで、以下のように鍵が生成されました。

  • 秘密鍵:~/.ssh/id_rsa
  • 公開鍵:~/.ssh/id_rsa.pub

GitLab CI への秘密鍵の登録

作成した秘密鍵を GitLab CI に登録します。

f:id:MoriKen254:20190601232317p:plain


まず、秘密鍵をクリップボードに格納します。

 xclip -sel clip < ~/.ssh/id_rsa

次に、GitLab CI の環境変数登録画面に遷移します。

「インポートした Private Repository」→「Settings」→「CI/CD」を選択し、「Variables」を展開します。

f:id:MoriKen254:20190601193444p:plain


SSH 秘密鍵について、以下のように入力します。

  • Type: Variable
  • Key: SSH_PRIVATE_KEY
  • Value: 先程クリップボードに入れた変数をペースト
    • -----BEGIN/END RSA PRIVATE KEY----- から始まるもの。
  • State: Protected を解除
  • Maked: Masked を解除
f:id:MoriKen254:20190601193648p:plain


次に、known hosts の情報を設定します。対象は GitHub です。

$ ssh-keyscan github.com
# github.com:22 SSH-2.0-babeld-80573d3e
github.com ssh-rsa ここに HOST KEY の文字列が入る
# github.com:22 SSH-2.0-babeld-80573d3e
# github.com:22 SSH-2.0-babeld-80573d3e

出力のうち、 # がついていない 2 行目のgithub.com ssh-rsa ここ文字列が入るの部分を、以下のように GitHub の取りうるIP アドレス(192.30.252.*,192.30.253.*,192.30.254.*,192.30.255.*)を挿入した形に置き換えます。

github.com,192.30.252.*,192.30.253.*,192.30.254.*,192.30.255.* ssh-rsa ここ文字列が入る

そして、下記のようにブラウザから入力します。

  • Type: Variable
  • Key: SSH_SERVER_HOSTKEYS
  • Value: github.com,192.30.252.*,192.30.253.*,192.30.254.*,192.30.255.* ssh-rsa ここに HOST KEY の文字列が入る をペースト
  • State: Protected を解除
  • Maked: Masked を解除
f:id:MoriKen254:20190601212246p:plain


そして、「Save variables」をクリックし、環境変数を保存します。

実は、この変数は ROS の industrial_ci を利用する際の環境変数に準拠しているので、同分野で GitLab CI を利用する人にとっては、この設定を踏襲する方が移行がスムーズになります。

github.com

GitHub への公開鍵の登録

続いて、GitHub 側に公開鍵を登録します。

f:id:MoriKen254:20190601212838p:plain


まず、公開鍵をクリップボードに格納しておきます。

 xclip -sel clip < ~/.ssh/id_rsa.pub

GitHub のページから、クローン対象の Private Repository を開きます。「Settings」→「Deploy keys」→「Add deploy key」を選択します。

f:id:MoriKen254:20190601214621p:plain


「Title」に鍵の名称(例えば、SSH_PUBLIC_KEY_FOR_GITLAB_CI とか)を入力し、「Key」に先程コピーした公開鍵をペーストします。

f:id:MoriKen254:20190601214907p:plain


「Add key」を押下し、鍵を登録します。

f:id:MoriKen254:20190601215527p:plain


.gitlab-ci.yml へ SSH 認証コマンドを追加

まだ続きます。これまでに登録した SSH の設定を、CI 空間で有効にするために、.gitlab-ci.ymlbefore_script: に然るべきコマンドを追加します。

f:id:MoriKen254:20190601215952p:plain


ここでは、.gitlab-ci.ymlbefore_script 部分の、しかも SSH 認証で必要となる部分だけ抜粋して記載します。対象の依存 Repository をクローンする前に以下のコマンドを挿入すれば、SSH 認証は通るはずです。

before_script:
  - mkdir -p ~/.ssh
  - echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa # 秘密鍵作成
  - chmod 600 ~/.ssh/id_rsa # 秘密鍵の権限編集
  - ssh-add ~/.ssh/id_rsa # SSH 登録
  - echo "$SSH_SERVER_HOSTKEYS" > ~/.ssh/known_hosts # ホスト登録
  - これ以降はプロジェクト次第

このコマンドを GitHub 側から追加しておきます。あとは、Push 後に GitLab CI が動くのを待つのみです。

ユーザ操作によるミラーリング

実は、GitHub 側で Push しても、GitLab 側で即それを検知してくれるわけではありません。

そう、ミラーリングのタイミングは、コールバックではなくポーリングなのです。長いと30分くらい待つこともあります。いやいや、いくら無料とは言え、CI デバッグをしている身としては、これはきついです涙。

f:id:MoriKen254:20190601221701p:plain


というわけで、GitHub 側でプッシュした後に、ミラーリング先の GitLab からユーザ操作でミラーリングする方法を共有します。少々面倒ですが、ポーリングで時間を食うよりマシです。

「インポートした Repository」のページから、「Settings」→「Repository」を選択し、「Mirror a repository」を展開します。先程のミラーリングの設定画面です。

下の方にある「Mirrored repositories」で右側にある更新を彷彿とさせるロゴを有したミラーリングボタンを押下します。Last update の時間が更新されれば、手動ミラーリングの完了です!

f:id:MoriKen254:20190601171624p:plain


GitLab CI Job にて SSH 認証の確認

以上の設定でちゃんと GitLab ⇔ GitHub 間で SSH 認証ができているか、確認してみましょう。

「インポートした Private Repository」→「CI/CD」を展開→「Piplelines」を選択→「Job ステータス」を選択、と操作します。ここでは既に成功している Job を選択するので、「passed」と表示されている部分を選択します。(実際にデバッグする時は failed を表示された赤いアイコンをクリックすることになるのですが笑。)

f:id:MoriKen254:20190601222650p:plain


展開したページから「Pipeline 名」を選択します。当方のケースではたまたま「kinetic」という名前をつけていているので、これを選択します。

f:id:MoriKen254:20190601223059p:plain


展開先のページで、最新の Job の実際の出力を確認できます。

f:id:MoriKen254:20190601223157p:plain


このうち、冒頭の before_scripts 部分を見に行けば、SSH 認証時のメッセージが見られます。

f:id:MoriKen254:20190601223257p:plain


ここで、下記のようなメッセージが表示されていれば、SSH 認証は成功しています。

Agent pid hoge
Identity added: /dev/hoge/hoge (メールアドレス)

ここまでできて晴れて、依存する Private Repository を巻き込んだ上で、Private Repository の CI を通すことができるようになります。

長かったー汗。

おわりに

GitHub x Travis CI で Private Repository を CI しようとしたらお金がかかってしまう問題を、GitLab CI で解決する方法を記述しました。

きっと、同じような状況で困っているエンジニアがいるはず!

そんなエンジニアにとって、この記事が少しでもお役に立てることを願っています。

前回:② ミラーリング編

www.moriken254.com

GitLab CI を使って GitHub の Private Repository を無料で CI ②ミラーリング編

はじめに

さて、タイトルの通りです。前回は背景を話しましたが、今回からは具体的なチュートリアルに入っていきます。

www.moriken254.com

まずは、ミラーリング編。GitHub の Repository をGitLab にミラーリングしないと、GitLab CI にかけることができませんので、その手順を示します。

その後、CI を有効にするための設定ファイルを準備します。

依存する Repository を CI にクローンする方法の方はちょっとゴチャゴチャするので、次回に持ち越すことにします。

GitLab にログイン

GitLab にログインしないと何も始まりませんね。

about.gitlab.com

f:id:MoriKen254:20190601162054p:plain


GitHub の Repository をミラーリングするので、GitHub のセッション経由でログインをします。

f:id:MoriKen254:20190601162344p:plain


Repository のインポート

CI をする対象となる GitHub の Repository を GitLab にインポートします。

f:id:MoriKen254:20190601162525p:plain


左上の「Projects」→「Your Projects」→右上の「New Projects」を選択します。

f:id:MoriKen254:20190601162814p:plain


「Import Project」を選択します。

f:id:MoriKen254:20190601163025p:plain


「GitHub」を選択します。

f:id:MoriKen254:20190601163119p:plain


「インポート元の GitHub Private Repository」を選択します。このとき、「インポート先の GitLab User / Group」も選択できるので、然るべきインポート先にしておいて下さい。間違えると面倒なので。そして、「Import」を押下します。

f:id:MoriKen254:20190601163227p:plain


選択した Repository が一覧の先頭に移動します。インポート中であれば「Running...」と表示されます。

f:id:MoriKen254:20190601232003p:plain


インポートが完了すれば、「Done」と表示されます。

f:id:MoriKen254:20190601163737p:plain


Repository のミラーリング

次に、ミラーリング設定を行います。実は、インポートをしただけでは GitHub 側の Repository と同期を取ってくれるわけではないのです。

明示的にミラーリング設定を追加しないと、インポートした Repository は、GitHub 側で変化が起きたとしても、初回インポートの状態ままになってしまいます。CI したくて GitLab にやってきたのに、同期されないのでは意味がありませんね。

f:id:MoriKen254:20190601164118p:plain


てなわけで、設定ページに参りましょう。

「インポートした Repository」のページから、「Settings」→「Repository」を選択します。

表示されたページ内の「Mirror a repository」を展開すると、設定項目が出てきます。

f:id:MoriKen254:20190601164641p:plain


ミラーリング元の GitHub Repository の URL を入力する欄がありますが、少し注意が必要です。その Repository にアクセスできる GitHub ユーザ ID を URL に挿入します。書式は下図を参照下さい。

ミラーリング方向は「Pull」、認証は「Password」、Password には「GitHubのパスワード」、Mirror userは「Private Repository にアクセス可能な GitHub ユーザ名」となります。

このユーザは必ずしも自分自身である必要はなく、共通ユーザなどを持っていて、そのユーザが対象 Repository へのアクセス権を持っていれば、そのユーザを設定することもできます。

そして必要項目にチェックを入れて(下図参照)、「Mirror repository」をクリック!これでミラーリングが開始されます。

f:id:MoriKen254:20190601164835p:plain


「Mirror repository」ボタン直下にある「Mirrored repositories」の「Last update」に最新更新時間が記載されれば、ミラーリング成功です!

f:id:MoriKen254:20190601165702p:plain


CI の有効化

CI を有効化するために、GitHub 側のリポジトリにあるファイルを追加します。

そう、.gitlab-ci.yml です。

f:id:MoriKen254:20190601171725p:plain


この記事ではこの内部の書式について細かくは語りません。ここは、ユーザアプリ次第ですので、他記事による良質な解説に譲らせていただきます。

qiita.com

とにかく、この.gitlab-ci.ymlにしかるべき設定を記述した上で、 GitHub Repository 直下に格納し、リモートにプッシュして下さい。

私の開発分野でのユースケースですが、以下に例を示します。

cd "ミラーリング元の GitHub のローカル Repository 最上位ディレクトリ"
vim .gitlab-ci.yml

yml の例です。ROS の industrial_ci を用いる場合です。何度も言いますが、このファイルの中身は、ご自身の開発プロジェクトの内容に合わせて適切なものに置き換えて下さい。

image: docker:git
services:
  - docker:dind
before_script:
  - apk add --update bash coreutils tar
  - git clone --quiet --depth 1 https://github.com/ros-industrial/industrial_ci .industrial_ci
  
kinetic:
  script:
    - .industrial_ci/gitlab.sh
  variables:
    ROS_DISTRO: "kinetic"
    CATKIN_LINT: "true"
    OPT_VI: "-vi"

上記ファイルを保存して、あとはリモートにプッシュしておいて下さい。

それ以外の設定(Runner 等)は全てデフォルトでも基本は大丈夫ですので、この記事では扱いません。

おわりに

これで、最低限 GitLab CI を有効にするためのミラーリング設定は完了です。

次は、依存するプライベート Repository を クローンできるように、SSH 認証を行えるようにする手順を述べます。

次回:③SSH 編

www.moriken254.com

前回:①背景編

www.moriken254.com