Skip to content

Commit

Permalink
Generate GitHub Actions summary
Browse files Browse the repository at this point in the history
Write a summary report to `$GITHUB_STEP_SUMMARY` by default containing the SDK version, release date and any CVEs.

Resolves #145.
  • Loading branch information
martincostello committed May 3, 2023
1 parent 4142ef0 commit c2c02b9
Show file tree
Hide file tree
Showing 10 changed files with 85 additions and 4 deletions.
6 changes: 6 additions & 0 deletions .github/workflows/update-dotnet-sdk.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ on:
required: false
type: string
default: ''
generate-step-summary:
description: 'If true, will output a summary of any .NET SDK update to $GITHUB_STEP_SUMMARY.'
required: false
type: boolean
default: true
global-json-file:
description: 'The optional path to the global.json file to update.'
required: false
Expand Down Expand Up @@ -164,6 +169,7 @@ jobs:
channel: ${{ inputs.channel }}
commit-message: ${{ inputs.commit-message }}
dry-run: ${{ inputs.dry-run }}
generate-step-summary: ${{ inputs.generate-step-summary }}
global-json-file: ${{ inputs.global-json-file }}
labels: ${{ inputs.labels }}
repo-token: ${{ steps.assign-token.outputs.access-token }}
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ jobs:
| `branch-name` | The optional Git branch name to use. | - |
| `channel` | The optional .NET release channel to download the SDK for (3.1, 6.0, etc.). | The channel derived from the current SDK version. |
| `commit-message` | The optional Git commit message to use. | - |
| `generate-step-summary` | If true, will output a summary of any .NET SDK update to `$GITHUB_STEP_SUMMARY`. | `true` |
| `global-json-file` | The optional path to the global.json file to update the SDK for. | `./global.json` |
| `labels` | The optional comma-separated label(s) to apply to Pull Requests generated by the action. | - |
| `user-email` | The optional email address to use for the Git commit. | `github-actions[bot]@users.noreply.github.com` |
Expand Down
4 changes: 4 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ inputs:
description: 'The optional Git commit message to use.'
required: false
default: ''
generate-step-summary:
description: 'If true, will output a summary of any .NET SDK update to $GITHUB_STEP_SUMMARY.'
required: false
default: true
global-json-file:
description: 'The optional path to the global.json file to update.'
required: false
Expand Down
4 changes: 2 additions & 2 deletions dist/index.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/index.js.map

Large diffs are not rendered by default.

46 changes: 46 additions & 0 deletions src/DotNetSdkUpdater.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,46 @@ export class DotNetSdkUpdater {
return body;
}

public static async generateSummary(update: SdkVersions, today: Date): Promise<string> {
const daysSinceRelease = Math.floor((today.getTime() - update.latest.releaseDate.getTime()) / (24 * 60 * 60 * 1000));
const daysUnit = daysSinceRelease === 1 ? 'day' : 'days';
const iso8601Date = update.latest.releaseDate.toISOString().split('T')[0];

let summary = core.summary
.addHeading(`.NET SDK ${update.latest.sdkVersion}`, 1)
.addRaw(`An update from version ${update.current.sdkVersion} to ${update.latest.sdkVersion} of the .NET SDK is available.`)
.addBreak()
.addBreak()
.addRaw(`This version of the .NET SDK was released on ${iso8601Date} (${daysSinceRelease} ${daysUnit} ago).`)
.addBreak()
.addBreak()
.addLink(`Release notes`, update.latest.releaseNotes);

if (update.security) {
summary = summary
.addHeading('Security Issues', 2)
.addRaw('This update includes fixes for the following security issues:')
.addBreak()
.addBreak()
.addList(
update.securityIssues.map((p) => p.id),
false
);
}

const result = summary.stringify();

try {
await summary.write();
} catch (err) {
// Swallow errors attempting to write to GITHUB_STEP_SUMMARY
} finally {
summary.emptyBuffer();
}

return result;
}

public async tryUpdateSdk(): Promise<UpdateResult> {
const globalJson: GlobalJson = JSON.parse(fs.readFileSync(this.options.globalJsonPath, { encoding: 'utf8' }));

Expand Down Expand Up @@ -166,6 +206,10 @@ export class DotNetSdkUpdater {
result.security = update.security;
result.updated = true;
result.version = update.latest.sdkVersion;

if (this.options.generateStepSummary) {
await DotNetSdkUpdater.generateSummary(update, new Date());
}
}
} else {
core.info('The current .NET SDK version is up-to-date');
Expand Down Expand Up @@ -327,6 +371,7 @@ export class DotNetSdkUpdater {
const release = releasesForSdk[0];

const result = {
releaseDate: new Date(release['release-date']),
releaseNotes: release['release-notes'],
runtimeVersion: release.runtime.version,
sdkVersion: foundSdk.version,
Expand Down Expand Up @@ -433,6 +478,7 @@ interface PullRequest {
}

interface ReleaseInfo {
releaseDate: Date;
releaseNotes: string;
runtimeVersion: string;
sdkVersion: string;
Expand Down
1 change: 1 addition & 0 deletions src/UpdateOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export interface UpdateOptions {
channel: string;
commitMessage: string;
dryRun: boolean;
generateStepSummary: boolean;
globalJsonPath: string;
labels: string;
repo?: string;
Expand Down
1 change: 1 addition & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export async function run(): Promise<void> {
channel: core.getInput('channel', { required: false }),
commitMessage: core.getInput('commit-message', { required: false }),
dryRun: core.getInput('dry-run', { required: false }) === 'true',
generateStepSummary: core.getInput('generate-step-summary', { required: false }) === 'true',
globalJsonPath,
labels: core.getInput('labels', { required: false }) ?? '',
repo: process.env.GITHUB_REPOSITORY,
Expand Down
19 changes: 19 additions & 0 deletions tests/DotNetSdkUpdater.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ describe('DotNetSdkUpdater tests', () => {
channel: '7.0',
commitMessage: '',
dryRun: false,
generateStepSummary: false,
globalJsonPath: '',
labels: '',
userEmail: '',
Expand All @@ -200,4 +201,22 @@ describe('DotNetSdkUpdater tests', () => {
const actual = updater.DotNetSdkUpdater.generatePullRequestBody(versions, options);
expect(actual).toContain('\n * [CVE-2022-41089](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-41089)\n * [CVE-2023-21808](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-21808)');
});

test.each([
['3.1', '3.1.403', '2023-05-02', '3.1.404', '903 days'],
['5.0', '5.0.102', '2023-05-02', '5.0.200', '791 days'],
['6.0', '6.0.407', '2023-05-02', '6.0.408', '21 days'],
['7.0', '7.0.201', '2023-03-14', '7.0.202', '0 days'],
['7.0', '7.0.201', '2023-03-15', '7.0.202', '1 day'],
['7.0', '7.0.201', '2023-03-16', '7.0.202', '2 days'],
['7.0', '7.0.201', '2023-05-02', '7.0.202', '49 days'],
['8.0', '8.0.100-preview.2.23157.25', '2023-05-02', '8.0.100-preview.3.23178.7', '21 days']
])('Generates correct GitHub step summary for %s from %s on %s', async (channelVersion, sdkVersion, date, expectedSdkVersion, expectedDaysAgo) => {
const today = new Date(date);
const channel = JSON.parse(fs.readFileSync(path.join(process.cwd(), 'tests', `releases-${channelVersion}.json`), {encoding: 'utf8'}));
const versions = updater.DotNetSdkUpdater.getLatestRelease(sdkVersion, channel);
const actual = await updater.DotNetSdkUpdater.generateSummary(versions, today);
expect(actual).toContain(`<h1>.NET SDK ${expectedSdkVersion}</h1>`);
expect(actual).toContain(`(${expectedDaysAgo} ago)`);
});
});
5 changes: 4 additions & 1 deletion tests/main.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@ import {afterEach, beforeEach, describe, expect, jest, test} from '@jest/globals

const tempDir = path.join(os.tmpdir(), 'update-dotnet-sdk-temp');
const globalJsonPath = path.join(tempDir, 'global.json');
const githubStepSummary = path.join(tempDir, 'github-step-summary.md');

describe('update-dotnet-sdk tests', () => {
const inputs = {
'GITHUB_API_URL': 'https://github.local/api/v3',
'GITHUB_REPOSITORY': '',
'GITHUB_SERVER_URL': 'https://github.local',
'GITHUB_STEP_SUMMARY': githubStepSummary,
'INPUT_GLOBAL-JSON-FILE': globalJsonPath,
'INPUT_LABELS': 'foo,bar',
'INPUT_REPO-TOKEN': 'my-token',
Expand All @@ -42,7 +44,8 @@ describe('update-dotnet-sdk tests', () => {

afterEach(async () => {
try {
await io.rmRF(path.join(tempDir, 'global.json'));
await io.rmRF(globalJsonPath);
await io.rmRF(githubStepSummary);
await io.rmRF(tempDir);
} catch {
console.log('Failed to remove test directories');
Expand Down

0 comments on commit c2c02b9

Please sign in to comment.