Skip to content

Commit 7748aba

Browse files
authored
Adding action support for windows (gazebo-tooling#28)
* Added action test for setup-conda --------- Signed-off-by: Saurabh Kamat <kamatsaurabh01@gmail.com>
1 parent 7eb8db7 commit 7748aba

File tree

7 files changed

+275
-2
lines changed

7 files changed

+275
-2
lines changed

.github/workflows/test.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,3 +148,22 @@ jobs:
148148
required-gazebo-distributions: 'harmonic'
149149
- name: 'Test Gazebo installation'
150150
run: 'gz sim --versions'
151+
152+
test_gazebo_install_windows:
153+
name: 'Check installation of Gazebo on Windows'
154+
runs-on: windows-latest
155+
steps:
156+
- uses: actions/checkout@v4
157+
- uses: actions/setup-node@v4.0.2
158+
with:
159+
node-version: '20.x'
160+
- uses: conda-incubator/setup-miniconda@v3
161+
- name: 'Check Gazebo installation on Windows runner'
162+
uses: ./
163+
with:
164+
required-gazebo-distributions: 'harmonic'
165+
- name: 'Test Gazebo installation'
166+
shell: pwsh
167+
run: |
168+
conda activate
169+
gz sim --versions

README.md

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@ This action sets up a Gazebo release inside a Linux environment.
1010
1. [Setting up worker and installing a compatible Gazebo and Ubuntu combination](#Setting-up-worker-and-installing-a-compatible-Gazebo-and-Ubuntu-combination)
1111
1. [Iterating on all Gazebo and Ubuntu combinations](#Iterating-on-all-gazebo-ubuntu-combinations)
1212
1. [Using pre-release and/or nightly Gazebo binaries](#Using-pre-release-and/or-nightly-Gazebo-binaries)
13-
2. [MacOS](#MacOS)
13+
2. [macOS](#macOS)
1414
1. [Setting up worker to install Gazebo on macOS](#Setting-up-worker-to-install-Gazebo-on-macOS)
15+
3. [Windows](#Windows)
16+
1. [Setting up worker to install Gazebo on Windows](#Setting-up-worker-to-install-Gazebo-on-Windows)
1517
1. [License](#License)
1618

1719
## Overview
@@ -25,6 +27,7 @@ It is recommended to use the `setup-gazebo` action inside a Docker container due
2527
`setup-gazebo` action works for all non-EOL Gazebo [releases] on the following platforms:
2628
- Ubuntu
2729
- macOS
30+
- Windows
2831

2932
## Tasks performed by the action
3033

@@ -36,6 +39,8 @@ The `setup-gazebo` action performs the following tasks:
3639
- Registers the Open Robotics APT repository
3740
- On macOS:
3841
- Tapping into the [osrf/homebrew-simulation](https://github.com/osrf/homebrew-simulation) using Homebrew
42+
- On Windows:
43+
- Installing Gazebo using Conda from conda-forge
3944
## Usage
4045

4146
See [action.yml](action.yml)
@@ -155,7 +160,7 @@ This workflow shows how to use binaries from [pre-release] or [nightly] Gazebo r
155160
run: 'gz sim --versions'
156161
```
157162

158-
### MacOS
163+
### macOS
159164

160165
#### Setting up worker to install Gazebo on macOS
161166

@@ -177,6 +182,32 @@ This workflow shows how to install Gazebo on a macOS worker. The action needs an
177182
run: 'gz sim --versions'
178183
```
179184

185+
### Windows
186+
187+
This workflow shows how to install Gazebo on a Windows worker. The action requires a Conda package management system such as miniconda as all Gazebo packages are available on conda-forge. The action is run by specifying the distribution of choice in `required-gazebo-distributions` field.
188+
189+
#### Setting up worker to install Gazebo on Windows
190+
191+
```yaml
192+
test_gazebo:
193+
runs-on: windows-latest
194+
steps:
195+
- uses: actions/checkout@v4
196+
- uses: actions/setup-node@v4.0.2
197+
with:
198+
node-version: '20.x'
199+
- uses: conda-incubator/setup-miniconda@v3
200+
- name: 'Check Gazebo installation on Windows runner'
201+
uses: gazebo-tooling/setup-gazebo@<full_commit_hash>
202+
with:
203+
required-gazebo-distributions: 'harmonic'
204+
- name: 'Test Gazebo installation'
205+
shell: pwsh
206+
run: |
207+
conda activate
208+
gz sim --versions
209+
```
210+
180211
## License
181212

182213
The scripts and documentation in this project are released under the [Apache 2](LICENSE) license.

__test__/main.test.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import * as exec from "@actions/exec";
33

44
import * as linux from "../src/setup-gazebo-linux";
55
import * as macOs from "../src/setup-gazebo-macos";
6+
import * as windows from "../src/setup-gazebo-windows";
67
import * as utils from "../src/utils";
78

89
describe("workflow test without input", () => {
@@ -21,6 +22,10 @@ describe("workflow test without input", () => {
2122
it("run macOS workflow without input", async () => {
2223
await expect(macOs.runMacOs()).rejects.toThrow();
2324
});
25+
26+
it("run Windows workflow without input", async () => {
27+
await expect(windows.runWindows()).rejects.toThrow();
28+
});
2429
});
2530

2631
describe("workflow test with a invalid distro input", () => {
@@ -40,6 +45,10 @@ describe("workflow test with a invalid distro input", () => {
4045
it("run macOS workflow with invalid distro input", async () => {
4146
await expect(macOs.runMacOs()).rejects.toThrow();
4247
});
48+
49+
it("run Windows workflow with invalid distro input", async () => {
50+
await expect(windows.runWindows()).rejects.toThrow();
51+
});
4352
});
4453

4554
describe("workflow test with a valid distro input", () => {
@@ -59,6 +68,10 @@ describe("workflow test with a valid distro input", () => {
5968
it("run macOS workflow with valid distro input", async () => {
6069
await expect(macOs.runMacOs()).resolves.not.toThrow();
6170
});
71+
72+
it("run Windows workflow with valid distro input", async () => {
73+
await expect(windows.runWindows()).resolves.not.toThrow();
74+
});
6275
});
6376

6477
describe("validate distribution test", () => {

dist/index.js

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26289,6 +26289,61 @@ function linkPackage(packageName) {
2628926289
}
2629026290

2629126291

26292+
/***/ }),
26293+
26294+
/***/ 7725:
26295+
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
26296+
26297+
"use strict";
26298+
26299+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
26300+
if (k2 === undefined) k2 = k;
26301+
var desc = Object.getOwnPropertyDescriptor(m, k);
26302+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
26303+
desc = { enumerable: true, get: function() { return m[k]; } };
26304+
}
26305+
Object.defineProperty(o, k2, desc);
26306+
}) : (function(o, m, k, k2) {
26307+
if (k2 === undefined) k2 = k;
26308+
o[k2] = m[k];
26309+
}));
26310+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
26311+
Object.defineProperty(o, "default", { enumerable: true, value: v });
26312+
}) : function(o, v) {
26313+
o["default"] = v;
26314+
});
26315+
var __importStar = (this && this.__importStar) || function (mod) {
26316+
if (mod && mod.__esModule) return mod;
26317+
var result = {};
26318+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
26319+
__setModuleDefault(result, mod);
26320+
return result;
26321+
};
26322+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
26323+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
26324+
return new (P || (P = Promise))(function (resolve, reject) {
26325+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
26326+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
26327+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
26328+
step((generator = generator.apply(thisArg, _arguments || [])).next());
26329+
});
26330+
};
26331+
Object.defineProperty(exports, "__esModule", ({ value: true }));
26332+
exports.runConda = runConda;
26333+
const utils = __importStar(__nccwpck_require__(1314));
26334+
/**
26335+
* Run conda install on a list of specified packages.
26336+
*
26337+
* @param packages list of conda-forge packages to be installed
26338+
* @returns Promise<number> exit code
26339+
*/
26340+
function runConda(packages) {
26341+
return __awaiter(this, void 0, void 0, function* () {
26342+
return utils.exec("conda", ["install", "--channel", "conda-forge"].concat(packages));
26343+
});
26344+
}
26345+
26346+
2629226347
/***/ }),
2629326348

2629426349
/***/ 5467:
@@ -26525,6 +26580,95 @@ function runMacOs() {
2652526580
}
2652626581

2652726582

26583+
/***/ }),
26584+
26585+
/***/ 8502:
26586+
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
26587+
26588+
"use strict";
26589+
26590+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
26591+
if (k2 === undefined) k2 = k;
26592+
var desc = Object.getOwnPropertyDescriptor(m, k);
26593+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
26594+
desc = { enumerable: true, get: function() { return m[k]; } };
26595+
}
26596+
Object.defineProperty(o, k2, desc);
26597+
}) : (function(o, m, k, k2) {
26598+
if (k2 === undefined) k2 = k;
26599+
o[k2] = m[k];
26600+
}));
26601+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
26602+
Object.defineProperty(o, "default", { enumerable: true, value: v });
26603+
}) : function(o, v) {
26604+
o["default"] = v;
26605+
});
26606+
var __importStar = (this && this.__importStar) || function (mod) {
26607+
if (mod && mod.__esModule) return mod;
26608+
var result = {};
26609+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
26610+
__setModuleDefault(result, mod);
26611+
return result;
26612+
};
26613+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
26614+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
26615+
return new (P || (P = Promise))(function (resolve, reject) {
26616+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
26617+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
26618+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
26619+
step((generator = generator.apply(thisArg, _arguments || [])).next());
26620+
});
26621+
};
26622+
Object.defineProperty(exports, "__esModule", ({ value: true }));
26623+
exports.runWindows = runWindows;
26624+
const utils = __importStar(__nccwpck_require__(1314));
26625+
const conda = __importStar(__nccwpck_require__(7725));
26626+
// List of mapped Gazebo distro to gz-sim versions
26627+
const validLibVersions = [
26628+
{
26629+
distro: "garden",
26630+
libVersion: 7,
26631+
},
26632+
{
26633+
distro: "harmonic",
26634+
libVersion: 8,
26635+
},
26636+
];
26637+
/**
26638+
* Get gz-sim library version corresponding to a gz-$collection
26639+
* since conda does not currently support the gz-$collection metapackages.
26640+
* See https://github.com/conda-forge/gz-sim-feedstock/issues/61
26641+
*
26642+
* @param gazeboDistro name of Gazebo distribution
26643+
* @returns gz-sim version
26644+
*/
26645+
function getLibVersion(gazeboDistro) {
26646+
return __awaiter(this, void 0, void 0, function* () {
26647+
let version;
26648+
validLibVersions.forEach((obj) => {
26649+
if (obj.distro == gazeboDistro) {
26650+
version = obj.libVersion;
26651+
}
26652+
});
26653+
if (version === undefined) {
26654+
throw new Error(`No conda packages available for gz-${gazeboDistro}`);
26655+
}
26656+
return version;
26657+
});
26658+
}
26659+
/**
26660+
* Install Gazebo on a Windows worker
26661+
*/
26662+
function runWindows() {
26663+
return __awaiter(this, void 0, void 0, function* () {
26664+
for (const gazeboDistro of utils.getRequiredGazeboDistributions()) {
26665+
const version = yield getLibVersion(gazeboDistro);
26666+
yield conda.runConda([`gz-sim${version}`]);
26667+
}
26668+
});
26669+
}
26670+
26671+
2652826672
/***/ }),
2652926673

2653026674
/***/ 525:
@@ -26568,6 +26712,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
2656826712
const core = __importStar(__nccwpck_require__(2186));
2656926713
const linux = __importStar(__nccwpck_require__(5467));
2657026714
const macOs = __importStar(__nccwpck_require__(8247));
26715+
const windows = __importStar(__nccwpck_require__(8502));
2657126716
function run() {
2657226717
return __awaiter(this, void 0, void 0, function* () {
2657326718
try {
@@ -26578,6 +26723,9 @@ function run() {
2657826723
else if (platform === "linux") {
2657926724
linux.runLinux();
2658026725
}
26726+
else if (platform === "win32") {
26727+
windows.runWindows();
26728+
}
2658126729
else {
2658226730
throw new Error(`Unsupported platform ${platform}`);
2658326731
}

src/package_manager/conda.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import * as utils from "../utils";
2+
3+
/**
4+
* Run conda install on a list of specified packages.
5+
*
6+
* @param packages list of conda-forge packages to be installed
7+
* @returns Promise<number> exit code
8+
*/
9+
export async function runConda(packages: string[]): Promise<number> {
10+
return utils.exec(
11+
"conda",
12+
["install", "--channel", "conda-forge"].concat(packages),
13+
);
14+
}

src/setup-gazebo-windows.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import * as utils from "./utils";
2+
import * as conda from "./package_manager/conda";
3+
4+
// List of mapped Gazebo distro to gz-sim versions
5+
const validLibVersions: { distro: string; libVersion: number }[] = [
6+
{
7+
distro: "garden",
8+
libVersion: 7,
9+
},
10+
{
11+
distro: "harmonic",
12+
libVersion: 8,
13+
},
14+
];
15+
16+
/**
17+
* Get gz-sim library version corresponding to a gz-$collection
18+
* since conda does not currently support the gz-$collection metapackages.
19+
* See https://github.com/conda-forge/gz-sim-feedstock/issues/61
20+
*
21+
* @param gazeboDistro name of Gazebo distribution
22+
* @returns gz-sim version
23+
*/
24+
async function getLibVersion(gazeboDistro: string): Promise<number> {
25+
let version: number | undefined;
26+
validLibVersions.forEach((obj) => {
27+
if (obj.distro == gazeboDistro) {
28+
version = obj.libVersion;
29+
}
30+
});
31+
if (version === undefined) {
32+
throw new Error(`No conda packages available for gz-${gazeboDistro}`);
33+
}
34+
return version;
35+
}
36+
37+
/**
38+
* Install Gazebo on a Windows worker
39+
*/
40+
export async function runWindows(): Promise<void> {
41+
for (const gazeboDistro of utils.getRequiredGazeboDistributions()) {
42+
const version = await getLibVersion(gazeboDistro);
43+
await conda.runConda([`gz-sim${version}`]);
44+
}
45+
}

src/setup-gazebo.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as core from "@actions/core";
22
import * as linux from "./setup-gazebo-linux";
33
import * as macOs from "./setup-gazebo-macos";
4+
import * as windows from "./setup-gazebo-windows";
45

56
async function run() {
67
try {
@@ -9,6 +10,8 @@ async function run() {
910
macOs.runMacOs();
1011
} else if (platform === "linux") {
1112
linux.runLinux();
13+
} else if (platform === "win32") {
14+
windows.runWindows();
1215
} else {
1316
throw new Error(`Unsupported platform ${platform}`);
1417
}

0 commit comments

Comments
 (0)