diff --git a/.github/workflows/create-ros2-package.yaml b/.github/workflows/create-ros2-package.yaml
new file mode 100644
index 0000000..f7c891f
--- /dev/null
+++ b/.github/workflows/create-ros2-package.yaml
@@ -0,0 +1,81 @@
+name: create-ros2-package
+
+on:
+ workflow_dispatch:
+ inputs:
+ package-name:
+ description: "Name of the ROS 2 package to create"
+ required: true
+ type: string
+ maintainer-email:
+ description: "Email of the maintainer"
+ required: true
+ type: string
+ maintainer-name:
+ description: "Name of the maintainer"
+ required: true
+ type: string
+
+jobs:
+ create-package:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Generate token
+ id: generate-token
+ uses: tibdex/github-app-token@v2
+ with:
+ app_id: ${{ secrets.APP_ID }}
+ private_key: ${{ secrets.PRIVATE_KEY }}
+
+ - name: Check out repository
+ uses: actions/checkout@v4
+
+ - name: Create ROS 2 package
+ run: |
+ if [ -d ${{ inputs.package-name }} ]; then
+ echo "Package ${{ inputs.package-name }} already exists."
+ exit 1
+ fi
+
+ mkdir ${{ inputs.package-name}} && cd ${{ inputs.package-name}}
+
+ if [[ "${{ inputs.package-name }}" != *_msgs ]]; then
+ mkdir src && touch src/.gitkeep
+ mkdir include/${{ inputs.package-name}} && touch include/${{ inputs.package-name}}/.gitkeep
+ mkdir launch && touch launch/.gitkeep
+ cp ../.template-package/.CMakeLists.txt ./CMakeLists.txt
+ cp ../.template-package/.package.xml ./package.xml
+ else
+ mkdir msg && touch msg/.gitkeep
+ cp ../.template-interface-package/.CMakeLists.txt ./CMakeLists.txt
+ cp ../.template-interface-package/.package.xml ./package.xml
+ fi
+
+ sed 's/__PACKAGE_NAME__/package-name/g' ./CMakeLists.txt > "./CMakeLists.txt.tmp"
+ mv "./CMakeLists.txt.tmp" "./CMakeLists.txt"
+ sed -e 's/__PACKAGE_NAME__/package-name/g' -e 's/__MAINTAINER_EMAIL__/maintainer-email/g' -e 's/__MAINTAINER_NAME__/maintainer-name/g' ./package.xml > "./package.xml.tmp"
+ mv "./package.xml.tmp" "./package.xml"
+
+ - name: Create PR
+ id: create-pr
+ uses: peter-evans/create-pull-request@v5
+ with:
+ token: ${{ steps.generate-token.outputs.token }}
+ base: ${{ github.event.repository.default_branch }}
+ branch: create-package-${{ inputs.package-name }}
+ title: "feat: create ${{ inputs.package-name }} package"
+ commit-message: "feat: create ${{ inputs.package-name }} package"
+ body: "Create ${{ inputs.package-name }} package."
+ signoff: true
+ delete-branch: true
+
+ - name: Check outputs
+ run: |
+ echo "Pull Request Number - ${{ steps.create-pr.outputs.pull-request-number }}"
+ echo "Pull Request URL - ${{ steps.create-pr.outputs.pull-request-url }}"
+
+ - name: Enable auto-merge
+ if: ${{ steps.create-pr.outputs.pull-request-operation == 'created' }}
+ run: gh pr merge --squash --auto "${{ steps.create-pr.outputs.pull-request-number }}"
+ env:
+ GITHUB_TOKEN: ${{ steps.generate-token.outputs.token }}
diff --git a/.template-interface-package/.CMakeLists.txt b/.template-interface-package/.CMakeLists.txt
new file mode 100644
index 0000000..6ce2865
--- /dev/null
+++ b/.template-interface-package/.CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 3.5)
+project(__PACKAGE_NAME__)
+
+if(NOT CMAKE_CXX_STANDARD)
+ set(CMAKE_CXX_STANDARD 14)
+endif()
+
+if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+ add_compile_options(-Wall -Wextra -Wpedantic)
+endif()
+
+find_package(ament_cmake REQUIRED)
+find_package(rosidl_default_generators REQUIRED)
+
+rosidl_generate_interfaces(${PROJECT_NAME}
+ DEPENDENCIES
+)
+
+ament_package()
\ No newline at end of file
diff --git a/.template-interface-package/.package.xml b/.template-interface-package/.package.xml
new file mode 100644
index 0000000..7b3ce3e
--- /dev/null
+++ b/.template-interface-package/.package.xml
@@ -0,0 +1,19 @@
+
+
+
+ __PACKAGE_NAME__
+ 0.0.0
+ The __PACKAGE_NAME__ package
+ __MAINTAINER_NAME__
+
+ Apache 2
+
+ ament_cmake
+ rosidl_default_generators
+ rosidl_default_runtime
+ rosidl_interface_packages
+
+
+ ament_cmake
+
+
\ No newline at end of file
diff --git a/.template-package/.CMakeLists.txt b/.template-package/.CMakeLists.txt
new file mode 100644
index 0000000..fbb663b
--- /dev/null
+++ b/.template-package/.CMakeLists.txt
@@ -0,0 +1,21 @@
+cmake_minimum_required(VERSION 3.5)
+project(__PACKAGE_NAME__)
+
+if(NOT CMAKE_CXX_STANDARD)
+ set(CMAKE_CXX_STANDARD 14)
+endif()
+
+if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+ add_compile_options(-Wall -Wextra -Wpedantic)
+endif()
+
+find_package(ament_cmake REQUIRED)
+
+if(BUILD_TESTING)
+ find_package(ament_lint_auto REQUIRED)
+ ament_lint_auto_find_test_dependencies()
+endif()
+
+ament_auto_package(INSTALL_TO_SHARE
+ launch
+)
\ No newline at end of file
diff --git a/.template-package/.package.xml b/.template-package/.package.xml
new file mode 100644
index 0000000..540291d
--- /dev/null
+++ b/.template-package/.package.xml
@@ -0,0 +1,16 @@
+
+
+
+ __PACKAGE_NAME__
+ 0.0.0
+ The __PACKAGE_NAME__ package
+ __MAINTAINER_NAME__
+
+ Apache 2
+
+ ament_cmake
+
+
+ ament_cmake
+
+
\ No newline at end of file