Repository: ros-tooling/setup-ros
Pull request #804: Add support for Kilted
Author: login: christophebedard
Created: 2025-05-01T16:11:00Z | Merged: 2025-05-01T18:36:38Z

Similar to #673, which did the same for Jazzy.

We need to use the testing apt repo to get Kilted binaries for tests before Kilted is officially released. See: https://docs.ros.org/en/kilted/Installation/Ubuntu-Install-Debians.html#enable-required-repositories. Once Kilted has been released, we can revert this.

Users will need to use `use-ros2-testing: true` for Kilted. On Windows, use the pre-release binaries. Also, allow using the testing repo for RHEL.

I won't mention Kilted in the README until it's officially been released


Diff:
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index aeaa6d07d..8146f8546 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -78,6 +78,8 @@ jobs:
           - iron
           # Jazzy Jalisco (May 2024 - May 2029)
           - jazzy
+          # Kilted Kaiju (May 2025 - November 2026)
+          - kilted
     steps:
       - uses: actions/checkout@v4
       - uses: actions/setup-node@v4.4.0
@@ -127,7 +129,7 @@ jobs:
             ros_distribution: iron
             ros_version: 2
 
-          # Jazzy Jalisco (May 2024 - November 2029)
+          # Jazzy Jalisco (May 2024 - May 2029)
           - docker_image: ubuntu:noble
             ros_distribution: jazzy
             ros_version: 2
@@ -136,6 +138,15 @@ jobs:
             ros_distribution: jazzy
             ros_version: 2
 
+          # Kilted Kaiju (May 2025 - November 2026)
+          - docker_image: ubuntu:noble
+            ros_distribution: kilted
+            ros_version: 2
+
+          - docker_image: almalinux:9
+            ros_distribution: kilted
+            ros_version: 2
+
           # Rolling Ridley (see REP 2002: https://www.ros.org/reps/rep-2002.html)
           - docker_image: ubuntu:noble
             ros_distribution: rolling
@@ -158,6 +169,8 @@ jobs:
       - uses: ./ # Uses an action in the root directory
         with:
           required-ros-distributions: ${{ matrix.ros_distribution }}
+          # Use ros2-testing repo for Kilted before it's officially released
+          use-ros2-testing: ${{ matrix.ros_distribution == 'kilted' }}
       - run: .github/workflows/check-environment.sh
       - run: .github/workflows/check-ros-distribution.sh "${{ matrix.ros_distribution }}"
         if: matrix.ros_version == 1
diff --git a/__test__/main.test.ts b/__test__/main.test.ts
index 26e527f2f..ed3780545 100644
--- a/__test__/main.test.ts
+++ b/__test__/main.test.ts
@@ -67,6 +67,7 @@ describe("validate distribution test", () => {
 		await expect(utils.validateDistro(["humble"])).toBe(true);
 		await expect(utils.validateDistro(["iron"])).toBe(true);
 		await expect(utils.validateDistro(["jazzy"])).toBe(true);
+		await expect(utils.validateDistro(["kilted"])).toBe(true);
 		await expect(utils.validateDistro(["rolling"])).toBe(true);
 	});
 
diff --git a/action.yml b/action.yml
index 6c67ea0be..818375856 100644
--- a/action.yml
+++ b/action.yml
@@ -30,6 +30,7 @@ inputs:
       - humble
       - iron
       - jazzy
+      - kilted
       - rolling
 
       Multiple values can be passed using a whitespace delimited list
diff --git a/dist/index.js b/dist/index.js
index 3a6ee0ac6..25c9ea790 100644
--- a/dist/index.js
+++ b/dist/index.js
@@ -6944,7 +6944,7 @@ function configOs() {
 /**
  * Add OSRF repository.
  */
-function addDnfRepo() {
+function addDnfRepo(use_ros2_testing) {
     return __awaiter(this, void 0, void 0, function* () {
         dnf.runDnfInstall(["epel-release"]);
         yield utils.exec("bash", [
@@ -6965,11 +6965,12 @@ function addDnfRepo() {
             "--set-enabled",
             extra_repo_name,
         ]);
+        const testing_repo_suffix = use_ros2_testing ? "-testing" : "";
         yield utils.exec("sudo", [
             "curl",
             "--output",
             "/etc/yum.repos.d/ros2.repo",
-            "http://packages.ros.org/ros2/rhel/ros2.repo",
+            `http://packages.ros.org/ros2${testing_repo_suffix}/rhel/ros2${testing_repo_suffix}.repo`,
         ]);
         yield utils.exec("sudo", ["dnf", "makecache", "--assumeyes"]);
     });
@@ -6996,8 +6997,9 @@ function rosdepInit() {
  */
 function runLinux() {
     return __awaiter(this, void 0, void 0, function* () {
+        const use_ros2_testing = core.getInput("use-ros2-testing") === "true";
         yield configOs();
-        yield addDnfRepo();
+        yield addDnfRepo(use_ros2_testing);
         // Install development-related packages and some common dependencies
         yield dnf.installDnfDependencies();
         yield rosdepInit();
@@ -7302,6 +7304,7 @@ const binaryReleases = {
     humble: "https://github.com/ros2/ros2/releases/download/release-humble-20230614/ros2-humble-20230614-windows-release-amd64.zip",
     iron: "https://github.com/ros2/ros2/releases/download/release-iron-20230523/ros2-iron-20230523-windows-release-amd64.zip",
     jazzy: "https://github.com/ros2/ros2/releases/download/release-jazzy-20240705/ros2-jazzy-20240705-windows-release-amd64.zip",
+    kilted: "https://github.com/ros2/ros2/releases/download/release-kilted-beta-20250430/ros2-kilted-beta-20250430-windows-release-amd64.zip",
 };
 const pip3Packages = ["lxml", "netifaces"];
 /**
@@ -7557,7 +7560,14 @@ function getRequiredRosDistributions() {
     return requiredRosDistributionsList;
 }
 //list of valid linux distributions
-const validDistro = ["noetic", "humble", "iron", "jazzy", "rolling"];
+const validDistro = [
+    "noetic",
+    "humble",
+    "iron",
+    "jazzy",
+    "kilted",
+    "rolling",
+];
 //Determine whether all inputs name supported ROS distributions.
 function validateDistro(requiredRosDistributionsList) {
     for (const rosDistro of requiredRosDistributionsList) {
diff --git a/src/setup-ros-rhel.ts b/src/setup-ros-rhel.ts
index 1e643a549..e43b47f75 100644
--- a/src/setup-ros-rhel.ts
+++ b/src/setup-ros-rhel.ts
@@ -45,7 +45,7 @@ async function configOs(): Promise<void> {
 /**
  * Add OSRF repository.
  */
-async function addDnfRepo(): Promise<void> {
+async function addDnfRepo(use_ros2_testing: boolean): Promise<void> {
 	dnf.runDnfInstall(["epel-release"]);
 
 	await utils.exec("bash", [
@@ -72,11 +72,12 @@ async function addDnfRepo(): Promise<void> {
 		extra_repo_name,
 	]);
 
+	const testing_repo_suffix = use_ros2_testing ? "-testing" : "";
 	await utils.exec("sudo", [
 		"curl",
 		"--output",
 		"/etc/yum.repos.d/ros2.repo",
-		"http://packages.ros.org/ros2/rhel/ros2.repo",
+		`http://packages.ros.org/ros2${testing_repo_suffix}/rhel/ros2${testing_repo_suffix}.repo`,
 	]);
 
 	await utils.exec("sudo", ["dnf", "makecache", "--assumeyes"]);
@@ -102,9 +103,11 @@ async function rosdepInit(): Promise<void> {
  * Install ROS 2 (development packages and/or ROS binaries) on a Linux worker.
  */
 export async function runLinux(): Promise<void> {
+	const use_ros2_testing = core.getInput("use-ros2-testing") === "true";
+
 	await configOs();
 
-	await addDnfRepo();
+	await addDnfRepo(use_ros2_testing);
 
 	// Install development-related packages and some common dependencies
 	await dnf.installDnfDependencies();
diff --git a/src/setup-ros-windows.ts b/src/setup-ros-windows.ts
index ab7f35378..e4d720068 100644
--- a/src/setup-ros-windows.ts
+++ b/src/setup-ros-windows.ts
@@ -12,6 +12,8 @@ const binaryReleases: { [index: string]: string } = {
 	iron: "https://github.com/ros2/ros2/releases/download/release-iron-20230523/ros2-iron-20230523-windows-release-amd64.zip",
 	jazzy:
 		"https://github.com/ros2/ros2/releases/download/release-jazzy-20240705/ros2-jazzy-20240705-windows-release-amd64.zip",
+	kilted:
+		"https://github.com/ros2/ros2/releases/download/release-kilted-beta-20250430/ros2-kilted-beta-20250430-windows-release-amd64.zip",
 };
 
 const pip3Packages: string[] = ["lxml", "netifaces"];
diff --git a/src/utils.ts b/src/utils.ts
index 097da2795..27bd0d8cd 100644
--- a/src/utils.ts
+++ b/src/utils.ts
@@ -41,7 +41,14 @@ export function getRequiredRosDistributions(): string[] {
 }
 
 //list of valid linux distributions
-const validDistro: string[] = ["noetic", "humble", "iron", "jazzy", "rolling"];
+const validDistro: string[] = [
+	"noetic",
+	"humble",
+	"iron",
+	"jazzy",
+	"kilted",
+	"rolling",
+];
 
 //Determine whether all inputs name supported ROS distributions.
 export function validateDistro(


Reviews:
user: login: MichaelOrlov
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-01T16:32:58Z
user: login: MichaelOrlov
body: LGTM. Please consider removing iron from supported distros as well.
state: APPROVED
author_association: MEMBER
submitted_at: 2025-05-01T16:34:09Z
user: login: christophebedard
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-01T17:26:28Z

Review comments:
diff_hunk: @@ -7557,7 +7557,14 @@ function getRequiredRosDistributions() {
     return requiredRosDistributionsList;
 }
 //list of valid linux distributions
-const validDistro = ["noetic", "humble", "iron", "jazzy", "rolling"];
+const validDistro = [
+    "noetic",
+    "humble",
+    "iron",
path: dist/index.js
user: login: MichaelOrlov
body: Should we remove iron here or better in a separate PR?
created_at: 2025-05-01T16:32:58Z
author_association: MEMBER
diff_hunk: @@ -7557,7 +7557,14 @@ function getRequiredRosDistributions() {
     return requiredRosDistributionsList;
 }
 //list of valid linux distributions
-const validDistro = ["noetic", "humble", "iron", "jazzy", "rolling"];
+const validDistro = [
+    "noetic",
+    "humble",
+    "iron",
path: dist/index.js
user: login: christophebedard
body: I would do that in a separate PR.
created_at: 2025-05-01T17:26:28Z
author_association: MEMBER

PR comments:
user: login: christophebedard
created_at: 2025-05-01T18:41:37Z
body: I will wait to test this with `action-ros-ci` before releasing it.
author_association: MEMBER
user: login: christophebedard
created_at: 2025-05-02T19:31:40Z
body: Released as `0.7.12`/`v0.7`.
author_association: MEMBER