Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions .github/workflows/prep-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ on:
type: string
required: false
default: NEWS.md
use_new_release:
description: Whether or not to use the new conventional commit release note workflow
type: string
required: false
changelog_json:
description: Whether or not it should generate a changelog.json (should only be for node-newrelic)
type: boolean
Expand Down Expand Up @@ -51,6 +47,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 }} ${{ inputs.use_new_release == 'true' && '--use-new-release' || '' }} ${{ inputs.changelog_json == true && '--changelog-json' || ''}}
run: node ./agent-repo/bin/prepare-release.js --release-type ${{ inputs.release_type }} --branch ${{ github.ref }} --repo ${{ github.repository }} --changelog ${{ inputs.changelog_file }} ${{ inputs.changelog_json == true && '--changelog-json' || ''}}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
1 change: 0 additions & 1 deletion .github/workflows/prepare-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +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 }}
changelog_json: true
165 changes: 11 additions & 154 deletions bin/prepare-release.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,13 @@

'use strict'

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_DEFAULT_REMOTE = 'origin'

// Add command line options
Expand All @@ -38,7 +35,6 @@ 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')
program.option(
'--changelog-json',
'generate notes with a corresponding changelog.json(only for node-newrelic)'
Expand Down Expand Up @@ -120,22 +116,15 @@ async function prepareReleaseNotes() {
await git.commit(`Setting version to ${version}.`)
}

let releaseData
if (options.useNewRelease) {
logStep('Create Release Notes - Conventional Commit based')
const [markdown] = await generateConventionalReleaseNotes({
owner,
repo,
newVersion: packageInfo.version,
markdownChangelog: options.changelog,
generateJsonChangelog: options.changelogJson
})
releaseData = markdown
} else {
logStep('Create Release Notes')
releaseData = await generateReleaseNotes(owner, repo)
await updateReleaseNotesFile(options.changelog, version, releaseData.notes)
}
logStep('Create Release Notes - Conventional Commit based')
const [markdown] = await generateConventionalReleaseNotes({
owner,
repo,
newVersion: packageInfo.version,
markdownChangelog: options.changelog,
generateJsonChangelog: options.changelogJson
})
const releaseData = markdown

if (options.dryRun) {
console.log('\nDry run indicated (--dry-run), skipping remaining steps.')
Expand Down Expand Up @@ -167,16 +156,8 @@ async function prepareReleaseNotes() {
console.log('Creating draft PR with new release notes for repo owner: ', owner)
const remoteApi = new Github(owner, repo)

let title
let body

if (options.useNewRelease) {
title = `chore: release ${version}`
body = releaseData
} else {
title = `Release ${version}`
body = getFormattedPrBody(releaseData)
}
const title = `chore: release ${version}`
const body = releaseData

const prOptions = {
head: newBranchName,
Expand Down Expand Up @@ -252,70 +233,6 @@ async function validateCurrentBranch(branch) {
}
}

async function generateReleaseNotes(owner, repo) {
const github = new Github(owner, repo)
const latestRelease = await github.getLatestRelease()
console.log(
`The latest release is: ${latestRelease.name} published: ${latestRelease.published_at}`
)
console.log(`Tag: ${latestRelease.tag_name}, Target: ${latestRelease.target_commitish}`)

const tag = await github.getTagByName(latestRelease.tag_name)
console.log('The tag commit sha is: ', tag.commit.sha)

const commit = await github.getCommit(tag.commit.sha)
const commitDate = commit.commit.committer.date

console.log(`Finding merged pull requests since: ${commitDate}`)

const mergedPullRequests = await github.getMergedPullRequestsSince(commitDate)

const filteredPullRequests = mergedPullRequests.filter((pr) => {
// Sometimes the commit for the PR the tag is set to has an earlier time than
// the PR merge time and we'll pull in release note PRs. Filters those out.

return pr.merge_commit_sha !== tag.commit.sha
})

console.log(`Found ${filteredPullRequests.length}`)

const releaseNoteData = filteredPullRequests.map((pr) => {
const parts = pr.body.split(/(?:^|\n)##\s*/g)

// If only has one part, not in appropriate format.
if (parts.length === 1) {
return {
notes: generateUnformattedNotes(pr.body),
url: pr.html_url
}
}

const { 1: proposedReleaseNotes } = parts

const titleRemoved = proposedReleaseNotes.replace(PROPOSED_NOTES_HEADER, '')
return {
notes: titleRemoved,
url: pr.html_url
}
})

return releaseNoteData.reduce(
(result, currentValue) => {
const trimmedNotes = currentValue.notes.trim()
if (trimmedNotes) {
// avoid adding lines for empty notes
result.notes += '\n\n' + trimmedNotes
}
result.links += `\n* PR: ${currentValue.url}`
return result
},
{
notes: '',
links: ''
}
)
}

/**
* Function for generating and writing our release notes based on Conventional Commits
*
Expand Down Expand Up @@ -358,54 +275,6 @@ async function generateConventionalReleaseNotes({
return [markdown, json]
}

function generateUnformattedNotes(originalNotes) {
let unformattedNotes = originalNotes

// Drop extra snyk details and just keep high-level summary.
if (originalNotes.indexOf('snyk:metadata') >= 0) {
const snykParts = originalNotes.split('<hr/>')
const { 0: snykDescription } = snykParts

unformattedNotes = snykDescription.trim()
}

return ['--- NOTES NEEDS REVIEW ---', unformattedNotes, '--------------------------'].join('\n')
}

function updateReleaseNotesFile(file, version, newNotes) {
return new Promise((resolve, reject) => {
fs.readFile(file, 'utf8', (err, data) => {
if (err) {
reject(err)
}

if (data.startsWith(`### ${version}`)) {
const errMessage = [
`${file} already contains '${version}'`,
`Delete existing ${version} release notes (if desired) and run again`
].join('\n')

reject(new Error(errMessage))
}

const todayFormatted = getReleaseDate()
const newVersionHeader = `### ${version} (${todayFormatted})`

const newContent = [newVersionHeader, newNotes, '\n\n', data].join('')

fs.writeFile(file, newContent, 'utf8', (writeErr) => {
if (writeErr) {
reject(err)
}

console.log(`Added new release notes to ${file} under ${newVersionHeader}`)

resolve()
})
})
})
}

/**
* Returns an RFC3339 date-string for the current day in the Pacific
* (Los Angeles) time zone.
Expand All @@ -422,18 +291,6 @@ function getReleaseDate() {
return `${parts[2]}-${parts[0].padStart(2, '0')}-${parts[1].padStart(2, '0')}`
}

function getFormattedPrBody(data) {
return [
'## Proposed Release Notes',
data.notes,
'## Links',
data.links,
'',
'## Details',
''
].join('\n')
}

/*
* Exports slightly differ for tests vs. Github Actions
* this allows us to require the function without it executing for tests,
Expand Down