Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add breaking/dangerous/safe messages to action output #2690

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
10 changes: 10 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ inputs:
For example, "Check Public API" and "Check Internal API".
annotations:
description: Use annotation (enabled by default)
create-action-check:
description: |
Create Github Action check with summary. When disabled, annotations are disabled too. (enabled by default)
It can be useful to disable, when running on master branch or similar. And when subsequent step is using output and annotations nor check is required.
fail-on-breaking:
description: Fail on breaking changes (enabled by default)
approve-label:
Expand Down Expand Up @@ -56,6 +60,12 @@ inputs:
outputs:
changes:
description: Total number of changes
breaking-changes:
description: List of breaking changes. Each item is message string.
dangerous-changes:
description: List of dangerous changes. Each item is message string.
safe-changes:
description: List of safe changes. Each item is message string.
runs:
using: node20
main: action/index.js
43 changes: 42 additions & 1 deletion action/index.js

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions action/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"type": "module"
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@
"@types/express": "4.17.21",
"@types/node": "20.12.12",
"@types/yargs": "17.0.32",
"@zeit/ncc": "0.22.3",
"@vercel/ncc": "0.38.1",
"bob-the-bundler": "7.0.1",
"eslint": "8.57.0",
"graphql": "16.8.1",
Expand Down
6 changes: 6 additions & 0 deletions packages/action/helpers/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ export interface ActionResult {
changes?: Change[];
}

export interface GroupedChanges {
breaking: Change[];
dangerous: Change[];
safe: Change[];
}

export interface Annotation {
path: string;
start_line: number;
Expand Down
31 changes: 19 additions & 12 deletions packages/action/helpers/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Change, CriticalityLevel } from '@graphql-inspector/core';
import { Endpoint } from './config.js';
import { GroupedChanges } from './types.js';

export function bolderize(msg: string): string {
return quotesTransformer(msg, '**');
Expand Down Expand Up @@ -28,17 +29,23 @@ export function filterChangesByLevel(level: CriticalityLevel) {
return (change: Change) => change.criticality.level === level;
}

export function splitChangesIntoGroups(changes: Change[]): GroupedChanges {
return {
breaking: changes.filter(filterChangesByLevel(CriticalityLevel.Breaking)),
dangerous: changes.filter(filterChangesByLevel(CriticalityLevel.Dangerous)),
safe: changes.filter(filterChangesByLevel(CriticalityLevel.NonBreaking)),
};
}

export function createSummary(changes: Change[], summaryLimit: number, isLegacyConfig = false) {
const breakingChanges = changes.filter(filterChangesByLevel(CriticalityLevel.Breaking));
const dangerousChanges = changes.filter(filterChangesByLevel(CriticalityLevel.Dangerous));
const safeChanges = changes.filter(filterChangesByLevel(CriticalityLevel.NonBreaking));
const groupedChanges = splitChangesIntoGroups(changes);

const summary: string[] = [
`# Found ${changes.length} change${changes.length > 1 ? 's' : ''}`,
'',
`Breaking: ${breakingChanges.length}`,
`Dangerous: ${dangerousChanges.length}`,
`Safe: ${safeChanges.length}`,
`Breaking: ${groupedChanges.breaking.length}`,
`Dangerous: ${groupedChanges.dangerous.length}`,
`Safe: ${groupedChanges.safe.length}`,
];

if (isLegacyConfig) {
Expand Down Expand Up @@ -74,16 +81,16 @@ export function createSummary(changes: Change[], summaryLimit: number, isLegacyC
summaryLimit -= changes.length;
}

if (breakingChanges.length) {
addChangesToSummary('Breaking', breakingChanges);
if (groupedChanges.breaking.length) {
addChangesToSummary('Breaking', groupedChanges.breaking);
}

if (dangerousChanges.length) {
addChangesToSummary('Dangerous', dangerousChanges);
if (groupedChanges.dangerous.length) {
addChangesToSummary('Dangerous', groupedChanges.dangerous);
}

if (safeChanges.length) {
addChangesToSummary('Safe', safeChanges);
if (groupedChanges.safe.length) {
addChangesToSummary('Safe', groupedChanges.safe);
}

summary.push(
Expand Down
70 changes: 48 additions & 22 deletions packages/action/src/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { diff } from '../helpers/diff.js';
import { printSchemaFromEndpoint } from '../helpers/loaders.js';
import { produceSchema } from '../helpers/schema.js';
import { CheckConclusion } from '../helpers/types.js';
import { createSummary } from '../helpers/utils.js';
import { createSummary, splitChangesIntoGroups } from '../helpers/utils.js';
import { updateCheckRun } from './checks.js';
import { fileLoader } from './files.js';
import { getAssociatedPullRequest, getCurrentCommitSha } from './git.js';
Expand Down Expand Up @@ -41,6 +41,7 @@ export async function run() {
const approveLabel: string = core.getInput('approve-label') || 'approved-breaking-change';
const rulesList = getInputAsArray('rules') || [];
const onUsage = core.getInput('onUsage');
const createActionCheck = castToBoolean(core.getInput('create-action-check'), true);

const octokit = github.getOctokit(token);

Expand All @@ -50,19 +51,26 @@ export async function run() {
// pull request
const pullRequest = await getAssociatedPullRequest(octokit, commitSha);

core.info(`Creating a check named "${checkName}"`);

const check = await octokit.checks.create({
owner,
repo,
name: checkName,
head_sha: commitSha,
status: 'in_progress',
});
let checkId = null;
let seeCheckURL = '';
if (createActionCheck) {
core.info(`Creating a check named "${checkName}"`);

const check = await octokit.checks.create({
owner,
repo,
name: checkName,
head_sha: commitSha,
status: 'in_progress',
});

const checkId = check.data.id;
checkId = check.data.id;
seeCheckURL = ' For more info see: ' + check.data.html_url;

core.info(`Check ID: ${checkId}`);
core.info(`Check ID: ${checkId}`);
} else {
core.info('Skipping check creation - disabled by input option');
}

const schemaPointer = core.getInput('schema', { required: true });

Expand Down Expand Up @@ -188,8 +196,20 @@ export async function run() {
let annotations = action.annotations || [];
const changes = action.changes || [];

const groupedChanges = splitChangesIntoGroups(changes);
core.setOutput('changes', String(changes.length || 0));
core.info(`Changes: ${changes.length || 0}`);
core.setOutput(
'breaking-changes',
groupedChanges.breaking.map(c => c.message),
);
core.setOutput(
'dangerous-changes',
groupedChanges.dangerous.map(c => c.message),
);
core.setOutput(
'safe-changes',
groupedChanges.safe.map(c => c.message),
);

const hasApprovedBreakingChangeLabel = pullRequest?.labels?.some(
(label: any) => label.name === approveLabel,
Expand All @@ -204,20 +224,26 @@ export async function run() {
conclusion = CheckConclusion.Success;
}

if (useAnnotations === false || isNewSchemaUrl) {
core.info(`Anotations are disabled. Skipping annotations...`);
annotations = [];
}

const summary = createSummary(changes, 100, false);

const title =
conclusion === CheckConclusion.Failure
? 'Something is wrong with your schema'
? 'Something is wrong with your schema.' + seeCheckURL // add Check URL to navigate users to Check from action.
: 'Everything looks good';

core.info(`Conclusion: ${conclusion}`);

// Action Check is disabled
if (checkId === null) {
core.info('Github Action Check is disabled, use outputs to determine errors');
if (conclusion === CheckConclusion.Failure) {
core.setFailed(conclusion);
}
return;
}

if (useAnnotations === false || isNewSchemaUrl) {
core.info(`Anotations are disabled. Skipping annotations...`);
annotations = [];
}
const summary = createSummary(changes, 100, false);
try {
return await updateCheckRun(octokit, checkId, {
conclusion,
Expand Down
19 changes: 9 additions & 10 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

27 changes: 27 additions & 0 deletions website/src/pages/docs/products/action.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,19 @@ Use annotation (`true` by default).
annotations: false
```

### `create-action-check`

Create Github Action check with summary. When disabled, annotations are disabled too. (`true` by default)

It can be useful to disable, when running on master branch or similar. And when subsequent step is using output and annotations nor check is required.

```yaml
- uses: kamilkisiela/graphql-inspector@master
with:
schema: 'master:schema.graphql'
create-action-check: false
```

### `fail-on-breaking`

Fail on breaking changes (`true` by default).
Expand Down Expand Up @@ -161,6 +174,20 @@ to see how to use outputs.

Total number of changes

### `breaking-changes`

List of breaking changes. Each item is message string.

Example: ```["Type `Abc` was removed", "Field `Xyz` was removed from object type `Abc`"]```

### `dangerous-changes`

List of dangerous changes. Each item is message string, see `breaking-changes` for example.

### `safe-changes`

List of safe changes. Each item is message string, see `breaking-changes` for example.

![Summary](/assets/img/github/summary.jpg)

![Annotations](/assets/img/cli/github.jpg)