Skip to content

Commit

Permalink
feat: Add Verbose option to reduce noise in output. (#883)
Browse files Browse the repository at this point in the history
* refactor: Move ActionParams to its own file
* feat: Add Verbose Option
  • Loading branch information
Jason3S authored Aug 14, 2022
1 parent 0ae1614 commit 6abfb1f
Show file tree
Hide file tree
Showing 19 changed files with 460 additions and 253 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ jobs:

# Path to `cspell.json`
config: '.'

# Log progress and other information during the action execution.
verbose: false
```
## Yarn 2 - PlugNPlay
Expand Down
1 change: 1 addition & 0 deletions action-src/cspell.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"ignorePaths": [
"**/coverage/**",
"node_modules",
"__recordings__",
"__snapshots__"
Expand Down
14 changes: 14 additions & 0 deletions action-src/fixtures/bad_params/bad_incremental_files_only.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"INPUT_GITHUB_TOKEN": "$GITHUB_TOKEN",
"INPUT_INCREMENTAL_FILES_ONLY": "yes please",
"GITHUB_EVENT_PATH": "./fixtures/push_payload.json",
"GITHUB_EVENT_NAME": "push",
"GITHUB_SHA": "a16b47a16f6c11b63cfdcf510c15ba26edd0f3d1",
"GITHUB_REF": "refs/heads/fix-resolve-path",
"GITHUB_WORKFLOW": "test-action",
"GITHUB_ACTION": "self",
"GITHUB_ACTOR": "Jason3S",
"GITHUB_JOB": "test-action",
"GITHUB_RUN_NUMBER": "7",
"GITHUB_RUN_ID": "425984531"
}
14 changes: 14 additions & 0 deletions action-src/fixtures/bad_params/bad_unsupported_event.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"INPUT_GITHUB_TOKEN": "$GITHUB_TOKEN",
"INPUT_INCREMENTAL_FILES_ONLY": "true",
"GITHUB_EVENT_PATH": "./fixtures/push_payload.json",
"GITHUB_EVENT_NAME": "fork",
"GITHUB_SHA": "a16b47a16f6c11b63cfdcf510c15ba26edd0f3d1",
"GITHUB_REF": "refs/heads/fix-resolve-path",
"GITHUB_WORKFLOW": "test-action",
"GITHUB_ACTION": "self",
"GITHUB_ACTOR": "Jason3S",
"GITHUB_JOB": "test-action",
"GITHUB_RUN_NUMBER": "7",
"GITHUB_RUN_ID": "425984531"
}
38 changes: 38 additions & 0 deletions action-src/src/ActionParams.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { ActionParamsInput, applyDefaults, validateActionParams, __testing__ } from './ActionParams';

describe('ActionParams', () => {
test.each`
params | expected
${{}} | ${__testing__.defaultActionParams}
${{ strict: 'false' }} | ${{ ...__testing__.defaultActionParams, strict: 'false' }}
`('applyDefaults $params', ({ params, expected }) => {
expect(applyDefaults(params)).toEqual(expected);
});

test.each`
params | expected
${{ github_token: '' }} | ${'Missing GITHUB Token'}
${{ incremental_files_only: 'sure' }} | ${'Invalid incremental_files_only setting, must be one of (true, false)'}
${{ config: 'config_not_found' }} | ${'Configuration file "config_not_found" not found.'}
${{ root: 'root_not_found' }} | ${'Root path does not exist: "root_not_found"'}
${{ inline: 'swizzle' }} | ${'Invalid inline level (swizzle), must be one of (error, warning, none)'}
${{ strict: 'sure' }} | ${'Invalid strict setting, must be one of (true, false)'}
`('validateActionParams Errors $params', ({ params, expected }) => {
const logger = jest.fn();
expect(() => validateActionParams(ap(params), logger)).toThrow();
expect(logger).toHaveBeenCalledWith(expected);
});

test.each`
params
${{ github_token: 'token' }}
`('validateActionParams $params', ({ params }) => {
const logger = jest.fn();
expect(() => validateActionParams(ap(params), logger)).not.toThrow();
expect(logger).not.toHaveBeenCalled();
});
});

function ap(p: Partial<ActionParamsInput>): ActionParamsInput {
return { ...__testing__.defaultActionParams, github_token: 'token', ...p };
}
128 changes: 128 additions & 0 deletions action-src/src/ActionParams.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import { existsSync } from 'fs';
import { AppError } from './error';

/**
* [Workflow commands for GitHub Actions - GitHub Docs](https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-commands-for-github-actions#setting-an-output-parameter)
*/
type InlineWorkflowCommand = 'error' | 'warning' | 'none';

export type TrueFalse = 'true' | 'false';

export interface ActionParamsInput extends Record<keyof ActionParams, string> {}

export interface ActionParams {
github_token: string;
files: string;
incremental_files_only: TrueFalse;
config: string;
root: string;
inline: InlineWorkflowCommand;
/**
* Determines if the action should be failed if any spelling issues are found.
*
* Allowed values are: true, false
*/
strict: TrueFalse;
/**
* Increases the amount of information logged during the action.
* true - show progress
* false - less information
*/
verbose: TrueFalse;
}

const defaultActionParams: ActionParams = {
github_token: '',
files: '',
incremental_files_only: 'true',
config: '',
root: '',
inline: 'warning',
strict: 'true',
verbose: 'false',
};

type ValidationFunction = (params: ActionParamsInput) => string | undefined;

export function applyDefaults(params: ActionParamsInput): ActionParamsInput {
const results = { ...params };
const alias = results as Record<string, string>;
for (const [key, value] of Object.entries(defaultActionParams)) {
alias[key] = alias[key] || value;
}
return results;
}

function validateToken(params: ActionParamsInput) {
const token = params.github_token;
return !token ? 'Missing GITHUB Token' : undefined;
}

function validateConfig(params: ActionParamsInput) {
const config = params.config;
const success = !config || existsSync(config);
return !success ? `Configuration file "${config}" not found.` : undefined;
}

function validateRoot(params: ActionParamsInput) {
const root = params.root;
const success = !root || existsSync(root);
return !success ? `Root path does not exist: "${root}"` : undefined;
}

function validateInlineLevel(params: ActionParamsInput) {
const inline = params.inline;
const success = isInlineWorkflowCommand(inline);
return !success ? `Invalid inline level (${inline}), must be one of (error, warning, none)` : undefined;
}

const validateStrict = validateTrueFalse('strict', 'Invalid strict setting, must be one of (true, false)');
const validateIncrementalFilesOnly = validateTrueFalse(
'incremental_files_only',
'Invalid incremental_files_only setting, must be one of (true, false)'
);
const validateVerbose = validateTrueFalse('verbose', 'Invalid verbose setting, must be one of (true, false)');

function validateTrueFalse(key: keyof ActionParamsInput, msg: string): ValidationFunction {
return (params: ActionParamsInput) => {
const value = params[key];
const success = value === 'true' || value === 'false';
return !success ? msg : undefined;
};
}

const inlineWorkflowCommandSet: Record<InlineWorkflowCommand | string, boolean | undefined> = {
error: true,
warning: true,
none: true,
};

function isInlineWorkflowCommand(cmd: InlineWorkflowCommand | string): cmd is InlineWorkflowCommand {
return !!inlineWorkflowCommandSet[cmd];
}

export function validateActionParams(
params: ActionParamsInput | ActionParams,
logError: (msg: string) => void
): asserts params is ActionParams {
const validations: ValidationFunction[] = [
validateToken,
validateConfig,
validateRoot,
validateInlineLevel,
validateStrict,
validateIncrementalFilesOnly,
validateVerbose,
];
const success = validations
.map((fn) => fn(params))
.map((msg) => !msg || (logError(msg), false))
.reduce((a, b) => a && b, true);
if (!success) {
throw new AppError('Bad Configuration.');
}
}

export const __testing__ = {
defaultActionParams,
};
12 changes: 7 additions & 5 deletions action-src/src/action.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,13 @@ describe('Validate Action', () => {
});

test.each`
test | file | expected
${'bad root'} | ${'bad_params/bad_root.json'} | ${new AppError('Bad Configuration.')}
${'missing config'} | ${'bad_params/missing_config.json'} | ${new AppError('Bad Configuration.')}
${'bad inline'} | ${'bad_params/bad_inline.json'} | ${new AppError('Bad Configuration.')}
${'bad strict'} | ${'bad_params/bad_strict.json'} | ${new AppError('Bad Configuration.')}
test | file | expected
${'bad root'} | ${'bad_params/bad_root.json'} | ${new AppError('Bad Configuration.')}
${'missing config'} | ${'bad_params/missing_config.json'} | ${new AppError('Bad Configuration.')}
${'bad inline'} | ${'bad_params/bad_inline.json'} | ${new AppError('Bad Configuration.')}
${'bad_incremental_files_only'} | ${'bad_params/bad_incremental_files_only.json'} | ${new AppError('Bad Configuration.')}
${'bad_unsupported_event'} | ${'bad_params/bad_unsupported_event.json'} | ${new AppError("Unsupported event: 'fork'")}
${'bad strict'} | ${'bad_params/bad_strict.json'} | ${new AppError('Bad Configuration.')}
`(
'$test',
async ({ file, expected }) => {
Expand Down
Loading

0 comments on commit 6abfb1f

Please sign in to comment.