diff --git a/src/action.ts b/src/action.ts index 1eca669..bf81367 100644 --- a/src/action.ts +++ b/src/action.ts @@ -4,9 +4,10 @@ import fm from 'front-matter' import nunjucks from 'nunjucks' // @ts-ignore import dateFilter from 'nunjucks-date-filter' +import { ZodError } from 'zod' import { FrontMatterAttributes, frontmatterSchema, listToArray, setOutputs } from './helpers' -function logError(tools: Toolkit, template: string, action: 'creating' | 'updating', err: any) { +function logError(tools: Toolkit, template: string, action: 'creating' | 'updating' | 'parsing', err: any) { // Log the error message const errorMessage = `An error occurred while ${action} the issue. This might be caused by a malformed issue title, or a typo in the labels or assignees. Check ${template}!` tools.log.error(errorMessage) @@ -51,7 +52,18 @@ export async function createAnIssue (tools: Toolkit) { // Grab the front matter as JSON const { attributes: rawAttributes, body } = fm(file) - const attributes = await frontmatterSchema.parseAsync(rawAttributes) + + let attributes: FrontMatterAttributes + try { + attributes = await frontmatterSchema.parseAsync(rawAttributes) + } catch (err) { + if (err instanceof ZodError) { + const formatted = err.format() + return logError(tools, template, 'parsing', formatted) + } + throw err + } + tools.log(`Front matter for ${template} is`, attributes) const templated = { diff --git a/src/helpers.ts b/src/helpers.ts index e3a9b96..a2e2e80 100644 --- a/src/helpers.ts +++ b/src/helpers.ts @@ -6,7 +6,7 @@ export const frontmatterSchema = z.object({ assignees: z.union([z.array(z.string()), z.string()]).optional(), labels: z.union([z.array(z.string()), z.string()]).optional(), milestone: z.union([z.string(), z.number()]).optional() -}) +}).strict() export type FrontMatterAttributes = z.infer diff --git a/tests/__snapshots__/index.test.ts.snap b/tests/__snapshots__/index.test.ts.snap index 5172e45..7340d64 100644 --- a/tests/__snapshots__/index.test.ts.snap +++ b/tests/__snapshots__/index.test.ts.snap @@ -232,6 +232,32 @@ exports[`create-an-issue logs a helpful error if creating an issue throws an err ] `; +exports[`create-an-issue logs a helpful error if the frontmatter is invalid 1`] = ` +[ + [ + "An error occurred while parsing the issue. This might be caused by a malformed issue title, or a typo in the labels or assignees. Check .github/invalid-frontmatter.md!", + ], + [ + { + "_errors": [ + "Unrecognized key(s) in object: 'name', 'not_a_thing'", + ], + "labels": { + "_errors": [ + "Expected array, received number", + "Expected string, received number", + ], + }, + "title": { + "_errors": [ + "Required", + ], + }, + }, + ], +] +`; + exports[`create-an-issue logs a helpful error if updating an issue throws an error with more errors 1`] = ` [ [ diff --git a/tests/fixtures/.github/invalid-frontmatter.md b/tests/fixtures/.github/invalid-frontmatter.md new file mode 100644 index 0000000..ab948e6 --- /dev/null +++ b/tests/fixtures/.github/invalid-frontmatter.md @@ -0,0 +1,6 @@ +--- +name: "Not a title" +labels: 123 +not_a_thing: "testing" +--- +Hi! \ No newline at end of file diff --git a/tests/index.test.ts b/tests/index.test.ts index 2e95f2a..a254823 100644 --- a/tests/index.test.ts +++ b/tests/index.test.ts @@ -302,4 +302,13 @@ describe('create-an-issue', () => { expect((tools.log.error as any).mock.calls).toMatchSnapshot() expect(tools.exit.failure).toHaveBeenCalled() }) + + it('logs a helpful error if the frontmatter is invalid', async () => { + process.env.INPUT_FILENAME = '.github/invalid-frontmatter.md' + + await createAnIssue(tools) + expect(tools.log.error).toHaveBeenCalled() + expect((tools.log.error as any).mock.calls).toMatchSnapshot() + expect(tools.exit.failure).toHaveBeenCalled() + }) })