Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle merge case where no prior release PR exists, but commit history exists #324

Merged
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
101 changes: 59 additions & 42 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -295,44 +295,14 @@ async function actionsYML(){
*/
async function extractChangelog(options){
let [owner,repo] = process.env.GITHUB_REPOSITORY.split('/')
let lastRelease = await getLastRelease({ owner, repo })

let a,b; {
let r = await octokit.rest.search.issuesAndPullRequests({
q: `is:pr is:merged base:${target} head:${source} repo:${owner}/${repo}`
,sort: 'updated'
,order: 'desc'
,per_page: 2
,page: 1
})

r = r.data.items
r = r.sort( (a,b) => a.number - b.number )

let [_a,_b] = r
a = _a
b = _b
}

// The PR to use to generate the next changelog entry
const lastRelease = await getLastRelease({ owner, repo })

let recentBranches; {

let firstEverRelease = a == null;
let onlyOneRelease = b == null

let q = firstEverRelease || onlyOneRelease
? `base:${source} is:pr is:merged repo:${owner}/${repo}`
: `merged:${a.closed_at}..${b.closed_at} base:${source} is:pr is:merged repo:${owner}/${repo}`

recentBranches =
await octokit.paginate(octokit.rest.search.issuesAndPullRequests, {
q
,sort: 'updated'
,order: 'desc'
,per_page: 2
,page: 1
})
}
let recentBranches =
await getRecentBranchesFromPRCommitHistory({
owner, repo, pull_number: lastRelease.number
})

let lines =
lastRelease
Expand Down Expand Up @@ -385,7 +355,7 @@ async function extractChangelog(options){
mode = 'major'; continue;
} else if ( line == '### Minor Changes' ) {
mode = 'minor'; continue;
} else if ( line == '### Patches' ) {
} else if ( line == '### Patch Changes' ) {
mode = 'patch'; continue;
} else {
sections[mode].push(line)
Expand All @@ -397,7 +367,7 @@ async function extractChangelog(options){
let patch = sections.patch.join('\n').trim()

let { version } =
await inferVersion({ owner, repo, lastRelease })
await inferVersion({ owner, repo })

// this version is the published version + branch inferred versions
// it ignores the version set in the PR description
Expand Down Expand Up @@ -526,6 +496,53 @@ async function getThisRelease({ owner, repo }){
return thisRelease
}

/**
* Identifies the feature branch PRs from a given
* release PRs commit history.
*
* Much more accurate than relying on merged_at timestamps.
*
* `pr` cannot use this because we create the pull request
* after we've generated the changelog. But it might be
* worth creating an empty PR first just to unify that logic
* and make the code a bit less temporal.
*/
async function getRecentBranchesFromPRCommitHistory({
owner, repo, pull_number
}){

const pullCommits =
await octokit.paginate(
octokit.rest.pulls.listCommits
, { owner, repo, pull_number }
)

let recentBranches = await Promise.all(
pullCommits.map( x =>

octokit.rest.repos.listPullRequestsAssociatedWithCommit({
owner
, repo
, commit_sha: x.sha
})
.then( ({ data: [x] }) => x ? [x] : [] )
)
)
.then( xs => xs.flat().filter( x => x.base.ref === source ) )

{
let seen = new Set()
recentBranches = recentBranches.filter( x => {
if( seen.has( x.number) ) return false;
seen.add(x.number)
return true;
})
}

return recentBranches;
}


async function getRecentBranchesFromLastRelease({ owner, repo, lastRelease }){
return getRecentBranchesFromLastCommitDate({
owner
Expand Down Expand Up @@ -574,7 +591,7 @@ async function merge(options){
const changelogOut = typeof options.changelog == 'string' ? { out: options.changelog } : {}

let out = options.changelog
? await changelog({ ...changelogOut })
? await externalChangelog({ ...changelogOut })
: await extractChangelog({})

let { nextVersion } = out
Expand Down Expand Up @@ -1200,7 +1217,7 @@ async function pr(options){
}
}

async function changelog(options){
async function externalChangelog(options){
let x = await extractChangelog({})

if( x.changelog + x.changeSummary + x.contributorsBody == '' ) {
Expand Down Expand Up @@ -1863,7 +1880,7 @@ let subcommands = {
, merge
, 'actions-yml': actionsYML
, 'extract-changelog': extractChangelog
, changelog
, changelog: externalChangelog
, 'feature-pr': featurePR
, 'repair-target': repairTarget
, rollback
Expand All @@ -1878,7 +1895,7 @@ let preflights = {
pr
, merge
, 'extract-changelog': extractChangelog
, changelog
, changelog: externalChangelog
, 'feature-pr': featurePR
, 'repair-target': repairTarget
, rollback
Expand Down