Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/bat.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,11 @@ jobs:
run: 'if [[ "${{ steps.setup_matlab.outputs.matlabroot }}" != *"MATLAB"* ]]; then exit 1; fi'
shell: bash
- name: Check MATLAB version
uses: matlab-actions/run-command@v2
uses: matlab-actions/run-command@v3
with:
command: "${{ matrix.check-matlab }}"
- name: Check toolbox version
uses: matlab-actions/run-command@v2
uses: matlab-actions/run-command@v3
with:
command: "${{ matrix.check-toolbox }}"
- name: Check NoOp on 2nd install
Expand All @@ -100,14 +100,14 @@ jobs:
products: Image_Processing_Toolbox
- name: Check additional product was installed
if: matrix.os != 'windows-latest'
uses: matlab-actions/run-command@v2
uses: matlab-actions/run-command@v3
with:
command: assert(any(strcmp({ver().Name},'Image Processing Toolbox')))
- name: Call setup MATLAB again with different release # should not error as in issue 130
uses: ./
with:
release: R2023b
- name: Check MATLAB version
uses: matlab-actions/run-command@v2
uses: matlab-actions/run-command@v3
with:
command: matlabVer = ver('matlab'); assert(strcmp(matlabVer.Release,'(R2023b)'));
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,10 +142,9 @@ When you define your workflow in the `.github/workflows` directory of your repos
| ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `release` | <p>(Optional) MATLAB release to set up. You can specify R2021a or a later release. By default, the value of `release` is `latest`, which corresponds to the latest release of MATLAB.</p><p><ul><li>To set up the latest update of a release, specify only the release name, for example, `R2024a`.</li><li>To set up a specific update release, specify the release name with an update number suffix, for example, `R2024aU4`.</li><li>To set up a release without updates, specify the release name with an update 0 or general release suffix, for example, `R2024aU0` or `R2024aGR`.</li></ul></p><p>**Example**: `release: R2024a`<br/>**Example**: `release: latest`<br/>**Example**: `release: R2024aU4`</p> |
| `products` | <p>(Optional) Products to set up in addition to MATLAB, specified as a list of product names separated by spaces. You can specify `products` to set up most MathWorks products and support packages. The action uses [MATLAB Package Manager](https://github.com/mathworks-ref-arch/matlab-dockerfile/blob/main/MPM.md) (`mpm`) to set up products.</p><p>For a list of supported products, open the input file for your preferred release from the [`mpm-input-files`](https://github.com/mathworks-ref-arch/matlab-dockerfile/tree/main/mpm-input-files) folder on GitHub. Specify products using the format shown in the input file, excluding the `#product.` prefix. For example, to set up Deep Learning Toolbox&trade; in addition to MATLAB, specify `products: Deep_Learning_Toolbox`.</p><p>For an example of how to use the `products` input, see [Run Tests in Parallel](#run-tests-in-parallel).</p><p>**Example**: `products: Simulink`<br/>**Example:** `products: Simulink Deep_Learning_Toolbox`</p> |
| `install-system-dependencies` | <p>(Optional) Option to install the dependencies required to run MATLAB and other MathWorks products, specified as one of these values:<ul><li>`auto` (default) — If the runner is GitHub-hosted, install the dependencies. Otherwise, do not install any dependencies.</li><li>`true` — Install the dependencies on the runner, regardless of its type.</li><li>`false` — Do not install any dependencies on the runner, regardless of its type.</li></ul></p><p>**Note**: On a self-hosted runner, if you specify this input as `true`, the runner must be configured with passwordless `sudo` access.</p><p>**Example**: `install-system-dependencies: true`</p> |
| `install-system-dependencies` | <p>(Optional) Option to install the dependencies required to run MATLAB and other MathWorks products, specified as one of these values:<ul><li>`auto` (default) — If the runner is GitHub-hosted, install the dependencies. Otherwise, do not install any dependencies.</li><li>`true` — Install the dependencies on the runner, regardless of its type.</li><li>`false` — Do not install any dependencies on the runner, regardless of its type.</li></ul></p><p>**Note**: On a self-hosted runner, if you specify this input as `true`, the runner must be configured with passwordless `sudo` access.</p><p>**Example**: `install-system-dependencies: true`</p> |
| `cache` | <p>(Optional) Option to enable caching with GitHub Actions, specified as `false` or `true`. By default, the value is `false` and the action does not store MATLAB and the specified products in a GitHub Actions cache for future use. For more information about caching with GitHub Actions, see [Caching dependencies to speed up workflows](https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows).</p><p>**Example**: `cache: true`</p> |


#### Required Software on Self-Hosted Runners

Setting up MATLAB and other MathWorks products on a self-hosted UNIX runner requires certain dependencies to be installed on the runner. You can install these dependencies by using the `install-system-dependencies` action input.
Expand Down
2 changes: 1 addition & 1 deletion action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ inputs:
description: >-
Option to install system dependencies for MATLAB, specified as auto, true, or false
required: false
default: auto
default: auto
cache:
description: >-
Option to enable caching with GitHub Actions, specified as false or true
Expand Down
29 changes: 29 additions & 0 deletions devel/contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,32 @@ Familiarize yourself with the best practices for [releasing and maintaining GitH
Changes should be made on a new branch. The new branch should be merged to the main branch via a pull request. Ensure that all of the CI pipeline checks and tests have passed for your changes.

After the pull request has been approved and merged to main, follow the Github process for [creating a new release](https://docs.github.com/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository). The release must follow semantic versioning (ex: vX.Y.Z). This will kick off a new pipeline execution, and the action will automatically be published to the GitHub Actions Marketplace if the pipeline finishes successfully. Check the [GitHub Marketplace](https://github.com/marketplace/actions/setup-matlab) and check the major version in the repository (ex: v1 for v1.0.0) to ensure that the new semantically versioned tag is available.

## Adding a Pre-Commit Hook

You can run all CI checks before each commit by adding a pre-commit hook. To do so, navigate to the repository root folder and run the following commands:

_bash (Linux/macOS)_

```sh
echo '#!/bin/sh' > .git/hooks/pre-commit
echo 'npm run ci' >> .git/hooks/pre-commit
chmod +x .git/hooks/pre-commit
```

_Command Prompt (Windows)_

```cmd
echo #!/bin/sh > .git\hooks\pre-commit
echo npm run ci >> .git\hooks\pre-commit
```

_PowerShell (Windows)_

```pwsh
Set-Content .git\hooks\pre-commit '#!/bin/sh'
Add-Content .git\hooks\pre-commit 'npm run ci'
```

> **Note:**
> Git hooks are not version-controlled, so you need to set up this hook for each fresh clone of the repository.
2 changes: 1 addition & 1 deletion jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export default {
},
],
},
extensionsToTreatAsEsm: ['.ts'],
extensionsToTreatAsEsm: [".ts"],
transformIgnorePatterns: ["node_modules/(?!(@actions)/)"],
moduleNameMapper: {
"^(\\.{1,2}/.*)\\.js$": "$1",
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"build": "tsc",
"package": "ncc build src/index.ts -o dist/setup --minify && ncc build src/post.ts -o dist/cache-save --minify",
"test": "NODE_OPTIONS='--experimental-vm-modules' jest",
"all": "npm run lint && npm test && npm run build && npm run package",

@davidbuzinski davidbuzinski Apr 7, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the only substantial change I made to the action in this change (other than the actions versions in the workflow). This will fail a CI job if there's formatter findings.

"all": "npm run format-check && npm run lint && npm test && npm run build && npm run package",
"ci": "npm run clean && npm ci && npm run all"
},
"files": [
Expand Down
12 changes: 9 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import * as core from "@actions/core";
import * as install from "./install.js";


/**
* Gather action inputs and then run action.
*/
Expand All @@ -14,8 +13,15 @@ export async function run() {
const products = core.getMultilineInput("products");
const cache = core.getBooleanInput("cache");
const installSystemDependencies = core.getInput("install-system-dependencies");

return install.install(platform, architecture, release, products, cache, installSystemDependencies);

return install.install(
platform,
architecture,
release,
products,
cache,
installSystemDependencies,
);
}

run().catch((e) => {
Expand Down
20 changes: 11 additions & 9 deletions src/install.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,31 +7,34 @@ import * as path from "path";
import * as cache from "./cache-restore.js";
import { State } from "./install-state.js";


export function resolveInstallDependencies(input: string): boolean {
const normalized = (input ?? '').trim().toLowerCase();
const normalized = (input ?? "").trim().toLowerCase();

if (normalized === 'true') {
if (normalized === "true") {
return true;
}

if (normalized === 'false'){
if (normalized === "false") {
return false;
}

if (normalized === 'auto') {
if (normalized === "auto") {
// detect runner type and provide value accordingly
const runnerEnvironment = process.env["RUNNER_ENVIRONMENT"];
const agentIsSelfHosted = process.env["AGENT_ISSELFHOSTED"];

const isGitHubHosted = runnerEnvironment === "github-hosted" && agentIsSelfHosted !== "1";

core.info(`Auto-detected runner type: ${isGitHubHosted ? 'GitHub-hosted' : 'self-hosted'}`);
core.info(`System dependencies will ${isGitHubHosted ? 'be' : 'not be'} installed (auto mode)`);
core.info(`Auto-detected runner type: ${isGitHubHosted ? "GitHub-hosted" : "self-hosted"}`);
core.info(
`System dependencies will ${isGitHubHosted ? "be" : "not be"} installed (auto mode)`,
);

return isGitHubHosted;
}
throw new Error(`Invalid value for install-system-dependencies: "${input}". Must be "auto", "true", or "false".`);
throw new Error(
`Invalid value for install-system-dependencies: "${input}". Must be "auto", "true", or "false".`,
);
}

/**
Expand All @@ -48,7 +51,6 @@ export function resolveInstallDependencies(input: string): boolean {
* @param installSystemDeps Input value for install-system-dependencies ("auto" | "true" | "false")
*/


export async function install(
platform: string,
architecture: string,
Expand Down
33 changes: 18 additions & 15 deletions src/install.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,10 @@ describe("resolveInstallDependencies function", () => {

expect(() => {
install.resolveInstallDependencies("");
}).toThrow('Invalid value for install-system-dependencies: "". Must be "auto", "true", or "false".');
});
}).toThrow(
'Invalid value for install-system-dependencies: "". Must be "auto", "true", or "false".',
);
});

// for empty string should throw error for self hosted
it("throws error for empty string input for self-hosted runner", () => {
Expand All @@ -102,14 +104,18 @@ describe("resolveInstallDependencies function", () => {

expect(() => {
install.resolveInstallDependencies("");
}).toThrow('Invalid value for install-system-dependencies: "". Must be "auto", "true", or "false".');
});
}).toThrow(
'Invalid value for install-system-dependencies: "". Must be "auto", "true", or "false".',
);
});

// for any invalid input should throw error
it("throws error for invalid string input", () => {
expect(() => {
install.resolveInstallDependencies("invalid-value");
}).toThrow('Invalid value for install-system-dependencies: "invalid-value". Must be "auto", "true", or "false".');
}).toThrow(
'Invalid value for install-system-dependencies: "invalid-value". Must be "auto", "true", or "false".',
);
});
});

Expand Down Expand Up @@ -145,9 +151,13 @@ describe("install procedure", () => {
install.install(platform, arch, release, products, useCache, installSystemDependencies);

beforeEach(() => {
matlabInstallSystemDependenciesMock = matlab.installSystemDependencies as jest.Mock<typeof matlab.installSystemDependencies>;
matlabInstallSystemDependenciesMock = matlab.installSystemDependencies as jest.Mock<
typeof matlab.installSystemDependencies
>;
matlabGetReleaseInfoMock = matlab.getReleaseInfo as jest.Mock<typeof matlab.getReleaseInfo>;
matlabGetToolcacheDirMock = matlab.getToolcacheDir as jest.Mock<typeof matlab.getToolcacheDir>;
matlabGetToolcacheDirMock = matlab.getToolcacheDir as jest.Mock<
typeof matlab.getToolcacheDir
>;
matlabSetupBatchMock = matlab.setupBatch as jest.Mock<typeof matlab.setupBatch>;
mpmSetupMock = mpm.setup as jest.Mock<typeof mpm.setup>;
mpmInstallMock = mpm.install as jest.Mock<typeof mpm.install>;
Expand Down Expand Up @@ -202,14 +212,7 @@ describe("install procedure", () => {
isPrerelease: false,
});
await expect(
install.install(
platform,
arch,
"r2020a",
products,
useCache,
"true",
),
install.install(platform, arch, "r2020a", products, useCache, "true"),
).rejects.toBeDefined();
});

Expand Down
8 changes: 6 additions & 2 deletions src/matlab.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,9 @@ describe("matlab tests", () => {
runnerToolcache = process.env["RUNNER_TOOL_CACHE"];

process.env["RUNNER_TOOL_CACHE"] = "C:\\hostedtoolcache\\windows\\matlab\\r2022b";
cacheFileMock.mockImplementation(() => Promise.resolve(process.env["RUNNER_TOOL_CACHE"] ?? ""));
cacheFileMock.mockImplementation(() =>
Promise.resolve(process.env["RUNNER_TOOL_CACHE"] ?? ""),
);
findMock.mockReturnValue("");
});

Expand Down Expand Up @@ -353,7 +355,9 @@ describe("matlab tests", () => {
const release = "r2023b";

beforeEach(() => {
downloadAndRunScriptMock = script.downloadAndRunScript as jest.Mock<typeof script.downloadAndRunScript>;
downloadAndRunScriptMock = script.downloadAndRunScript as jest.Mock<
typeof script.downloadAndRunScript
>;
tcDownloadToolMock = tc.downloadTool as jest.Mock<typeof tc.downloadTool>;
execMock = exec.exec as jest.Mock<typeof exec.exec>;
});
Expand Down
4 changes: 3 additions & 1 deletion src/mpm.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ describe("setup mpm", () => {
tcDownloadToolMock = tc.downloadTool as jest.Mock<typeof tc.downloadTool>;
tcCacheFileMock = tc.cacheFile as jest.Mock<typeof tc.cacheFile>;
execMock = exec.exec as jest.Mock<typeof exec.exec>;
defaultInstallRootMock = script.defaultInstallRoot as jest.Mock<typeof script.defaultInstallRoot>;
defaultInstallRootMock = script.defaultInstallRoot as jest.Mock<
typeof script.defaultInstallRoot
>;
tcDownloadToolMock.mockResolvedValue(mpmMockPath);
tcCacheFileMock.mockResolvedValue(mpmMockPath);
process.env.RUNNER_TEMP = path.join("runner", "workdir", "tmp");
Expand Down
Loading