Skip to content

Commit

Permalink
feat(ado-gha-axe-core): Add Job Summary to GH Action (#1204)
Browse files Browse the repository at this point in the history
* add job summary creator

* swap smarkdownSummary for summary due to deprecation
  • Loading branch information
brocktaylor7 committed Jun 13, 2022
1 parent 6b4e71f commit 3c4d60e
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 1 deletion.
5 changes: 4 additions & 1 deletion packages/gh-action/src/ioc/setup-ioc-container.ts
Expand Up @@ -10,20 +10,23 @@ import { GitHubIocTypes } from './gh-ioc-types';
import { CheckRunCreator } from '../check-run/check-run-creator';
import { GitHubArtifactsInfoProvider } from '../gh-artifacts-info-provider';
import { ConsoleCommentCreator } from '../console/console-comment-creator';
import { JobSummaryCreator } from '../job-summary/job-summary-creator';

export function setupIocContainer(container = new inversify.Container({ autoBindInjectable: true })): inversify.Container {
container = setupSharedIocContainer(container);
container.bind(GitHubIocTypes.Github).toConstantValue(github);
container.bind(iocTypes.TaskConfig).to(GHTaskConfig).inSingletonScope();
container.bind(CheckRunCreator).toSelf().inSingletonScope();
container.bind(JobSummaryCreator).toSelf().inSingletonScope();
container.bind(ConsoleCommentCreator).toSelf().inSingletonScope();
container
.bind(iocTypes.ProgressReporters)
.toDynamicValue((context) => {
const consoleCommentCreator = context.container.get(ConsoleCommentCreator);
const checkRunCreator = context.container.get(CheckRunCreator);
const jobSummaryCreator = context.container.get(JobSummaryCreator);

return [checkRunCreator, consoleCommentCreator];
return [checkRunCreator, consoleCommentCreator, jobSummaryCreator];
})
.inSingletonScope();

Expand Down
61 changes: 61 additions & 0 deletions packages/gh-action/src/job-summary/job-summary-creator.spec.ts
@@ -0,0 +1,61 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
import 'reflect-metadata';
import { IMock, Mock } from 'typemoq';
import { Logger, ReportMarkdownConvertor } from '@accessibility-insights-action/shared';
import { CombinedReportParameters } from 'accessibility-insights-report';
import { JobSummaryCreator } from './job-summary-creator';
import { GHTaskConfig } from '../task-config/gh-task-config';

describe(JobSummaryCreator, () => {
let testSubject: JobSummaryCreator;
let reportMarkdownConvertorMock: IMock<ReportMarkdownConvertor>;
let loggerMock: IMock<Logger>;
let taskConfigMock: IMock<GHTaskConfig>;

const markdownContent = 'test markdown content';
const combinedReportResult = { serviceName: 'combinedReportResult' } as CombinedReportParameters;

beforeEach(() => {
taskConfigMock = Mock.ofType<GHTaskConfig>();
reportMarkdownConvertorMock = Mock.ofType(ReportMarkdownConvertor);
loggerMock = Mock.ofType(Logger);
testSubject = new JobSummaryCreator(taskConfigMock.object, reportMarkdownConvertorMock.object, loggerMock.object);
});

afterEach(() => {
reportMarkdownConvertorMock.verifyAll();
loggerMock.verifyAll();
});

describe('start', () => {
it('does nothing', async () => {
await expect(testSubject.start()).resolves.toBeUndefined();
});
});

describe('didScanSucceed', () => {
it('returns true by default', async () => {
await expect(testSubject.didScanSucceed()).resolves.toBe(true);
});

it('returns false after failRun() is called', async () => {
await testSubject.failRun();
await expect(testSubject.didScanSucceed()).resolves.toBe(false);
});
});

describe('completeRun', () => {
it('converts to markdown and writes the job summary', async () => {
reportMarkdownConvertorMock
.setup((a) => a.convert(combinedReportResult))
.returns(() => markdownContent)
.verifiable();
taskConfigMock
.setup((a) => a.writeJobSummary(markdownContent))
.returns(() => Promise.resolve())
.verifiable();
await testSubject.completeRun(combinedReportResult);
});
});
});
39 changes: 39 additions & 0 deletions packages/gh-action/src/job-summary/job-summary-creator.ts
@@ -0,0 +1,39 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

import { inject, injectable } from 'inversify';
import { iocTypes, Logger, ProgressReporter, ReportMarkdownConvertor } from '@accessibility-insights-action/shared';
import { CombinedReportParameters } from 'accessibility-insights-report';
import { GHTaskConfig } from '../task-config/gh-task-config';

@injectable()
export class JobSummaryCreator extends ProgressReporter {
private scanSucceeded = true;

constructor(
@inject(iocTypes.TaskConfig) private readonly taskConfig: GHTaskConfig,
@inject(ReportMarkdownConvertor) private readonly reportMarkdownConvertor: ReportMarkdownConvertor,
@inject(Logger) private readonly logger: Logger,
) {
super();
}

public start(): Promise<void> {
this.logger.logDebug('job summary creator started');
return Promise.resolve();
}

public async completeRun(combinedReportResult: CombinedReportParameters): Promise<void> {
const reportMarkdown = this.reportMarkdownConvertor.convert(combinedReportResult);
return await this.taskConfig.writeJobSummary(reportMarkdown);
}

// eslint-disable-next-line @typescript-eslint/require-await
public async failRun(): Promise<void> {
this.scanSucceeded = false;
}

public didScanSucceed(): Promise<boolean> {
return Promise.resolve(this.scanSucceeded);
}
}
17 changes: 17 additions & 0 deletions packages/gh-action/src/task-config/gh-task-config.spec.ts
Expand Up @@ -12,17 +12,20 @@ describe(GHTaskConfig, () => {
let processStub: any;
let actionCoreMock: IMock<typeof actionCore>;
let taskConfig: GHTaskConfig;
let markdownSummaryMock: IMock<typeof actionCore.summary>;

beforeEach(() => {
processStub = {
env: {},
} as any;
actionCoreMock = Mock.ofType<typeof actionCore>();
markdownSummaryMock = Mock.ofType<typeof actionCore.summary>();
taskConfig = new GHTaskConfig(processStub, actionCoreMock.object);
});

afterEach(() => {
actionCoreMock.verifyAll();
markdownSummaryMock.verifyAll();
});

function getPlatformAgnosticPath(inputPath: string): string {
Expand Down Expand Up @@ -126,4 +129,18 @@ describe(GHTaskConfig, () => {

expect(actualRunId).toBe(runId);
});

it('should write job summary', async () => {
const markdownStub = 'markdownStub';

markdownSummaryMock
.setup((o) => o.addRaw(markdownStub))
.returns(() => markdownSummaryMock.object)
.verifiable();
markdownSummaryMock.setup((o) => o.write()).verifiable();

actionCoreMock.setup((o) => o.summary).returns(() => markdownSummaryMock.object);

await taskConfig.writeJobSummary(markdownStub);
});
});
4 changes: 4 additions & 0 deletions packages/gh-action/src/task-config/gh-task-config.ts
Expand Up @@ -98,6 +98,10 @@ export class GHTaskConfig extends TaskConfig {
return keyToName[key];
}

public async writeJobSummary(jobSummaryMarkdown: string): Promise<void> {
await this.actionCoreObj.summary.addRaw(jobSummaryMarkdown).write();
}

public getUsageDocsUrl(): string {
const url = 'https://github.com/microsoft/accessibility-insights-action/blob/main/docs/gh-action-usage.md';
return url;
Expand Down

0 comments on commit 3c4d60e

Please sign in to comment.