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
17 changes: 17 additions & 0 deletions .github/workflows/bat.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,22 @@ permissions:
contents: read

jobs:
plugin-tests:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
- os: windows-latest
- os: macos-latest
steps:
- uses: actions/checkout@v5
- uses: matlab-actions/setup-matlab@v2
with:
release: latest-including-prerelease
- uses: matlab-actions/run-tests@v2

bat:
name: Build and Test
runs-on: ubuntu-22.04
Expand All @@ -14,3 +30,4 @@ jobs:
node-version: 20
- name: Perform npm tasks
run: npm run ci

32 changes: 23 additions & 9 deletions plugins/+buildframework/ParallelizableBuildSummaryPlugin.m
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
classdef ParallelizableBuildSummaryPlugin < matlab.buildtool.plugins.BuildRunnerPlugin

% Copyright 2025 The MathWorks, Inc.
% Copyright 2025-2026 The MathWorks, Inc.

properties
TempFolder
end

methods
function plugin = ParallelizableBuildSummaryPlugin()
tempRoot = getenv("RUNNER_TEMP");
plugin.TempFolder = fullfile(tempRoot, "taskDetails");
function plugin = ParallelizableBuildSummaryPlugin(options)
arguments
options.TempFolder (1,:) string = getenv("RUNNER_TEMP")
end

plugin.TempFolder = fullfile(options.TempFolder, "taskDetails");
end
end

Expand All @@ -31,7 +34,8 @@ function runBuild(plugin, pluginData)
end

% Write to file
[fID, msg] = fopen(fullfile(getenv("RUNNER_TEMP"), "buildSummary" + getenv("GITHUB_RUN_ID") + ".json"), "w");
folder = fileparts(plugin.TempFolder);
[fID, msg] = fopen(fullfile(folder, "buildSummary" + getenv("GITHUB_RUN_ID") + ".json"), "w");
if fID == -1
warning("buildframework:BuildSummaryPlugin:UnableToOpenFile","Unable to open a file required to create the MATLAB build summary table: %s", msg);
else
Expand All @@ -44,18 +48,28 @@ function runBuild(plugin, pluginData)
function runTask(plugin, pluginData)
runTask@matlab.buildtool.plugins.BuildRunnerPlugin(plugin, pluginData);

name = fullfile(plugin.TempFolder, pluginData.Name + ".mat");
name = fullfile(plugin.TempFolder, matlab.lang.makeValidName(pluginData.Name) + ".mat");
taskDetail = getCommonTaskDetail(pluginData);
save(name, "taskDetail");

try
save(name, "taskDetail");
catch e
warning("buildframework:BuildSummaryPlugin:UnableToSaveTrace", "Unable to save an artifact needed for the build summary.");
end
end

function skipTask(plugin, pluginData)
skipTask@matlab.buildtool.plugins.BuildRunnerPlugin(plugin, pluginData);

name = fullfile(plugin.TempFolder, pluginData.Name + ".mat");
name = fullfile(plugin.TempFolder, matlab.lang.makeValidName(pluginData.Name) + ".mat");
taskDetail = getCommonTaskDetail(pluginData);
taskDetail.skipReason = pluginData.SkipReason;
save(name, "taskDetail");

try
save(name, "taskDetail");
catch e
warning("buildframework:BuildSummaryPlugin:UnableToSaveTrace", "Unable to save an artifact needed for the build summary.");
end
end
end
end
Expand Down
110 changes: 110 additions & 0 deletions plugins/tests/tParallelizableBuildSummaryPlugin.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
classdef tParallelizableBuildSummaryPlugin < matlab.unittest.TestCase

% Copyright 2026 The MathWorks, Inc.

properties
TempFolder
Plugin
Runner
end

methods (TestClassSetup)
function setupPath(testCase)
import matlab.unittest.fixtures.PathFixture;

testCase.applyFixture(PathFixture(fileparts(fileparts(mfilename("fullpath")))));
end
end

methods (TestMethodSetup)
function createPlugin(testCase)
import matlab.unittest.fixtures.WorkingFolderFixture;

testCase.applyFixture(WorkingFolderFixture);
testCase.TempFolder = pwd();

testCase.Plugin = ParallelizableBuildSummaryPlugin(TempFolder=testCase.TempFolder);
testCase.Runner = matlab.buildtool.BuildRunner.withNoPlugins();
testCase.Runner.addPlugin(testCase.Plugin);
end
end

methods (Test)
function runningBuildCreatesSummaryArtifact(testCase)
plan = buildplan();
plan("t1") = Task();
plan("t2") = Task();

testCase.Runner.run(plan, ["t1", "t2"]);

name = "buildSummary" + getenv("GITHUB_RUN_ID") + ".json";
testCase.verifyTrue(isfile(fullfile(testCase.TempFolder, name)));
end

function runningBuildCreatesSummaryArtifactWithExpectedTasks(testCase)
plan = buildplan();
plan("t1") = Task();
plan("t2") = Task();

testCase.Runner.run(plan, ["t1", "t2"]);

name = "buildSummary" + getenv("GITHUB_RUN_ID") + ".json";
f = fullfile(testCase.TempFolder, name);
testCase.assertTrue(isfile(f));

s = readstruct(f);

testCase.verifySize(s, [1 2]);
testCase.verifyEqual(s(1).name, "t1");
testCase.verifyEqual(s(2).name, "t2");
end

function summaryArtifactStatusesAreCorrect(testCase)
plan = buildplan();
plan("t1") = Task();
plan("t2") = Task(Actions=@()error("bam"));

testCase.Runner.run(plan, ["t1", "t2"]);

name = "buildSummary" + getenv("GITHUB_RUN_ID") + ".json";
f = fullfile(testCase.TempFolder, name);
testCase.assertTrue(isfile(f));

s = readstruct(f);

testCase.verifySize(s, [1 2]);

testCase.verifyFalse(s(1).failed);
testCase.verifyFalse(s(1).skipped);

testCase.verifyTrue(s(2).failed);
testCase.verifyFalse(s(2).skipped);
end

function runningBuildCreatesSummaryForTaskGroups(testCase)
plan = buildplan();
plan("g:t") = Task();

testCase.Runner.run(plan, "g:t");

name = "buildSummary" + getenv("GITHUB_RUN_ID") + ".json";
f = fullfile(testCase.TempFolder, name);

testCase.assertTrue(isfile(f));

s = readstruct(f);

testCase.verifySize(s, [1 1]);
testCase.verifyEqual(s(1).name, "g:t");
end
end

end

function plugin = ParallelizableBuildSummaryPlugin(varargin)
plugin = buildframework.ParallelizableBuildSummaryPlugin(varargin{:});
end

function task = Task(varargin)
task = matlab.buildtool.Task(varargin{:});
end
Loading