diff --git a/packages/core/__tests__/markdown-summary.test.ts b/packages/core/__tests__/summary.test.ts similarity index 76% rename from packages/core/__tests__/markdown-summary.test.ts rename to packages/core/__tests__/summary.test.ts index d9b8ee5c..c13b0179 100644 --- a/packages/core/__tests__/markdown-summary.test.ts +++ b/packages/core/__tests__/summary.test.ts @@ -1,9 +1,10 @@ import * as fs from 'fs' import * as os from 'os' import path from 'path' -import {markdownSummary, SUMMARY_ENV_VAR} from '../src/markdown-summary' +import {summary, SUMMARY_ENV_VAR} from '../src/summary' -const testFilePath = path.join(__dirname, 'test', 'test-summary.md') +const testDirectoryPath = path.join(__dirname, 'test') +const testFilePath = path.join(testDirectoryPath, 'test-summary.md') async function assertSummary(expected: string): Promise { const file = await fs.promises.readFile(testFilePath, {encoding: 'utf8'}) @@ -67,11 +68,12 @@ const fixtures = { } } -describe('@actions/core/src/markdown-summary', () => { +describe('@actions/core/src/summary', () => { beforeEach(async () => { process.env[SUMMARY_ENV_VAR] = testFilePath + await fs.promises.mkdir(testDirectoryPath, {recursive: true}) await fs.promises.writeFile(testFilePath, '', {encoding: 'utf8'}) - markdownSummary.emptyBuffer() + summary.emptyBuffer() }) afterAll(async () => { @@ -80,39 +82,39 @@ describe('@actions/core/src/markdown-summary', () => { it('throws if summary env var is undefined', async () => { process.env[SUMMARY_ENV_VAR] = undefined - const write = markdownSummary.addRaw(fixtures.text).write() + const write = summary.addRaw(fixtures.text).write() await expect(write).rejects.toThrow() }) it('throws if summary file does not exist', async () => { await fs.promises.unlink(testFilePath) - const write = markdownSummary.addRaw(fixtures.text).write() + const write = summary.addRaw(fixtures.text).write() await expect(write).rejects.toThrow() }) it('appends text to summary file', async () => { await fs.promises.writeFile(testFilePath, '# ', {encoding: 'utf8'}) - await markdownSummary.addRaw(fixtures.text).write() + await summary.addRaw(fixtures.text).write() await assertSummary(`# ${fixtures.text}`) }) it('overwrites text to summary file', async () => { await fs.promises.writeFile(testFilePath, 'overwrite', {encoding: 'utf8'}) - await markdownSummary.addRaw(fixtures.text).write({overwrite: true}) + await summary.addRaw(fixtures.text).write({overwrite: true}) await assertSummary(fixtures.text) }) it('appends text with EOL to summary file', async () => { await fs.promises.writeFile(testFilePath, '# ', {encoding: 'utf8'}) - await markdownSummary.addRaw(fixtures.text, true).write() + await summary.addRaw(fixtures.text, true).write() await assertSummary(`# ${fixtures.text}${os.EOL}`) }) it('chains appends text to summary file', async () => { await fs.promises.writeFile(testFilePath, '', {encoding: 'utf8'}) - await markdownSummary + await summary .addRaw(fixtures.text) .addRaw(fixtures.text) .addRaw(fixtures.text) @@ -122,33 +124,33 @@ describe('@actions/core/src/markdown-summary', () => { it('empties buffer after write', async () => { await fs.promises.writeFile(testFilePath, '', {encoding: 'utf8'}) - await markdownSummary.addRaw(fixtures.text).write() + await summary.addRaw(fixtures.text).write() await assertSummary(fixtures.text) - expect(markdownSummary.isEmptyBuffer()).toBe(true) + expect(summary.isEmptyBuffer()).toBe(true) }) it('returns summary buffer as string', () => { - markdownSummary.addRaw(fixtures.text) - expect(markdownSummary.stringify()).toEqual(fixtures.text) + summary.addRaw(fixtures.text) + expect(summary.stringify()).toEqual(fixtures.text) }) it('return correct values for isEmptyBuffer', () => { - markdownSummary.addRaw(fixtures.text) - expect(markdownSummary.isEmptyBuffer()).toBe(false) + summary.addRaw(fixtures.text) + expect(summary.isEmptyBuffer()).toBe(false) - markdownSummary.emptyBuffer() - expect(markdownSummary.isEmptyBuffer()).toBe(true) + summary.emptyBuffer() + expect(summary.isEmptyBuffer()).toBe(true) }) it('clears a buffer and summary file', async () => { await fs.promises.writeFile(testFilePath, 'content', {encoding: 'utf8'}) - await markdownSummary.clear() + await summary.clear() await assertSummary('') - expect(markdownSummary.isEmptyBuffer()).toBe(true) + expect(summary.isEmptyBuffer()).toBe(true) }) it('adds EOL', async () => { - await markdownSummary + await summary .addRaw(fixtures.text) .addEOL() .write() @@ -156,37 +158,37 @@ describe('@actions/core/src/markdown-summary', () => { }) it('adds a code block without language', async () => { - await markdownSummary.addCodeBlock(fixtures.code).write() + await summary.addCodeBlock(fixtures.code).write() const expected = `
func fork() {\n  for {\n    go fork()\n  }\n}
${os.EOL}` await assertSummary(expected) }) it('adds a code block with a language', async () => { - await markdownSummary.addCodeBlock(fixtures.code, 'go').write() + await summary.addCodeBlock(fixtures.code, 'go').write() const expected = `
func fork() {\n  for {\n    go fork()\n  }\n}
${os.EOL}` await assertSummary(expected) }) it('adds an unordered list', async () => { - await markdownSummary.addList(fixtures.list).write() + await summary.addList(fixtures.list).write() const expected = `${os.EOL}` await assertSummary(expected) }) it('adds an ordered list', async () => { - await markdownSummary.addList(fixtures.list, true).write() + await summary.addList(fixtures.list, true).write() const expected = `
  1. foo
  2. bar
  3. baz
  4. 💣
${os.EOL}` await assertSummary(expected) }) it('adds a table', async () => { - await markdownSummary.addTable(fixtures.table).write() + await summary.addTable(fixtures.table).write() const expected = `
foobarbaztall
onetwothree
wide
${os.EOL}` await assertSummary(expected) }) it('adds a details element', async () => { - await markdownSummary + await summary .addDetails(fixtures.details.label, fixtures.details.content) .write() const expected = `
open me🎉 surprise
${os.EOL}` @@ -194,13 +196,13 @@ describe('@actions/core/src/markdown-summary', () => { }) it('adds an image with alt text', async () => { - await markdownSummary.addImage(fixtures.img.src, fixtures.img.alt).write() + await summary.addImage(fixtures.img.src, fixtures.img.alt).write() const expected = `actions logo${os.EOL}` await assertSummary(expected) }) it('adds an image with custom dimensions', async () => { - await markdownSummary + await summary .addImage(fixtures.img.src, fixtures.img.alt, fixtures.img.options) .write() const expected = `actions logo${os.EOL}` @@ -208,7 +210,7 @@ describe('@actions/core/src/markdown-summary', () => { }) it('adds an image with custom dimensions', async () => { - await markdownSummary + await summary .addImage(fixtures.img.src, fixtures.img.alt, fixtures.img.options) .write() const expected = `actions logo${os.EOL}` @@ -217,21 +219,21 @@ describe('@actions/core/src/markdown-summary', () => { it('adds headings h1...h6', async () => { for (const i of [1, 2, 3, 4, 5, 6]) { - markdownSummary.addHeading('heading', i) + summary.addHeading('heading', i) } - await markdownSummary.write() + await summary.write() const expected = `

heading

${os.EOL}

heading

${os.EOL}

heading

${os.EOL}

heading

${os.EOL}
heading
${os.EOL}
heading
${os.EOL}` await assertSummary(expected) }) it('adds h1 if heading level not specified', async () => { - await markdownSummary.addHeading('heading').write() + await summary.addHeading('heading').write() const expected = `

heading

${os.EOL}` await assertSummary(expected) }) it('uses h1 if heading level is garbage or out of range', async () => { - await markdownSummary + await summary .addHeading('heading', 'foobar') .addHeading('heading', 1337) .addHeading('heading', -1) @@ -242,35 +244,31 @@ describe('@actions/core/src/markdown-summary', () => { }) it('adds a separator', async () => { - await markdownSummary.addSeparator().write() + await summary.addSeparator().write() const expected = `
${os.EOL}` await assertSummary(expected) }) it('adds a break', async () => { - await markdownSummary.addBreak().write() + await summary.addBreak().write() const expected = `
${os.EOL}` await assertSummary(expected) }) it('adds a quote', async () => { - await markdownSummary.addQuote(fixtures.quote.text).write() + await summary.addQuote(fixtures.quote.text).write() const expected = `
Where the world builds software
${os.EOL}` await assertSummary(expected) }) it('adds a quote with citation', async () => { - await markdownSummary - .addQuote(fixtures.quote.text, fixtures.quote.cite) - .write() + await summary.addQuote(fixtures.quote.text, fixtures.quote.cite).write() const expected = `
Where the world builds software
${os.EOL}` await assertSummary(expected) }) it('adds a link with href', async () => { - await markdownSummary - .addLink(fixtures.link.text, fixtures.link.href) - .write() + await summary.addLink(fixtures.link.text, fixtures.link.href).write() const expected = `GitHub${os.EOL}` await assertSummary(expected) }) diff --git a/packages/core/src/core.ts b/packages/core/src/core.ts index 8a9170ca..97073839 100644 --- a/packages/core/src/core.ts +++ b/packages/core/src/core.ts @@ -361,6 +361,6 @@ export async function getIDToken(aud?: string): Promise { } /** - * Markdown summary exports + * Summary exports */ -export {markdownSummary} from './markdown-summary' +export {summary} from './summary' diff --git a/packages/core/src/markdown-summary.ts b/packages/core/src/summary.ts similarity index 80% rename from packages/core/src/markdown-summary.ts rename to packages/core/src/summary.ts index 97d2d3ca..41db1de1 100644 --- a/packages/core/src/markdown-summary.ts +++ b/packages/core/src/summary.ts @@ -4,7 +4,7 @@ const {access, appendFile, writeFile} = promises export const SUMMARY_ENV_VAR = 'GITHUB_STEP_SUMMARY' export const SUMMARY_DOCS_URL = - 'https://docs.github.com/actions/using-workflows/workflow-commands-for-github-actions#adding-a-markdown-summary' + 'https://docs.github.com/actions/using-workflows/workflow-commands-for-github-actions#adding-a-job-summary' export type SummaryTableRow = (SummaryTableCell | string)[] @@ -51,7 +51,7 @@ export interface SummaryWriteOptions { overwrite?: boolean } -class MarkdownSummary { +class Summary { private _buffer: string private _filePath?: string @@ -73,7 +73,7 @@ class MarkdownSummary { const pathFromEnv = process.env[SUMMARY_ENV_VAR] if (!pathFromEnv) { throw new Error( - `Unable to find environment variable for $${SUMMARY_ENV_VAR}. Check if your runtime environment supports markdown summaries.` + `Unable to find environment variable for $${SUMMARY_ENV_VAR}. Check if your runtime environment supports job summaries.` ) } @@ -119,9 +119,9 @@ class MarkdownSummary { * * @param {SummaryWriteOptions} [options] (optional) options for write operation * - * @returns {Promise} markdown summary instance + * @returns {Promise} summary instance */ - async write(options?: SummaryWriteOptions): Promise { + async write(options?: SummaryWriteOptions): Promise { const overwrite = !!options?.overwrite const filePath = await this.filePath() const writeFunc = overwrite ? writeFile : appendFile @@ -132,9 +132,9 @@ class MarkdownSummary { /** * Clears the summary buffer and wipes the summary file * - * @returns {MarkdownSummary} markdown summary instance + * @returns {Summary} summary instance */ - async clear(): Promise { + async clear(): Promise { return this.emptyBuffer().write({overwrite: true}) } @@ -159,9 +159,9 @@ class MarkdownSummary { /** * Resets the summary buffer without writing to summary file * - * @returns {MarkdownSummary} markdown summary instance + * @returns {Summary} summary instance */ - emptyBuffer(): MarkdownSummary { + emptyBuffer(): Summary { this._buffer = '' return this } @@ -172,9 +172,9 @@ class MarkdownSummary { * @param {string} text content to add * @param {boolean} [addEOL=false] (optional) append an EOL to the raw text (default: false) * - * @returns {MarkdownSummary} markdown summary instance + * @returns {Summary} summary instance */ - addRaw(text: string, addEOL = false): MarkdownSummary { + addRaw(text: string, addEOL = false): Summary { this._buffer += text return addEOL ? this.addEOL() : this } @@ -182,9 +182,9 @@ class MarkdownSummary { /** * Adds the operating system-specific end-of-line marker to the buffer * - * @returns {MarkdownSummary} markdown summary instance + * @returns {Summary} summary instance */ - addEOL(): MarkdownSummary { + addEOL(): Summary { return this.addRaw(EOL) } @@ -194,9 +194,9 @@ class MarkdownSummary { * @param {string} code content to render within fenced code block * @param {string} lang (optional) language to syntax highlight code * - * @returns {MarkdownSummary} markdown summary instance + * @returns {Summary} summary instance */ - addCodeBlock(code: string, lang?: string): MarkdownSummary { + addCodeBlock(code: string, lang?: string): Summary { const attrs = { ...(lang && {lang}) } @@ -210,9 +210,9 @@ class MarkdownSummary { * @param {string[]} items list of items to render * @param {boolean} [ordered=false] (optional) if the rendered list should be ordered or not (default: false) * - * @returns {MarkdownSummary} markdown summary instance + * @returns {Summary} summary instance */ - addList(items: string[], ordered = false): MarkdownSummary { + addList(items: string[], ordered = false): Summary { const tag = ordered ? 'ol' : 'ul' const listItems = items.map(item => this.wrap('li', item)).join('') const element = this.wrap(tag, listItems) @@ -224,9 +224,9 @@ class MarkdownSummary { * * @param {SummaryTableCell[]} rows table rows * - * @returns {MarkdownSummary} markdown summary instance + * @returns {Summary} summary instance */ - addTable(rows: SummaryTableRow[]): MarkdownSummary { + addTable(rows: SummaryTableRow[]): Summary { const tableBody = rows .map(row => { const cells = row @@ -260,9 +260,9 @@ class MarkdownSummary { * @param {string} label text for the closed state * @param {string} content collapsable content * - * @returns {MarkdownSummary} markdown summary instance + * @returns {Summary} summary instance */ - addDetails(label: string, content: string): MarkdownSummary { + addDetails(label: string, content: string): Summary { const element = this.wrap('details', this.wrap('summary', label) + content) return this.addRaw(element).addEOL() } @@ -274,13 +274,9 @@ class MarkdownSummary { * @param {string} alt text description of the image * @param {SummaryImageOptions} options (optional) addition image attributes * - * @returns {MarkdownSummary} markdown summary instance + * @returns {Summary} summary instance */ - addImage( - src: string, - alt: string, - options?: SummaryImageOptions - ): MarkdownSummary { + addImage(src: string, alt: string, options?: SummaryImageOptions): Summary { const {width, height} = options || {} const attrs = { ...(width && {width}), @@ -297,9 +293,9 @@ class MarkdownSummary { * @param {string} text heading text * @param {number | string} [level=1] (optional) the heading level, default: 1 * - * @returns {MarkdownSummary} markdown summary instance + * @returns {Summary} summary instance */ - addHeading(text: string, level?: number | string): MarkdownSummary { + addHeading(text: string, level?: number | string): Summary { const tag = `h${level}` const allowedTag = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'].includes(tag) ? tag @@ -311,9 +307,9 @@ class MarkdownSummary { /** * Adds an HTML thematic break (
) to the summary buffer * - * @returns {MarkdownSummary} markdown summary instance + * @returns {Summary} summary instance */ - addSeparator(): MarkdownSummary { + addSeparator(): Summary { const element = this.wrap('hr', null) return this.addRaw(element).addEOL() } @@ -321,9 +317,9 @@ class MarkdownSummary { /** * Adds an HTML line break (
) to the summary buffer * - * @returns {MarkdownSummary} markdown summary instance + * @returns {Summary} summary instance */ - addBreak(): MarkdownSummary { + addBreak(): Summary { const element = this.wrap('br', null) return this.addRaw(element).addEOL() } @@ -334,9 +330,9 @@ class MarkdownSummary { * @param {string} text quote text * @param {string} cite (optional) citation url * - * @returns {MarkdownSummary} markdown summary instance + * @returns {Summary} summary instance */ - addQuote(text: string, cite?: string): MarkdownSummary { + addQuote(text: string, cite?: string): Summary { const attrs = { ...(cite && {cite}) } @@ -350,13 +346,13 @@ class MarkdownSummary { * @param {string} text link text/content * @param {string} href hyperlink * - * @returns {MarkdownSummary} markdown summary instance + * @returns {Summary} summary instance */ - addLink(text: string, href: string): MarkdownSummary { + addLink(text: string, href: string): Summary { const element = this.wrap('a', text, {href}) return this.addRaw(element).addEOL() } } // singleton export -export const markdownSummary = new MarkdownSummary() +export const summary = new Summary()