diff --git a/plugins/+ciplugins/+github/BuildSummaryPlugin.m b/plugins/+ciplugins/+github/BuildSummaryPlugin.m index 1eed7a1..efbaa13 100644 --- a/plugins/+ciplugins/+github/BuildSummaryPlugin.m +++ b/plugins/+ciplugins/+github/BuildSummaryPlugin.m @@ -2,27 +2,46 @@ % Copyright 2024 The MathWorks, Inc. - methods (Access=protected) + properties (Access=private) + TaskDetails = {}; + end + methods (Access=protected) function runTaskGraph(plugin, pluginData) runTaskGraph@matlab.buildtool.plugins.BuildRunnerPlugin(plugin, pluginData); - [fID, msg] = fopen(fullfile(getenv("RUNNER_TEMP") ,"buildSummary" + getenv("GITHUB_RUN_ID") + ".json"), "w"); + [fID, msg] = fopen(fullfile(getenv("RUNNER_TEMP") ,"buildSummary" + getenv("GITHUB_RUN_ID") + ".json"), "w"); if fID == -1 warning("ciplugins:github:BuildSummaryPlugin:UnableToOpenFile","Unable to open a file required to create the MATLAB build summary table: %s", msg); else closeFile = onCleanup(@()fclose(fID)); - taskDetails = struct(); - for idx = 1:numel(pluginData.TaskResults) - taskDetails(idx).name = pluginData.TaskResults(idx).Name; - taskDetails(idx).description = pluginData.TaskGraph.Tasks(idx).Description; - taskDetails(idx).failed = pluginData.TaskResults(idx).Failed; - taskDetails(idx).skipped = pluginData.TaskResults(idx).Skipped; - taskDetails(idx).duration = string(pluginData.TaskResults(idx).Duration); - end - s = jsonencode(taskDetails); + s = jsonencode(plugin.TaskDetails); fprintf(fID, "%s",s); end end + + function runTask(plugin, pluginData) + runTask@matlab.buildtool.plugins.BuildRunnerPlugin(plugin, pluginData); + + taskDetail = getCommonTaskDetail(pluginData); + plugin.TaskDetails = [plugin.TaskDetails, taskDetail]; + end + + function skipTask(plugin, pluginData) + skipTask@matlab.buildtool.plugins.BuildRunnerPlugin(plugin, pluginData); + + taskDetail = getCommonTaskDetail(pluginData); + taskDetail.skipReason = pluginData.SkipReason; + plugin.TaskDetails = [plugin.TaskDetails, taskDetail]; + end end +end + +function taskDetail = getCommonTaskDetail(pluginData) + taskDetail = struct(); + taskDetail.name = pluginData.TaskResults.Name; + taskDetail.description = pluginData.TaskGraph.Tasks.Description; + taskDetail.failed = pluginData.TaskResults.Failed; + taskDetail.skipped = pluginData.TaskResults.Skipped; + taskDetail.duration = string(pluginData.TaskResults.Duration); end \ No newline at end of file diff --git a/src/buildSummary.ts b/src/buildSummary.ts index edc9ebf..927fba9 100644 --- a/src/buildSummary.ts +++ b/src/buildSummary.ts @@ -3,14 +3,6 @@ import * as core from "@actions/core"; import { join } from 'path'; import { readFileSync, unlinkSync, existsSync } from 'fs'; -export interface Task { - name: string; - description: string; - failed: boolean; - skipped: boolean; - duration: string; -} - export function writeSummary(taskSummaryTableRows: string[][]) { try { core.summary @@ -24,20 +16,34 @@ export function writeSummary(taskSummaryTableRows: string[][]) { export function getSummaryRows(buildSummary: string): any[] { const rows = JSON.parse(buildSummary).map((t: any) => { if (t.failed) { - return [t.name, '🔴 Failed', t.description, t.duration.toString()]; + return [t.name, '🔴 Failed', t.description, t.duration]; } else if (t.skipped) { - return [t.name, '🔵 Skipped', t.description, t.duration.toString()]; + return [t.name, '🔵 Skipped' + ' (' + interpretSkipReason(t.skipReason) + ')', t.description, t.duration]; } else { - return [t.name, '🟢 Success', t.description, t.duration.toString()]; + return [t.name, '🟢 Succeeded', t.description, t.duration]; } }); return rows; } +export function interpretSkipReason(skipReason: string){ + switch(skipReason) { + case "UpToDate": + return "up-to-date"; + case "UserSpecified": + case "UserRequested": + return "user requested"; + case "DependencyFailed": + return "dependency failed"; + default: + return skipReason; + } +} + export function processAndDisplayBuildSummary() { const runId = process.env.GITHUB_RUN_ID || ''; const runnerTemp = process.env.RUNNER_TEMP || ''; - const header = [{ data: 'MATLAB Build Task', header: true }, { data: 'Status', header: true }, { data: 'Description', header: true }, { data: 'Duration (hh:mm:ss)', header: true }]; + const header = [{ data: 'MATLAB Task', header: true }, { data: 'Status', header: true }, { data: 'Description', header: true }, { data: 'Duration (HH:mm:ss)', header: true }]; const filePath: string = join(runnerTemp, `buildSummary${runId}.json`); let taskSummaryTable; diff --git a/src/buildSummary.unit.test.ts b/src/buildSummary.unit.test.ts index 6a97852..aeee551 100644 --- a/src/buildSummary.unit.test.ts +++ b/src/buildSummary.unit.test.ts @@ -15,22 +15,26 @@ describe('summaryGeneration', () => { it('should process and return summary rows for valid JSON with different task statuses', () => { const mockBuildSummary = JSON.stringify([ { name: 'Task 1', failed: true, skipped: false, description: 'Task 1 description', duration: '00:00:10' }, - { name: 'Task 2', failed: false, skipped: true, description: 'Task 2 description', duration: '00:00:20' }, - { name: 'Task 3', failed: false, skipped: false, description: 'Task 3 description', duration: '00:00:30' } + { name: 'Task 2', failed: false, skipped: true, skipReason: 'UserSpecified', description: 'Task 2 description', duration: '00:00:20' }, + { name: 'Task 3', failed: false, skipped: true, skipReason: 'DependencyFailed', description: 'Task 3 description', duration: '00:00:20' }, + { name: 'Task 4', failed: false, skipped: true, skipReason: 'UpToDate', description: 'Task 4 description', duration: '00:00:20' }, + { name: 'Task 5', failed: false, skipped: false, description: 'Task 5 description', duration: '00:00:30' } ]); const result = buildSummary.getSummaryRows(mockBuildSummary); expect(result).toEqual([ ['Task 1', '🔴 Failed', 'Task 1 description', '00:00:10'], - ['Task 2', '🔵 Skipped', 'Task 2 description', '00:00:20'], - ['Task 3', '🟢 Success', 'Task 3 description', '00:00:30'] + ['Task 2', '🔵 Skipped (user requested)', 'Task 2 description', '00:00:20'], + ['Task 3', '🔵 Skipped (dependency failed)', 'Task 3 description', '00:00:20'], + ['Task 4', '🔵 Skipped (up-to-date)', 'Task 4 description', '00:00:20'], + ['Task 5', '🟢 Succeeded', 'Task 5 description', '00:00:30'] ]); }); it('writes the summary correctly', () => { const mockTableRows = [ - ['MATLAB Build Task', 'Status', 'Description', 'Duration (hh:mm:ss)'], + ['MATLAB Task', 'Status', 'Description', 'Duration (HH:mm:ss)'], ['Test Task', '🔴 Failed', 'A test task', '00:00:10'], ];