Skip to content

Commit

Permalink
include-paths: Only consider PRs that modify these paths for release …
Browse files Browse the repository at this point in the history
…notes
  • Loading branch information
Devon Stewart committed Mar 2, 2022
1 parent bd3f0d7 commit 1ce8b4a
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 3 deletions.
5 changes: 5 additions & 0 deletions action.yml
Expand Up @@ -53,6 +53,11 @@ inputs:
A boolean indicating whether the autolabeler mode is disabled.
required: false
default: ''
include-paths:
description: |
A list of paths for which associated PRs should be considered
required: false
default: ''
outputs:
id:
description: The ID of therelease that was created or updated.
Expand Down
7 changes: 7 additions & 0 deletions index.js
Expand Up @@ -139,6 +139,7 @@ module.exports = (app, { getRouter }) => {
name,
disableReleaser,
commitish,
includePaths,
} = getInput()

const config = await getConfig({
Expand All @@ -150,6 +151,8 @@ module.exports = (app, { getRouter }) => {

if (config === null || disableReleaser) return

const includePaths = config['include-paths']

// GitHub Actions merge payloads slightly differ, in that their ref points
// to the PR branch instead of refs/heads/master
const ref = process.env['GITHUB_REF'] || context.payload.ref
Expand All @@ -173,6 +176,7 @@ module.exports = (app, { getRouter }) => {
targetCommitish,
lastRelease,
config,
includePaths,
})

const sortedMergedPullRequests = sortPullRequests(
Expand Down Expand Up @@ -239,6 +243,9 @@ function getInput({ config } = {}) {
disableAutolabeler:
core.getInput('disable-autolabeler').toLowerCase() === 'true',
commitish: core.getInput('commitish') || undefined,
includePaths: (core.getInput('include-paths') || '')
.split(',')
.filter((x) => Boolean(x)),
}
}

Expand Down
75 changes: 72 additions & 3 deletions lib/commits.js
Expand Up @@ -2,6 +2,34 @@ const _ = require('lodash')
const { log } = require('./log')
const { paginate } = require('./pagination')

const findCommitsWithPathChangesQuery = ({ includePaths }) => /* GraphQL */ `
query findCommitsWithPathChangesQuery(
$name: String!
$owner: String!
$targetCommitish: String!
$since: GitTimestamp
$after: String
) {
repository(name: $name, owner: $owner) {
object(expression: $targetCommitish) {
... on Commit {
${includePaths
.map(
(path, idx) => `\
path${idx}: history(path: "${path}", since: $since, after: $after) {
nodes {
id
}
}
`
)
.join('\n')}
}
}
}
}
`

const findCommitsWithAssociatedPullRequestsQuery = /* GraphQL */ `
query findCommitsWithAssociatedPullRequests(
$name: String!
Expand Down Expand Up @@ -70,6 +98,7 @@ const findCommitsWithAssociatedPullRequests = async ({
targetCommitish,
lastRelease,
config,
includePaths,
}) => {
const { owner, repo } = context.repo()
const variables = {
Expand All @@ -84,7 +113,38 @@ const findCommitsWithAssociatedPullRequests = async ({
const dataPath = ['repository', 'object', 'history']
const repoNameWithOwner = `${owner}/${repo}`

let data, commits
let data,
allCommits,
includedIds = {}

if (includePaths.length > 0) {
const commitsWithPathChanges = await context.octokit.graphql(
findCommitsWithPathChangesQuery({
includePaths,
}),
lastRelease ? { ...variables, since: lastRelease.created_at } : variables
)

var anyChanges = false
for (const [idx, path] of includePaths.entries()) {
const { nodes } = _.get(commitsWithPathChanges, [
'repository',
'object',
`path${idx}`,
])
includedIds[path] = includedIds[path] || new Set([])
for (const { id } of nodes) {
anyChanges = true
includedIds[path].add(id)
}
}

if (!anyChanges) {
// Short circuit to avoid blowing GraphQL budget
return { commits: [], pullRequests: [] }
}
}

if (lastRelease) {
log({
context,
Expand All @@ -99,7 +159,7 @@ const findCommitsWithAssociatedPullRequests = async ({
)
// GraphQL call is inclusive of commits from the specified dates. This means the final
// commit from the last tag is included, so we remove this here.
commits = _.get(data, [...dataPath, 'nodes']).filter(
allCommits = _.get(data, [...dataPath, 'nodes']).filter(
(commit) => commit.committedDate != lastRelease.created_at
)
} else {
Expand All @@ -111,9 +171,16 @@ const findCommitsWithAssociatedPullRequests = async ({
variables,
dataPath
)
commits = _.get(data, [...dataPath, 'nodes'])
allCommits = _.get(data, [...dataPath, 'nodes'])
}

const commits =
includePaths.length > 0
? allCommits.filter((commit) =>
includePaths.some((path) => includedIds[path].has(commit.id))
)
: allCommits

const pullRequests = _.uniqBy(
commits.flatMap((commit) => commit.associatedPullRequests.nodes),
'number'
Expand All @@ -127,5 +194,7 @@ const findCommitsWithAssociatedPullRequests = async ({
exports.findCommitsWithAssociatedPullRequestsQuery =
findCommitsWithAssociatedPullRequestsQuery

exports.findCommitsWithPathChangesQuery = findCommitsWithPathChangesQuery

exports.findCommitsWithAssociatedPullRequests =
findCommitsWithAssociatedPullRequests
1 change: 1 addition & 0 deletions lib/default-config.js
Expand Up @@ -16,6 +16,7 @@ const DEFAULT_CONFIG = Object.freeze({
categories: [],
'exclude-labels': [],
'include-labels': [],
'include-paths': [],
'exclude-contributors': [],
'no-contributors-template': 'No contributors',
replacers: [],
Expand Down
4 changes: 4 additions & 0 deletions lib/schema.js
Expand Up @@ -51,6 +51,10 @@ const schema = (context) => {
.items(Joi.string())
.default(DEFAULT_CONFIG['include-labels']),

'include-paths': Joi.array()
.items(Joi.string())
.default(DEFAULT_CONFIG['include-paths']),

'exclude-contributors': Joi.array()
.items(Joi.string())
.default(DEFAULT_CONFIG['exclude-contributors']),
Expand Down

0 comments on commit 1ce8b4a

Please sign in to comment.