diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 494de27..71aa15b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -79,3 +79,46 @@ jobs: echo "Neither ign nor gz command found" exit 1 fi + + test_gazebo_install_ubuntu_prerelease: + name: 'Check installation of Gazebo pre-release binary on Ubuntu' + runs-on: ubuntu-latest + container: + image: ${{ matrix.docker_image }} + strategy: + fail-fast: false + matrix: + docker_image: + - ubuntu:jammy + - ubuntu:noble + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4.0.2 + with: + node-version: '20.x' + - name: 'Check Gazebo installation on Ubuntu runner' + uses: ./ + with: + required-gazebo-distributions: 'harmonic' + use-gazebo-prerelease: 'true' + - name: 'Test Gazebo installation' + run: 'gz sim --versions' + + test_gazebo_install_ubuntu_nightly: + name: 'Check installation of Gazebo nightly binary on Ubuntu' + runs-on: ubuntu-latest + container: + # Ionic should be running on Noble but existing bug is releasing it into Jammy + image: ubuntu:jammy + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4.0.2 + with: + node-version: '20.x' + - name: 'Check Gazebo installation on Ubuntu runner' + uses: ./ + with: + required-gazebo-distributions: 'ionic' + use-gazebo-nightly: 'true' + - name: 'Test Gazebo installation' + run: 'gz sim --versions' diff --git a/.gitignore b/.gitignore index 57d9462..dd5d1a0 100644 --- a/.gitignore +++ b/.gitignore @@ -127,3 +127,5 @@ out .yarn/build-state.yml .yarn/install-state.gz .pnp.* + +.vscode \ No newline at end of file diff --git a/README.md b/README.md index 2611e8c..559a85b 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ This action sets up a Gazebo release inside a Linux environment. 1. [Usage](#Usage) 1. [Setting up worker and installing a compatible Gazebo and Ubuntu combination](#Setting-up-worker-and-installing-a-compatible-Gazebo-and-Ubuntu-combination) 1. [Iterating on all Gazebo and Ubuntu combinations](#Iterating-on-all-gazebo-ubuntu-combinations) + 1. [Using pre-release and/or nightly Gazebo binaries](#Using-pre-release-and/or-nightly-Gazebo-binaries) 1. [License](#License) ## Overview @@ -47,74 +48,106 @@ See [action.yml](action.yml) This workflow shows how to spawn a job to install Gazebo using the action. The action needs an input in the `required-gazebo-distributions` field and requires a Docker configuration to run seamlessly. -The following code snippet shows the installation of Gazebo Garden on Ubuntu Focal. +The following code snippet shows the installation of Gazebo Harmonic on Ubuntu Noble. ```yaml jobs: - build_docker: + test_gazebo: runs-on: ubuntu-latest container: image: ubuntu:noble steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4.0.2 + with: + node-version: '20.x' - name: 'Setup Gazebo' uses: gazebo-tooling/setup-gazebo@ with: required-gazebo-distributions: harmonic - - run: 'gz sim --versions' + - name: 'Test Gazebo installation' + run: 'gz sim --versions' ``` ### Iterating on all Gazebo and Ubuntu combinations -This workflow shows how to spawn one job per Gazebo release. It iterates over all specified Gazebo and Ubuntu combinations using Docker. For example, Gazebo Garden requires Ubuntu Focal while Gazebo Harmonic requires Ubuntu Jammy. +This workflow shows how to spawn one job per Gazebo release. It iterates over all specified Gazebo and Ubuntu combinations using Docker. For example, Gazebo Garden is paired with Ubuntu Focal while Gazebo Harmonic is paired with Ubuntu Jammy. + +```yaml + jobs: + test_gazebo: + runs-on: ubuntu-latest + container: + image: ${{ matrix.docker_image }} + strategy: + fail-fast: false + matrix: + gazebo_distribution: + - citadel + - fortress + - garden + - harmonic + include: + # Gazebo Citadel (Dec 2019 - Dec 2024) + - docker_image: ubuntu:focal + gazebo_distribution: citadel + + # Gazebo Fortress (Sep 2021 - Sep 2026) + - docker_image: ubuntu:focal + gazebo_distribution: fortress + + # Gazebo Garden (Sep 2022 - Nov 2024) + - docker_image: ubuntu:focal + gazebo_distribution: garden + + # Gazebo Harmonic (Sep 2023 - Sep 2028) + - docker_image: ubuntu:jammy + gazebo_distribution: harmonic + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4.0.2 + with: + node-version: '20.x' + - name: 'Check Gazebo installation on Ubuntu runner' + uses: gazebo-tooling/setup-gazebo@ + with: + required-gazebo-distributions: ${{ matrix.gazebo_distribution }} + - name: 'Test Gazebo installation' + run: | + if command -v ign > /dev/null; then + ign gazebo --versions + elif command -v gz > /dev/null; then + gz sim --versions + else + echo "Neither ign nor gz command found" + exit 1 + fi +``` + +### Using pre-release and/or nightly Gazebo binaries + +This workflow shows how to use binaries from [pre-release] or [nightly] Gazebo repositories instead of the stable repository by setting the `use-gazebo-prerelease` or `use-gazebo-nightly` to `true`. ```yaml - test_gazebo: - runs-on: ubuntu-latest - container: - image: ${{ matrix.docker_image }} - strategy: - fail-fast: false - matrix: - gazebo_distribution: - - citadel - - fortress - - garden - - harmonic - include: - # Gazebo Citadel (Dec 2019 - Dec 2024) - - docker_image: ubuntu:focal - gazebo_distribution: citadel - - # Gazebo Fortress (Sep 2021 - Sep 2026) - - docker_image: ubuntu:focal - gazebo_distribution: fortress - - # Gazebo Garden (Sep 2022 - Nov 2024) - - docker_image: ubuntu:focal - gazebo_distribution: garden - - # Gazebo Harmonic (Sep 2023 - Sep 2028) - - docker_image: ubuntu:jammy - gazebo_distribution: harmonic - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4.0.2 - with: - node-version: '20.x' - - name: 'Check Gazebo installation on Ubuntu runner' - uses: gazebo-tooling/setup-gazebo@ - with: - required-gazebo-distributions: ${{ matrix.gazebo_distribution }} - - name: 'Test Gazebo installation' - run: | - if command -v ign > /dev/null; then - ign gazebo --versions - elif command -v gz > /dev/null; then - gz sim --versions - else - echo "Neither ign nor gz command found" - exit 1 - fi + jobs: + test_gazebo: + name: 'Check installation of Gazebo nightly binary on Ubuntu' + runs-on: ubuntu-latest + container: + image: ubuntu:noble + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4.0.2 + with: + node-version: '20.x' + - name: 'Check Gazebo installation on Ubuntu runner' + uses: gazebo-tooling/setup-gazebo@ + with: + required-gazebo-distributions: 'harmonic' + use-gazebo-prerelease: 'true' + use-gazebo-nightly: 'true' + - name: 'Test Gazebo installation' + run: 'gz sim --versions' ``` ## License @@ -123,4 +156,6 @@ The scripts and documentation in this project are released under the [Apache 2]( [releases]: https://gazebosim.org/docs/all/releases [officially]: https://gazebosim.org/docs/harmonic/releases#supported-platforms -[best-effort]: https://gazebosim.org/docs/harmonic/releases#supported-platforms \ No newline at end of file +[best-effort]: https://gazebosim.org/docs/harmonic/releases#supported-platforms +[pre-release]: https://packages.osrfoundation.org/gazebo/ubuntu-prerelease/ +[nightly]: https://packages.osrfoundation.org/gazebo/ubuntu-nightly/ \ No newline at end of file diff --git a/__test__/main.test.ts b/__test__/main.test.ts index 30afb96..1212712 100644 --- a/__test__/main.test.ts +++ b/__test__/main.test.ts @@ -13,7 +13,7 @@ describe("workflow test without input", () => { jest.resetAllMocks(); }); - it("run Linux workflow without", async () => { + it("run Linux workflow without input", async () => { await expect(linux.runLinux()).rejects.toThrow(); }); }); @@ -28,7 +28,7 @@ describe("workflow test with a invalid distro input", () => { jest.resetAllMocks(); }); - it("run Linux workflow without", async () => { + it("run Linux workflow with invalid distro input", async () => { await expect(linux.runLinux()).rejects.toThrow(); }); }); @@ -43,7 +43,7 @@ describe("workflow test with a valid distro input", () => { jest.resetAllMocks(); }); - it("run Linux workflow without", async () => { + it("run Linux workflow with valid distro input", async () => { await expect(linux.runLinux()).resolves.not.toThrow(); }); }); @@ -68,3 +68,35 @@ describe("validate distribution test", () => { ); }); }); + +describe("check for unstable repositories input", () => { + beforeAll(() => { + jest.spyOn(exec, "exec").mockImplementation(jest.fn()); + jest + .spyOn(utils, "checkForUnstableAptRepos") + .mockReturnValueOnce(["prerelease"]); + jest + .spyOn(utils, "checkForUnstableAptRepos") + .mockReturnValueOnce(["nightly"]); + jest + .spyOn(utils, "checkForUnstableAptRepos") + .mockReturnValueOnce(["prerelease", "nightly"]); + jest.spyOn(core, "getInput").mockReturnValue("harmonic"); + }); + + afterAll(() => { + jest.resetAllMocks(); + }); + + it("run Linux workflow with unstable repo prerelease", async () => { + await expect(linux.runLinux()).resolves.not.toThrow(); + }); + + it("run Linux workflow with unstable repo nightly", async () => { + await expect(linux.runLinux()).resolves.not.toThrow(); + }); + + it("run Linux workflow with both unstable repos", async () => { + await expect(linux.runLinux()).resolves.not.toThrow(); + }); +}); diff --git a/action.yml b/action.yml index 877158f..b13c75a 100644 --- a/action.yml +++ b/action.yml @@ -1,20 +1,31 @@ name: 'Setup Gazebo release' description: | Install a Gazebo release on a Linux system -required-gazebo-distributions: - description: | - List of Gazebo distributions to be installed. +inputs: + required-gazebo-distributions: + description: | + List of Gazebo distributions to be installed. - Allowed Gazebo distributions - - citadel - - fortress - - garden - - harmonic + Allowed Gazebo distributions + - citadel + - fortress + - garden + - harmonic - Multiple values can be passed using a whitespace delimited list - "fortress garden". + Multiple values can be passed using a whitespace delimited list + "fortress garden". + required: false + default: '' + use-gazebo-prerelease: + description: | + Use pre-release binaries from OSRF repository + required: false + default: 'false' + use-gazebo-nightly: + description: | + Use nightly binaries from OSRF repository required: false - default: '' + default: 'false' runs: using: node20 main: dist/index.js diff --git a/dist/index.js b/dist/index.js index 653f34c..e3fed6d 100644 --- a/dist/index.js +++ b/dist/index.js @@ -26336,6 +26336,16 @@ function addAptRepo(ubuntuCodename) { http://packages.osrfoundation.org/gazebo/ubuntu-stable ${ubuntuCodename} main" | \ sudo tee /etc/apt/sources.list.d/gazebo-stable.list > /dev/null`, ]); + const unstableRepos = utils.checkForUnstableAptRepos(); + for (const unstableRepo of unstableRepos) { + yield utils.exec("sudo", [ + "bash", + "-c", + `echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/pkgs-osrf-archive-keyring.gpg] \ + http://packages.osrfoundation.org/gazebo/ubuntu-${unstableRepo} ${ubuntuCodename} main" | \ + sudo tee /etc/apt/sources.list.d/gazebo-${unstableRepo}.list > /dev/null`, + ]); + } yield utils.exec("sudo", ["apt-get", "update"]); }); } @@ -26456,7 +26466,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }); }; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.getRequiredGazeboDistributions = exports.validateDistro = exports.determineDistribCodename = exports.exec = void 0; +exports.checkForUnstableAptRepos = exports.getRequiredGazeboDistributions = exports.validateDistro = exports.determineDistribCodename = exports.exec = void 0; const actions_exec = __importStar(__nccwpck_require__(1514)); const core = __importStar(__nccwpck_require__(2186)); /** @@ -26501,7 +26511,13 @@ function determineDistribCodename() { } exports.determineDistribCodename = determineDistribCodename; // List of valid Gazebo distributions -const validDistro = ["citadel", "fortress", "garden", "harmonic"]; +const validDistro = [ + "citadel", + "fortress", + "garden", + "harmonic", + "ionic", +]; /** * Validate all Gazebo input distribution names * @@ -26538,6 +26554,24 @@ function getRequiredGazeboDistributions() { return requiredGazeboDistributionsList; } exports.getRequiredGazeboDistributions = getRequiredGazeboDistributions; +/** + * Check for unstable repository inputs + * + * @returns unstableRepos unstable repository names + */ +function checkForUnstableAptRepos() { + const unstableRepos = []; + const useGazeboPrerelease = core.getInput("use-gazebo-prerelease") === "true"; + if (useGazeboPrerelease) { + unstableRepos.push("prerelease"); + } + const useGazeboNightly = core.getInput("use-gazebo-nightly") === "true"; + if (useGazeboNightly) { + unstableRepos.push("nightly"); + } + return unstableRepos; +} +exports.checkForUnstableAptRepos = checkForUnstableAptRepos; /***/ }), diff --git a/src/setup-gazebo-linux.ts b/src/setup-gazebo-linux.ts index 7dbe00b..1eb8b44 100644 --- a/src/setup-gazebo-linux.ts +++ b/src/setup-gazebo-linux.ts @@ -79,6 +79,16 @@ async function addAptRepo(ubuntuCodename: string): Promise { http://packages.osrfoundation.org/gazebo/ubuntu-stable ${ubuntuCodename} main" | \ sudo tee /etc/apt/sources.list.d/gazebo-stable.list > /dev/null`, ]); + const unstableRepos = utils.checkForUnstableAptRepos(); + for (const unstableRepo of unstableRepos) { + await utils.exec("sudo", [ + "bash", + "-c", + `echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/pkgs-osrf-archive-keyring.gpg] \ + http://packages.osrfoundation.org/gazebo/ubuntu-${unstableRepo} ${ubuntuCodename} main" | \ + sudo tee /etc/apt/sources.list.d/gazebo-${unstableRepo}.list > /dev/null`, + ]); + } await utils.exec("sudo", ["apt-get", "update"]); } diff --git a/src/utils.ts b/src/utils.ts index 4eb395e..7c62625 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -49,7 +49,13 @@ export async function determineDistribCodename(): Promise { } // List of valid Gazebo distributions -const validDistro: string[] = ["citadel", "fortress", "garden", "harmonic"]; +const validDistro: string[] = [ + "citadel", + "fortress", + "garden", + "harmonic", + "ionic", +]; /** * Validate all Gazebo input distribution names @@ -91,3 +97,21 @@ export function getRequiredGazeboDistributions(): string[] { } return requiredGazeboDistributionsList; } + +/** + * Check for unstable repository inputs + * + * @returns unstableRepos unstable repository names + */ +export function checkForUnstableAptRepos(): string[] { + const unstableRepos: string[] = []; + const useGazeboPrerelease = core.getInput("use-gazebo-prerelease") === "true"; + if (useGazeboPrerelease) { + unstableRepos.push("prerelease"); + } + const useGazeboNightly = core.getInput("use-gazebo-nightly") === "true"; + if (useGazeboNightly) { + unstableRepos.push("nightly"); + } + return unstableRepos; +}