From d97b421be5acda61f0212fd49a433e58811fc27c Mon Sep 17 00:00:00 2001 From: Jessica Lopatta Date: Fri, 12 May 2023 15:38:45 -0400 Subject: [PATCH] ci: add --use-new-release functionality (#1633) --- .github/workflows/prep-release.yml | 6 +- .github/workflows/prepare-release.yml | 1 + bin/.eslintrc.js | 3 +- bin/conventional-changelog.js | 36 ++++-- bin/create-docs-pr.js | 69 ++++++++-- bin/prepare-release.js | 112 +++++++++++++---- bin/templates/header.hbs | 2 +- bin/test/conventional-changelog.test.js | 9 +- bin/test/create-docs-pr.test.js | 159 ++++++++++++++++++++++++ bin/test/prepare-release.test.js | 154 +++++++++++++++++++++++ third_party_manifest.json | 2 +- 11 files changed, 503 insertions(+), 50 deletions(-) create mode 100644 bin/test/create-docs-pr.test.js create mode 100644 bin/test/prepare-release.test.js diff --git a/.github/workflows/prep-release.yml b/.github/workflows/prep-release.yml index dfa815056b..5bdda54b37 100644 --- a/.github/workflows/prep-release.yml +++ b/.github/workflows/prep-release.yml @@ -13,6 +13,10 @@ on: type: string required: false default: NEWS.md + use_new_release: + description: Whether or not to use the new conventional commit release note workflow + required: false + default: false jobs: generate-release-notes: @@ -41,6 +45,6 @@ jobs: git config user.name $GITHUB_ACTOR git config user.email gh-actions-${GITHUB_ACTOR}@github.com - name: Create Release Notes - run: node ./agent-repo/bin/prepare-release.js --release-type ${{ inputs.release_type }} --branch ${{ github.ref }} --repo ${{ github.repository }} --changelog ${{ inputs.changelog_file }} + run: node ./agent-repo/bin/prepare-release.js --release-type ${{ inputs.release_type }} --branch ${{ github.ref }} --repo ${{ github.repository }} --changelog ${{ inputs.changelog_file }} --use-new-release ${{ inputs.use_new_release }} env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/prepare-release.yml b/.github/workflows/prepare-release.yml index 963f6e5ccc..75d4e79745 100644 --- a/.github/workflows/prepare-release.yml +++ b/.github/workflows/prepare-release.yml @@ -14,3 +14,4 @@ jobs: uses: newrelic/node-newrelic/.github/workflows/prep-release.yml@main with: release_type: ${{ github.event.inputs.release_type }} + use_new_release: ${{ vars.USE_NEW_RELEASE }} diff --git a/bin/.eslintrc.js b/bin/.eslintrc.js index e994f4cd35..31c4b824f2 100644 --- a/bin/.eslintrc.js +++ b/bin/.eslintrc.js @@ -7,6 +7,7 @@ module.exports = { rules: { 'no-process-exit': 'off', - 'no-console': 'off' + 'no-console': 'off', + 'no-shadow': 'off' } } diff --git a/bin/conventional-changelog.js b/bin/conventional-changelog.js index 9dfe3f0b1c..f9e742fd44 100644 --- a/bin/conventional-changelog.js +++ b/bin/conventional-changelog.js @@ -113,6 +113,21 @@ class ConventionalChangelog { } } + /** + * Helper method to strip out the PR links that Github + * likes to add to the end of commit messages when + * using squash and merge + * + * Also since we're already manipulating the string, + * use .trim() to strip any trailing or leading whitespace + * + * @param {string} subject commit message header + * @returns {string} the commit message header with any PR links removed and whitespace trimmed + */ + removePrLinks(subject) { + return subject.replace(/\(\#\d+\)$/, '').trim() + } + /** * Function for generating our front-matter content in a machine readable format * @@ -120,21 +135,22 @@ class ConventionalChangelog { * @returns {object} the entry to add to the JSON changelog */ generateJsonChangelog(commits) { + const self = this const securityChanges = [] const bugfixChanges = [] const featureChanges = [] commits.forEach((commit) => { if (commit.type === 'security') { - securityChanges.push(commit.subject) + securityChanges.push(self.removePrLinks(commit.subject)) } if (commit.type === 'fix') { - bugfixChanges.push(commit.subject) + bugfixChanges.push(self.removePrLinks(commit.subject)) } if (commit.type === 'feat') { - featureChanges.push(commit.subject) + featureChanges.push(self.removePrLinks(commit.subject)) } }) @@ -214,9 +230,8 @@ class ConventionalChangelog { * @param {string} markdownFile path to the markdown file to update, defaults to NEWS.md * @returns {void} */ - async writeMarkdownChangelog(newEntry, markdownFile = '../NEWS.md') { - const filename = path.resolve(__dirname, markdownFile) - const changelog = await readFile(filename, 'utf-8') + async writeMarkdownChangelog(newEntry, markdownFile = 'NEWS.md') { + const changelog = await readFile(markdownFile, 'utf-8') const heading = `### v${this.newVersion}` @@ -225,7 +240,7 @@ class ConventionalChangelog { return } - await writeFile(filename, `${newEntry}\n${changelog}`, 'utf-8') + await writeFile(markdownFile, `${newEntry}\n${changelog}`, 'utf-8') } /** @@ -237,9 +252,8 @@ class ConventionalChangelog { * @param {string} jsonFile path to the markdown file to update, defaults to changelog.json * @returns {void} */ - async writeJsonChangelog(newEntry, jsonFile = '../changelog.json') { - const filename = path.resolve(__dirname, jsonFile) - const rawChangelog = await readFile(filename, 'utf-8') + async writeJsonChangelog(newEntry, jsonFile = 'changelog.json') { + const rawChangelog = await readFile(jsonFile, 'utf-8') const changelog = JSON.parse(rawChangelog) if (changelog.entries.find((entry) => entry.version === this.newVersion)) { @@ -248,7 +262,7 @@ class ConventionalChangelog { } changelog.entries.unshift(newEntry) - await writeFile(filename, JSON.stringify(changelog, null, 2), 'utf-8') + await writeFile(jsonFile, JSON.stringify(changelog, null, 2), 'utf-8') } } diff --git a/bin/create-docs-pr.js b/bin/create-docs-pr.js index c2849947f6..76c2a41646 100644 --- a/bin/create-docs-pr.js +++ b/bin/create-docs-pr.js @@ -35,6 +35,11 @@ program.option( 'Path to the docs-website fork on local machine', '/tmp/docs-website' ) +program.option( + '--front-matter-file ', + 'Name of changelog(defaults to changelog.json)', + 'changelog.json' +) program.option('--repo-owner ', 'Owner of the target repo', 'newrelic') @@ -66,6 +71,7 @@ async function createReleaseNotesPr() { validateTag(version, options.force) logStep('Get Release Notes from File') const { body, releaseDate } = await getReleaseNotes(version, options.changelog) + const frontmatter = await getFrontMatter(version, options.frontMatterFile) if (!fs.existsSync(options.repoPath)) { logStep('Clone docs repo') @@ -75,7 +81,7 @@ async function createReleaseNotesPr() { logStep('Branch Creation') const branchName = await createBranch(options.repoPath, version, options.dryRun) logStep('Format release notes file') - const releaseNotesBody = formatReleaseNotes(releaseDate, version, body) + const releaseNotesBody = formatReleaseNotes(releaseDate, version, body, frontmatter) logStep('Create Release Notes') await addReleaseNotesFile(releaseNotesBody, version) logStep('Commit Release Notes') @@ -124,7 +130,7 @@ async function getReleaseNotes(version, releaseNotesFile) { const data = await readReleaseNoteFile(releaseNotesFile) - const sections = data.split('### ') + const sections = data.split(/^### /m) // Iterate over all past releases to find the version we want const versionChangeLog = sections.find((section) => section.startsWith(version)) // e.g. v7.1.2 (2021-02-24)\n\n @@ -135,6 +141,33 @@ async function getReleaseNotes(version, releaseNotesFile) { return { body, releaseDate } } +/** + * Pulls the necessary frontmatter content for the given version + * from our JSON based changelog + * + * @param {string} tagName version tag name + * @param {string} frontMatterFile JSON changelog file + * @returns {object} frontmatter hash containing security, bugfix and feature lists + */ +async function getFrontMatter(tagName, frontMatterFile) { + console.log(`Retrieving release notes from file: ${frontMatterFile}`) + + const version = tagName.replace('v', '') + const data = await readReleaseNoteFile(frontMatterFile) + const changelog = JSON.parse(data) + const frontmatter = changelog.entries.find((entry) => entry.version === version) + + if (!frontmatter) { + throw new Error(`Unable to find ${version} entry in ${frontMatterFile}`) + } + + return { + security: JSON.stringify(frontmatter.changes.security), + bugfixes: JSON.stringify(frontmatter.changes.bugfixes), + features: JSON.stringify(frontmatter.changes.features) + } +} + /** * Reads the contents of NEWS.md * @@ -155,8 +188,8 @@ async function readReleaseNoteFile(file) { /** * Clones docs repo * - * @param repoPath - * @param repoOwner + * @param {string} repoPath where to checkout the repo + * @param {string} repoOwner Github organization/owner name * @returns {boolean} success or failure */ async function cloneDocsRepo(repoPath, repoOwner) { @@ -198,15 +231,19 @@ async function createBranch(filePath, version, dryRun) { * @param {string} releaseDate date the release was created * @param {string} version version number * @param {string} body list of changes + * @param {object} frontmatter agent version metadata information about the release * @returns {string} appropriately formatted release notes */ -function formatReleaseNotes(releaseDate, version, body) { +function formatReleaseNotes(releaseDate, version, body, frontmatter) { const releaseNotesBody = [ '---', 'subject: Node.js agent', `releaseDate: '${releaseDate}'`, `version: ${version.substr(1)}`, // remove the `v` from start of version `downloadLink: 'https://www.npmjs.com/package/newrelic'`, + `security: ${frontmatter.security}`, + `bugs: ${frontmatter.bugfixes}`, + `features: ${frontmatter.features}`, '---', '', '## Notes', @@ -284,13 +321,16 @@ async function createPR(version, branch, dryRun, repoOwner) { } const github = new Github(repoOwner, 'docs-website') - const title = `Node.js Agent ${version} Release Notes` + const title = `chore: add Node.js Agent ${version} Release Notes` const head = repoOwner === `newrelic` ? branch : `${repoOwner}:${branch}` + const body = + 'This is an automated PR generated when the Node.js agent is released. Please merge as soon as possible.' + const prOptions = { head, base: BASE_BRANCH, title, - body: title + body } console.log(`Creating PR with following options: ${JSON.stringify(prOptions)}\n\n`) @@ -326,4 +366,17 @@ function logStep(step) { console.log(`\n ----- [Step]: ${step} -----\n`) } -createReleaseNotesPr() +/* + * Exports slightly differ for tests vs. Github Actions + * this allows us to require the function without it executing for tests, + * and executing via `node` cli in GHA + */ +if (require.main === module) { + createReleaseNotesPr() +} else { + module.exports = { + getReleaseNotes, + getFrontMatter, + formatReleaseNotes + } +} diff --git a/bin/prepare-release.js b/bin/prepare-release.js index a571f6fedb..67de0a958c 100644 --- a/bin/prepare-release.js +++ b/bin/prepare-release.js @@ -10,11 +10,11 @@ const fs = require('fs') const { program, Option } = require('commander') const Github = require('./github') +const ConventionalChangelog = require('./conventional-changelog') const git = require('./git-commands') const npm = require('./npm-commands') const PROPOSED_NOTES_HEADER = 'Proposed Release Notes' - const FORCE_RUN_DEAFULT_REMOTE = 'origin' // Add command line options @@ -38,6 +38,7 @@ program.option( 'Repo to work against(Defaults to newrelic/node-newrelic)', 'newrelic/node-newrelic' ) +program.option('--use-new-release', 'use new conventional commit release note process') function stopOnError(err) { if (err) { @@ -52,29 +53,29 @@ function logStep(step) { console.log(`\n ----- [Step]: ${step} -----\n`) } +async function isValid(options) { + if (options.force) { + console.log('--force set. Skipping validation logic') + return true + } + const startingBranch = options.branch.replace('refs/heads/', '') + return ( + (await validateRemote(options.remote)) && + (await validateLocalChanges()) && + (await validateCurrentBranch(startingBranch)) + ) +} + async function prepareReleaseNotes() { // Parse commandline options inputs program.parse() - const options = program.opts() console.log('Script running with following options: ', JSON.stringify(options)) const [owner, repo] = options.repo.split('/') logStep('Validation') - if (options.force) { - console.log('--force set. Skipping validation logic') - } - - const startingBranch = options.branch.replace('refs/heads/', '') - - const isValid = - options.force || - ((await validateRemote(options.remote)) && - (await validateLocalChanges()) && - (await validateCurrentBranch(startingBranch))) - - if (!isValid) { + if (!(await isValid(options))) { console.log('Invalid configuration. Halting script.') stopOnError() } @@ -115,10 +116,21 @@ async function prepareReleaseNotes() { await git.commit(`Setting version to ${version}.`) } - logStep('Create Release Notes') - - const releaseData = await generateReleaseNotes(owner, repo) - await updateReleaseNotesFile(options.changelog, version, releaseData.notes) + let releaseData + if (options.useNewRelease) { + logStep('Create Release Notes - Conventional Commit based') + const [markdown] = await generateConventionalReleaseNotes( + owner, + repo, + packageInfo.version, + options.changelog + ) + releaseData = markdown + } else { + logStep('Create Release Notes') + releaseData = await generateReleaseNotes(owner, repo) + await updateReleaseNotesFile(options.changelog, version, releaseData.notes) + } if (options.dryRun) { console.log('\nDry run indicated (--dry-run), skipping remaining steps.') @@ -149,8 +161,18 @@ async function prepareReleaseNotes() { console.log('Creating draft PR with new release notes for repo owner: ', owner) const remoteApi = new Github(owner, repo) - const title = `Release ${version}` - const body = getFormattedPrBody(releaseData) + + let title + let body + + if (options.useNewRelease) { + title = `chore: release ${version}` + body = releaseData + } else { + title = `Release ${version}` + body = getFormattedPrBody(releaseData) + } + const prOptions = { head: newBranchName, base: 'main', @@ -289,6 +311,40 @@ async function generateReleaseNotes(owner, repo) { ) } +/** + * Function for generating and writing our release notes based on Conventional Commits + * + * @param {string} owner github repo org + * @param {string} repo github repo name + * @param {string} newVersion version to be published + * @param {string} markdownChangelog filepath of markdown changelog + */ +async function generateConventionalReleaseNotes(owner, repo, newVersion, markdownChangelog) { + const github = new Github(owner, repo) + const latestRelease = await github.getLatestRelease() + + const changelog = new ConventionalChangelog({ + org: owner, + repo, + newVersion, + previousVersion: latestRelease.tag_name.replace('v', '') + }) + + const commits = await changelog.getFormattedCommits() + + const [markdown, json] = await Promise.all([ + changelog.generateMarkdownChangelog(commits), + changelog.generateJsonChangelog(commits) + ]) + + await Promise.all([ + changelog.writeMarkdownChangelog(markdown, markdownChangelog), + changelog.writeJsonChangelog(json) + ]) + + return [markdown, json] +} + function generateUnformattedNotes(originalNotes) { let unformattedNotes = originalNotes @@ -350,4 +406,16 @@ function getFormattedPrBody(data) { ].join('\n') } -prepareReleaseNotes() +/* + * Exports slightly differ for tests vs. Github Actions + * this allows us to require the function without it executing for tests, + * and executing via `node` cli in GHA + */ +if (require.main === module) { + prepareReleaseNotes() +} else { + module.exports = { + generateConventionalReleaseNotes, + isValid + } +} diff --git a/bin/templates/header.hbs b/bin/templates/header.hbs index dd16310033..420f5fd22a 100644 --- a/bin/templates/header.hbs +++ b/bin/templates/header.hbs @@ -2,4 +2,4 @@ {{~#if title}} "{{title}}" {{~/if}} {{~#if date}} ({{date}}) -{{/if}} \ No newline at end of file +{{~/if}} \ No newline at end of file diff --git a/bin/test/conventional-changelog.test.js b/bin/test/conventional-changelog.test.js index 4f9b32fbdd..906a3301af 100644 --- a/bin/test/conventional-changelog.test.js +++ b/bin/test/conventional-changelog.test.js @@ -53,7 +53,6 @@ const exampleCommit = { } const exampleMarkdown = `### v1.0.0 (2020-04-03) - #### ⚠ BREAKING CHANGES * **thing:** updated Thing to prevent accidental modifications to inputs @@ -187,10 +186,10 @@ tap.test('Conventional Changelog Class', (testHarness) => { testHarness.test('generateJsonChangelog - should create the new JSON changelog entry', (t) => { const commits = [ - { type: 'fix', subject: 'Fixed issue one' }, - { type: 'fix', subject: 'Fixed issue two' }, - { type: 'feat', subject: 'Added something new' }, - { type: 'security', subject: 'Bumped some dep' } + { type: 'fix', subject: 'Fixed issue one (#1234)' }, + { type: 'fix', subject: ' Fixed issue two' }, + { type: 'feat', subject: 'Added something new ' }, + { type: 'security', subject: ' Bumped some dep (#4567)' } ] const changelog = new ConventionalChangelog({ newVersion: '1.0.0', previousVersion: '0.9.0' }) diff --git a/bin/test/create-docs-pr.test.js b/bin/test/create-docs-pr.test.js new file mode 100644 index 0000000000..d467047e2c --- /dev/null +++ b/bin/test/create-docs-pr.test.js @@ -0,0 +1,159 @@ +/* + * Copyright 2023 New Relic Corporation. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +'use strict' + +const tap = require('tap') +const proxyquire = require('proxyquire') +const sinon = require('sinon') +const SCRIPT_PATH = '../create-docs-pr' + +tap.test('Create Docs PR script', (testHarness) => { + testHarness.autoend() + + testHarness.test('getReleaseNotes', (t) => { + t.autoend() + + let mockFs + let script + + t.beforeEach(() => { + mockFs = { + readFile: sinon.stub() + } + script = proxyquire(SCRIPT_PATH, { + fs: mockFs + }) + }) + + t.test('should return our release notes', async (t) => { + const expectedMarkdown = [ + '### v1.2.3 (2020-04-03)', + '', + '#### Stuff heading', + '* first commit', + '', + '### v1.2.2 (2020-01-01)', + '', + '#### Things heading', + '* second commit' + ].join('\n') + + mockFs.readFile.yields(null, expectedMarkdown) + + const result = await script.getReleaseNotes('v1.2.3', 'NEWS.md') + + t.equal(result.releaseDate, '2020-04-03') + + const body = result.body.split('\n') + t.equal(body[0], '#### Stuff heading') + t.equal(body[1], '* first commit') + t.equal(body[4], '### Support statement:') + + t.end() + }) + }) + + testHarness.test('getFrontMatter', (t) => { + t.autoend() + + let mockFs + let script + + t.beforeEach(() => { + mockFs = { + readFile: sinon.stub() + } + script = proxyquire(SCRIPT_PATH, { + fs: mockFs + }) + }) + + t.test('should throw an error if there is no frontmatter', async (t) => { + mockFs.readFile.yields(null, JSON.stringify({ entries: [{ version: '1.2.3', changes: [] }] })) + + const func = () => script.getFrontMatter('v2.0.0', 'changelog.json') + t.rejects(func, 'Unable to find 2.0.0 entry in changelog.json') + + t.end() + }) + + t.test('should return our formatted frontmatter', async (t) => { + mockFs.readFile.yields( + null, + JSON.stringify({ + entries: [ + { + version: '2.0.0', + changes: { + security: ['one', 'two'], + features: ['three', 'four'], + bugfixes: ['five', 'six'] + } + } + ] + }) + ) + + const result = await script.getFrontMatter('v2.0.0', 'changelog.json') + + t.same(result, { + security: '["one","two"]', + bugfixes: '["five","six"]', + features: '["three","four"]' + }) + t.end() + }) + }) + + testHarness.test('formatReleaseNotes', (t) => { + t.autoend() + + let script + + t.beforeEach(() => { + script = proxyquire(SCRIPT_PATH, {}) + }) + + t.test('should generate the release note markdown', (t) => { + const markdown = [ + '#### Stuff', + '* commit number one', + '#### Things', + '* commit number two' + ].join('\n') + + const frontmatter = { + security: '["upgraded a dep"]', + bugfixes: '["fixed a bug"]', + features: '["added new api method"]' + } + const result = script.formatReleaseNotes('2020-04-03', 'v2.0.0', markdown, frontmatter) + + const expected = [ + '---', + 'subject: Node.js agent', + `releaseDate: '2020-04-03'`, + 'version: 2.0.0', + `downloadLink: 'https://www.npmjs.com/package/newrelic'`, + `security: ["upgraded a dep"]`, + `bugs: ["fixed a bug"]`, + `features: ["added new api method"]`, + `---`, + '', + '## Notes', + '', + '#### Stuff', + '* commit number one', + '#### Things', + '* commit number two' + ].join('\n') + + t.equal(result, expected) + + t.end() + }) + }) +}) diff --git a/bin/test/prepare-release.test.js b/bin/test/prepare-release.test.js new file mode 100644 index 0000000000..8dd9abb3d6 --- /dev/null +++ b/bin/test/prepare-release.test.js @@ -0,0 +1,154 @@ +/* + * Copyright 2023 New Relic Corporation. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +'use strict' + +const tap = require('tap') +const proxyquire = require('proxyquire') +const sinon = require('sinon') + +tap.test('Prepare Release script', (testHarness) => { + testHarness.autoend() + + testHarness.test('generateConventionalReleaseNotes', (t) => { + t.autoend() + + let mockConventionalCommands + let MockConventionalChangelog + let mockGithubCommands + let MockGithubSdk + let script + + t.beforeEach(() => { + mockConventionalCommands = { + getFormattedCommits: sinon.stub(), + generateMarkdownChangelog: sinon.stub(), + generateJsonChangelog: sinon.stub(), + writeMarkdownChangelog: sinon.stub(), + writeJsonChangelog: sinon.stub() + } + MockConventionalChangelog = sinon.stub().returns(mockConventionalCommands) + + mockGithubCommands = { + getLatestRelease: sinon.stub() + } + MockGithubSdk = sinon.stub().returns(mockGithubCommands) + + script = proxyquire('../prepare-release', { + './github': MockGithubSdk, + './conventional-changelog': MockConventionalChangelog + }) + }) + + t.test('should return the markdown and json generated notes', async (t) => { + mockGithubCommands.getLatestRelease.resolves({ tag_name: 'v1.2.3' }) + const expectedCommits = [{ title: 'stuff: commit number one' }] + mockConventionalCommands.getFormattedCommits.resolves(expectedCommits) + const expectedMarkdown = ` + ### v2.0.0 + + #### Stuff + * commit number 1 + + ### v1.2.3 + ` + mockConventionalCommands.generateMarkdownChangelog.resolves(expectedMarkdown) + const expectedJson = { + entries: [ + { version: '2.0.0', changes: [{ type: 'stuff', subject: 'commit number one' }] }, + { version: '1.2.3', changes: [] } + ] + } + mockConventionalCommands.generateJsonChangelog.resolves(expectedJson) + + const [markdown, json] = await script.generateConventionalReleaseNotes( + 'org', + 'repo', + '2.0.0', + 'changelog.json' + ) + + t.same(json, expectedJson) + t.equal(markdown, expectedMarkdown) + + t.ok(MockGithubSdk.calledWith('org', 'repo')) + t.ok( + MockConventionalChangelog.calledWith({ + org: 'org', + repo: 'repo', + newVersion: '2.0.0', + previousVersion: '1.2.3' + }) + ) + + t.equal(mockConventionalCommands.getFormattedCommits.callCount, 1) + + t.ok(mockConventionalCommands.generateMarkdownChangelog.calledWith(expectedCommits)) + t.ok(mockConventionalCommands.generateJsonChangelog.calledWith(expectedCommits)) + + t.ok( + mockConventionalCommands.writeMarkdownChangelog.calledWith( + expectedMarkdown, + 'changelog.json' + ) + ) + t.ok(mockConventionalCommands.writeJsonChangelog.calledWith(expectedJson)) + + t.end() + }) + }) + + testHarness.test('isValid', (t) => { + t.autoend() + + let mockGitCommands + let script + + t.beforeEach(() => { + mockGitCommands = { + getPushRemotes: sinon.stub(), + getLocalChanges: sinon.stub(), + getCurrentBranch: sinon.stub() + } + + script = proxyquire('../prepare-release', { + './git-commands': mockGitCommands + }) + }) + + t.test('should return true if force mode enabled', async (t) => { + const result = await script.isValid({ force: true }) + + t.equal(result, true) + t.end() + }) + + t.test('should return true when all checks pass', async (t) => { + mockGitCommands.getPushRemotes.resolves({ origin: 'stuff' }) + mockGitCommands.getLocalChanges.resolves([]) + mockGitCommands.getCurrentBranch.resolves('test-branch') + + const result = await script.isValid({ force: false, branch: 'test-branch', remote: 'origin' }) + + t.equal(result, true) + t.end() + }) + + t.test('should return false if one check fails', async (t) => { + mockGitCommands.getPushRemotes.resolves({ origin: 'stuff' }) + mockGitCommands.getLocalChanges.resolves(['stuff']) + mockGitCommands.getCurrentBranch.resolves('another-branch') + + const result = await script.isValid({ + force: false, + branch: 'another-branch', + remote: 'origin' + }) + + t.equal(result, false) + t.end() + }) + }) +}) diff --git a/third_party_manifest.json b/third_party_manifest.json index 4e6a7a95f2..5a4e6d7b91 100644 --- a/third_party_manifest.json +++ b/third_party_manifest.json @@ -1,5 +1,5 @@ { - "lastUpdated": "Wed May 10 2023 16:48:17 GMT-0400 (Eastern Daylight Time)", + "lastUpdated": "Thu May 11 2023 16:39:40 GMT-0400 (Eastern Daylight Time)", "projectName": "New Relic Node Agent", "projectUrl": "https://github.com/newrelic/node-newrelic", "includeOptDeps": true,