GitHub ActionsでROS 2のビルド・テストを自動化する
海洋ロボコンをやってた人です。
今回はGitHub Actionsを触ってROS 2のパッケージのcolcon build
とcolcon test
を自動化してみたので、その備忘録として記載していきます。
GitHub Actionsは、GitHub上で利用可能なCI/CDツール※1, 2です。GitHub Actionsを使用すると、ソフトウェア開発プロジェクトのビルド、テスト、デプロイなどの一連のタスクを自動化することができます。
※1 CI: Continuous Integration(継続的インテグレーション)
※2 CD: Continuous Deployment(継続的デプロイメント)
記事を書いた理由は以下です。
- CI/CDを触りながら学びたいため
- 後から使い方を自分で見直せるようにするため
初学者なので、何かコメントあれば積極的に募集します。
では、早速記載していきますね。
※ 2023/8 GitHub ActionsとJenkinsどっちを使用するのが良いのか?という疑問に対しては、使用する際の環境と以下の相違点を踏まえて判断していただければと思います。
ROS 2のテストとは
ビルド・テスト・デプロイメントなどのプロセス自動化での、ビルドはcolcon build
などで馴染みがあると思いますが、テストとデプロイはあまりイメージがなかったので、以下にメモを記載しておきます。
ROS 2 でソースコードのテストを行うには以下を実行します。
colcon test --packages-select package_name
実行後にxxx_ws下のlogファイルを見てみると、様々なテストが行われているのが分かります。
The following tests FAILED:
[0;31m 1 - copyright (Failed)[0;0m
[0;31m 2 - cppcheck (Failed)[0;0m
[0;31m 3 - cpplint (Failed)[0;0m
[0;31m 4 - lint_cmake (Failed)[0;0m
[0;31m 5 - uncrustify (Failed)[0;0m
[0;31m 6 - xmllint (Failed)[0;0m
上記ですが、cppcheck
やcpplint
など必要なパッケージをインストールしていないと上記のように全項目Failedが表示されるので、以下もインストールしました。
sudo apt install ros-humble-ament-cppcheck
sudo apt install ros-humble-ament-cpplint
sudo apt install ros-humble-ament-lint-cmake
sudo apt install ros-humble-ament-uncrustify
sudo apt install ros-humble-ament-xmllint
あとはlogファイルに書いてあるエラーを見ながら、テスト項目をクリアできるようにプログラムを修正していけば良さそうです。
参考までに、自分が引っかかったエラー項目に対しての対策一覧を記載しておきます。
- copyrightが先頭にあること
- a < bと演算子の両端にスペースが入っていること
- Tabでなくspace推奨
- ファイル末尾に改行文字があること
- 空白行にインデントが入っていないこと
- コードブロック開始部分(関数の始め)の余分な空白行を削除すること
- void function()で改行し { は次行に書くこと
デプロイでは、Gitを使用して特定のバージョンやブランチのコードを本番環境(アプリケーションやウェブサイト)に展開させます。
思いつく案としては、GitでROS 2 パッケージをpush後、GitHub Actionsでビルド、テストが実行され、ssh等でロボット側へアクセス&pullでデプロイする形でしょうか。
このあたりは、あくまで私の想定ですので各自調べてくださいね。
GitHub ActionsでROS 2のビルドとテストをする
GitHub ActionsではGitHub Actions の課金についてによると、パブリックリポジトリは無料、プライベートリポジトリでは制限範囲内(使用時間 (分) とストレージ)であれば無料という形になっています。
なので、上記で説明したtestなどをGitHub Actionsで試すためのROS 2パッケージサンプルを以下のように準備しました。
以降、こちらを利用して説明していきます。
Actions用のymlを作成する
まずはpublicリポジトリに移動し、Actionsから.github/workflows/xxx.yml
へGitHub Actions用の設定ファイルを作成します。
デフォルトで準備してあるものを使用しない場合は、Skip this and set up a workflow yourself
を選択してymlを直書きします。
name: build and test
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
workflow_dispatch:
schedule:
- cron: '0 0 * * *'
release:
types: [published]
jobs:
build_and_test:
strategy:
matrix:
os:
- ubuntu-22.04
rosdistro:
- humble
runs-on: ubuntu-latest
container:
image: ros:${{ matrix.rosdistro }}-ros-base
steps:
- name: Setup directories
run: mkdir -p ros2_ws/src
- name: Check out repository
uses: actions/checkout@v3
with:
path: ros2_ws/src/ros2_topic_sample
- name: Install dependencies
run: |
rosdep update &&
apt-get update &&
rosdep install --from-path . -i -y --rosdistro ${{ matrix.rosdistro }}
- name: Install diagnostic-updater
run: apt-get install ros-${{ matrix.rosdistro }}-diagnostic-updater
- name: Build tests
id: build_test
run: |
. /opt/ros/${{ matrix.rosdistro }}/setup.sh &&
colcon build
continue-on-error: true
- name: build_test command success
if: steps.build_test.outcome == 'success'
run: echo "result - success"
- name: build_test command failure
if: steps.build_test.outcome == 'failure'
run: echo "result - failure" && exit 1
- name: Run tests
id: run_test
run: |
. /opt/ros/${{ matrix.rosdistro }}/setup.sh &&
colcon test &&
colcon test-result
continue-on-error: true
- name: run_test command success
if: steps.run_test.outcome == 'success'
run: echo "result - success"
- name: run_test command failure
if: steps.run_test.outcome == 'failure'
run: echo "result - failure" && exit 1
GitHub Actionsのワークフロー構文
上記の中身について、備忘録も兼ねて記載します。
GitHub Actionsのワークフロー構文についてはGitHub Docs: GitHub Actions のワークフロー構文もご参照ください。
name要素
name: build and test
では、GitHub Actionsのワークフロー名を指定しています。ここではbuild and testが該当します。
on要素
on
では、どのようなイベントに対してGitHub Actionsのワークフローをトリガーするかを設定します。トリガーにできるイベントは複数個や時間スケジュールも可能です。
push: branches: [master]
と記述することで、masterブランチに対してpushイベントが生じたときにワークフローが実行されます。
pull_request
も原理は同様です。
workflow_dispatch: schedule:
では定期的に実行する設定をします。
cron: '0 0 * * *'
は順に分、時、日、月、曜日なので、毎日0時(UTC: Coordinated Universal Time 協定世界時)に実行されます。
UTCとJST:日本標準時ではおよそ9時間の時差があることを覚えておくとスケジュール設定しやすいと思います。
release: types: [published]
はReleaseがPublishされた時にIssueをクローズするために使用します。
jobs要素
jobs: build_and_test:
では、ジョブの名前を定義しています。
strategy: matrix:
ではジョブ内で使用する変数要素を宣言します。
上記ではos:
でubuntu-22.04を、rosdistro:
でディストリビューションを宣言しています。
runs-on:
はジョブの実行環境を指定し、ubuntu-latestでUbuntuの最新バージョンを指定しています。
container: image
ではジョブが実行されるコンテナイメージを指定しており、ros:${{ matrix.rosdistro }}-ros-base
とすることで、ROSのコンテナイメージを宣言しています。
steps:
ではジョブ個々のステップを定義し、上から順に実行されます。
-name:
はステップ名、run:
は実行するコマンドやスクリプトを表します。
continue-on-error: true
を追記することで、コマンドやスクリプトでエラーが発生した場合でも、以降のワークフロー実行を継続します。
if: steps.build_test.outcome == 'success'
では、build_testというIDをもつステップが成功した場合に実行されることを意味します。
IDを付与し、outcomeでステップの結果を判断することで、コマンドの成功/失敗によって以降の処理を分岐できる利点があります。
exit 1
はGitHub Actionsにおいて、ステップがエラーを示すために使用されるコマンドです。
エラーが発生すると、ジョブもfailureとなりますね。
GitHub ActionsでROS 2ビルドとテストを確認する
変更を加えて、.github/workflow/xxx.yamlのあるリポジトリにpushしてみましょう。
このような形で、successになっていればOKですね。
右上の「・・・」ボタンからCreate status badge > Copy status badge Markdown
でCIのバッチをREADME.mdに貼り付けるとCIでテストしてあることを示せるので良いと思います。
Reference
- ROS 2 CI
Running Tests in ROS 2 from the Command Line
GitHub: ros2-build-and-test-action
GitHub: ROS 2 CI Infrastructure
GitHub: YumaMatsumura/ros_ci_test
GitHub: ros-tooling/action-ros-ci-template
以上です。
Likeいただけると大変励みになりますので、よろしくお願いいたします。
Discussion