diff --git a/dist/index.js b/dist/index.js index 8e07d39..c9375e3 100644 --- a/dist/index.js +++ b/dist/index.js @@ -19747,7 +19747,7 @@ var require_core = __commonJS({ return inputs.map((input) => input.trim()); } exports2.getMultilineInput = getMultilineInput; - function getBooleanInput(name, options) { + function getBooleanInput2(name, options) { const trueValue = ["true", "True", "TRUE"]; const falseValue = ["false", "False", "FALSE"]; const val = getInput2(name, options); @@ -19758,7 +19758,7 @@ var require_core = __commonJS({ throw new TypeError(`Input does not meet YAML 1.2 "Core Schema" specification: ${name} Support boolean input list: \`true | True | TRUE | false | False | FALSE\``); } - exports2.getBooleanInput = getBooleanInput; + exports2.getBooleanInput = getBooleanInput2; function setOutput2(name, value) { const filePath = process.env["GITHUB_OUTPUT"] || ""; if (filePath) { @@ -26539,10 +26539,11 @@ var require_semver2 = __commonJS({ }); // src/index.ts -var core = __toESM(require_core()); +var core2 = __toESM(require_core()); var github2 = __toESM(require_github()); // src/comment.ts +var core = __toESM(require_core()); var github = __toESM(require_github()); // src/render.ts @@ -30627,11 +30628,15 @@ function renderBody(plan) { } return body; } -function renderComment({ - body, +function renderMarkdown({ + plan, header, includeFooter }) { + core.debug(`plan: ${JSON.stringify(plan, null, 2)}`); + core.debug(`header: ${header}`); + const body = renderBody(plan); + core.debug(`body: ${body}`); let footer = ""; if (includeFooter === void 0 || includeFooter === true) { footer = ` @@ -30640,6 +30645,7 @@ function renderComment({ _Triggered by @${github.context.actor}, Commit: \`${github.context.payload.pull_request.head.sha}\`_`; } + core.debug(`footer: ${footer}`); return `## ${header} ${body}${footer}`; @@ -30676,15 +30682,16 @@ async function createOrUpdateComment({ // src/index.ts async function run() { const inputs = { - token: core.getInput("token", { required: true }), - planfile: core.getInput("planfile", { required: true }), - terraformCmd: core.getInput("terraform-cmd", { required: true }), - workingDirectory: core.getInput("working-directory", { required: true }), - header: core.getInput("header", { required: true }), - shouldComment: core.getInput("comment", { required: false }) + token: core2.getInput("token", { required: true }), + planfile: core2.getInput("planfile", { required: true }), + terraformCmd: core2.getInput("terraform-cmd", { required: true }), + workingDirectory: core2.getInput("working-directory", { required: true }), + header: core2.getInput("header", { required: true }), + skipEmpty: core2.getBooleanInput("skip-empty", { required: true }), + shouldComment: core2.getInput("should-comment", { required: false }) }; const octokit = github2.getOctokit(inputs.token); - const plan = await core.group( + const plan = await core2.group( "Render plan", () => renderPlan({ planfile: inputs.planfile, @@ -30692,16 +30699,19 @@ async function run() { workingDirectory: inputs.workingDirectory }) ); - const planMarkdown = await core.group("Rendering plan diff markdown", () => { - const markdown = renderBody(plan); - core.debug(`Outputting plan as markdown: ${markdown}`); - core.setOutput("plan-markdown", markdown); - return Promise.resolve(markdown); - }); - if (inputs.shouldComment === "true") { - await core.group("Render comment", () => { - const comment = renderComment({ body: planMarkdown, header: inputs.header }); - return createOrUpdateComment({ octokit, content: comment }); + if (!inputs.skipEmpty || !planIsEmpty(plan)) { + const planMarkdown = await core2.group("Render plan diff markdown", () => { + const markdown = renderMarkdown({ plan, header: inputs.header }); + core2.setOutput("plan-markdown", markdown); + return Promise.resolve(markdown); + }); + if (inputs.shouldComment === "true") { + await core2.group("Render comment", () => { + return createOrUpdateComment({ octokit, content: planMarkdown }); + }); + } + await core2.group("Adding plan to step summary", async () => { + await core2.summary.addRaw(planMarkdown).write(); }); } } @@ -30710,7 +30720,7 @@ async function main() { await run(); } catch (error) { if (error instanceof Error) { - core.setFailed(error.message); + core2.setFailed(error.message); } } } diff --git a/src/comment.ts b/src/comment.ts index 7a8f97d..90f30ad 100644 --- a/src/comment.ts +++ b/src/comment.ts @@ -1,3 +1,4 @@ +import * as core from '@actions/core' import type { GitHub } from '@actions/github/lib/utils' import * as github from '@actions/github' import type { PullRequestEvent } from '@octokit/webhooks-types' @@ -12,7 +13,7 @@ function renderResources(resources: Record): string { return result } -export function renderBody(plan: RenderedPlan): string { +function renderBody(plan: RenderedPlan): string { if (planIsEmpty(plan)) { return '**→ No Resource Changes!**' } @@ -44,15 +45,24 @@ export function renderBody(plan: RenderedPlan): string { return body } -export function renderComment({ - body, +export function renderMarkdown({ + plan, header, includeFooter }: { - body: string + plan: RenderedPlan header: string includeFooter?: boolean }): string { + core.debug(`plan: ${JSON.stringify(plan, null, 2)}`) + core.debug(`header: ${header}`) + + // Build body + const body = renderBody(plan) + + core.debug(`body: ${body}`) + + // Build footer let footer = '' if (includeFooter === undefined || includeFooter === true) { footer = @@ -60,6 +70,8 @@ export function renderComment({ ` Commit: \`${(github.context.payload as PullRequestEvent).pull_request.head.sha}\`_` } + core.debug(`footer: ${footer}`) + return `## ${header}\n\n${body}${footer}` } diff --git a/src/index.ts b/src/index.ts index 45048ea..0a6b382 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,7 @@ import * as core from '@actions/core' import * as github from '@actions/github' -import { createOrUpdateComment, renderBody, renderComment } from './comment' -import { renderPlan } from './render' +import { createOrUpdateComment, renderMarkdown } from './comment' +import { planIsEmpty, renderPlan } from './render' async function run() { // 1) Setup @@ -11,6 +11,7 @@ async function run() { terraformCmd: core.getInput('terraform-cmd', { required: true }), workingDirectory: core.getInput('working-directory', { required: true }), header: core.getInput('header', { required: true }), + skipEmpty: core.getBooleanInput('skip-empty', { required: true }), shouldComment: core.getInput('should-comment', { required: false }) } const octokit = github.getOctokit(inputs.token) @@ -24,19 +25,23 @@ async function run() { }) ) - // 3) Render the plan diff markdown and set it as output - const planMarkdown = await core.group('Rendering plan diff markdown', () => { - const markdown = renderBody(plan) - core.debug(`Outputting plan as markdown: ${markdown}`) - core.setOutput('plan-markdown', markdown) - return Promise.resolve(markdown) - }) + if (!inputs.skipEmpty || !planIsEmpty(plan)) { + // 3) Render the plan diff markdown and set it as output + const planMarkdown = await core.group('Render plan diff markdown', () => { + const markdown = renderMarkdown({ plan, header: inputs.header }) + core.setOutput('plan-markdown', markdown) + return Promise.resolve(markdown) + }) + // 4) Post comment with markdown (if applicable) + if (inputs.shouldComment === 'true') { + await core.group('Render comment', () => { + return createOrUpdateComment({ octokit, content: planMarkdown }) + }) + } - // 4) Post comment with markdown (if applicable) - if (inputs.shouldComment === 'true') { - await core.group('Render comment', () => { - const comment = renderComment({ body: planMarkdown, header: inputs.header }) - return createOrUpdateComment({ octokit, content: comment }) + // 5) Add plan to GitHub step summary + await core.group('Adding plan to step summary', async () => { + await core.summary.addRaw(planMarkdown).write() }) } } diff --git a/tests/e2e.test.ts b/tests/e2e.test.ts index b129ca3..b85996b 100644 --- a/tests/e2e.test.ts +++ b/tests/e2e.test.ts @@ -1,7 +1,7 @@ import * as fs from 'fs' import { internalRenderPlan } from '../src/render' import { parsePlanfileJSON } from '../src/planfile' -import { renderBody, renderComment } from '../src/comment' +import { renderMarkdown } from '../src/comment' test.each(['basic/0-create', 'basic/1-modify', 'basic/2-delete', 'basic/3-empty'])( 'parse-successful', @@ -10,18 +10,17 @@ test.each(['basic/0-create', 'basic/1-modify', 'basic/2-delete', 'basic/3-empty' const planTxt = fs.readFileSync(`tests/fixtures/${arg}/plan.txt`, 'utf-8') const planfile = parsePlanfileJSON(planJson) const renderedPlan = internalRenderPlan(planfile, planTxt) - const renderedMarkdown = renderBody(renderedPlan) - const renderedComment = renderComment({ - body: renderedMarkdown, + const renderedMarkdown = renderMarkdown({ + plan: renderedPlan, header: '📝 Terraform Plan', includeFooter: false }) if (process.env.GENERATE_FIXTURE === '1') { - fs.writeFileSync(`tests/fixtures/${arg}/rendered.md`, renderedComment) + fs.writeFileSync(`tests/fixtures/${arg}/rendered.md`, renderedMarkdown) } else { const expected = fs.readFileSync(`tests/fixtures/${arg}/rendered.md`, 'utf-8') - expect(renderedComment).toBe(expected) + expect(renderedMarkdown).toBe(expected) } } )