From f5bc0f69f2989b62752823069f7dc9ee17f9fe2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20THIERIOT?= Date: Thu, 7 Jan 2021 12:10:45 +0100 Subject: [PATCH 1/2] Allow negative patterns to be used in an array --- README.md | 15 +++++++++++++++ __tests__/action.test.ts | 16 ++++++++++++++++ __tests__/fixtures/config.yml | 3 ++- src/action.ts | 11 +++++++---- 4 files changed, 40 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 15d8e43d..e5531054 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,21 @@ Then if a pull request is opened with the branch name `feature/218-add-emoji-sup You can use `*` as a wildcard for matching multiple branch names. See https://www.npmjs.com/package/matcher for more information about wildcard options. +### Negative matcher + +You can also use `!` to add a label on all branches that does NOT match the pattern. + +Used in a list of patterns, then, the branch name will have to match all patterns. + +For example: + +```yml +patch: ['update/*', '!update/sbt-*'] +no-release: update/sbt-* +``` + +In this scenario, a branch named `update/sbt-native-package` will only have the `no-release` label + ### Default configuration When no configuration is provided, the following defaults will be used: diff --git a/__tests__/action.test.ts b/__tests__/action.test.ts index 475f150d..bfc5e125 100644 --- a/__tests__/action.test.ts +++ b/__tests__/action.test.ts @@ -76,6 +76,22 @@ describe('pr-labeler-action', () => { expect.assertions(1) }) + it("adds only one label if the branch matches a negative pattern", async () => { + nock('https://api.github.com') + .get('/repos/Codertocat/Hello-World/contents/.github/pr-labeler.yml?ref=release%2Fskip-this-one') + .reply(200, configFixture()) + .post('/repos/Codertocat/Hello-World/issues/1/labels', body => { + expect(body).toMatchObject({ + labels: ['skip-release'] + }) + return true + }) + .reply(200) + + await action(new MockContext(pullRequestOpenedFixture({ ref: 'release/skip-this-one' }))) + expect.assertions(1) + }) + it("adds no labels if the branch doesn't match any patterns", async () => { nock('https://api.github.com') .get('/repos/Codertocat/Hello-World/contents/.github/pr-labeler.yml?ref=hello_world') diff --git a/__tests__/fixtures/config.yml b/__tests__/fixtures/config.yml index 04574e6b..a9580659 100644 --- a/__tests__/fixtures/config.yml +++ b/__tests__/fixtures/config.yml @@ -1,4 +1,5 @@ '🎉 feature': ['feature/*', 'feat/*'] fix: fix/* chore: chore/* -release: release/* +release: ['release/*', '!release/skip-*'] +skip-release: release/skip-* diff --git a/src/action.ts b/src/action.ts index 09a6b19d..a2f46daf 100644 --- a/src/action.ts +++ b/src/action.ts @@ -45,11 +45,14 @@ async function action(context: Context = github.context) { function getLabelsToAdd(config: Config, branchName: string): string[] { return Object.entries(config).reduce( - (labels, [label, patterns]) => { + + (labels, [label, pattern]) => { + const patterns = Array.isArray(pattern) ? pattern : [pattern] + if ( - Array.isArray(patterns) - ? patterns.some(pattern => matcher.isMatch(branchName, pattern)) - : matcher.isMatch(branchName, patterns) + patterns.some(pattern => pattern.startsWith("!")) + ? patterns.every(pattern => matcher.isMatch(branchName, pattern)) + : patterns.some(pattern => matcher.isMatch(branchName, pattern)) ) { labels.push(label) } From 8625492b3a852fc88ed9e5f1b44568bef8600d74 Mon Sep 17 00:00:00 2001 From: Timon van Spronsen Date: Mon, 8 Nov 2021 16:47:06 +0100 Subject: [PATCH 2/2] Fix: use OR matching even when negate pattern is used --- README.md | 16 ---------------- __tests__/fixtures/config.yml | 2 +- src/action.ts | 28 ++++++++++++---------------- src/utils/arrayify.ts | 3 +++ 4 files changed, 16 insertions(+), 33 deletions(-) create mode 100644 src/utils/arrayify.ts diff --git a/README.md b/README.md index e5531054..ec9e74fc 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,6 @@ For example: feature: ['feature/*', 'feat/*'] fix: fix/* chore: chore/* -fixed-branch: fixed-branch-name ``` Then if a pull request is opened with the branch name `feature/218-add-emoji-support` the Action will automatically apply the `feature` label. @@ -45,21 +44,6 @@ Then if a pull request is opened with the branch name `feature/218-add-emoji-sup You can use `*` as a wildcard for matching multiple branch names. See https://www.npmjs.com/package/matcher for more information about wildcard options. -### Negative matcher - -You can also use `!` to add a label on all branches that does NOT match the pattern. - -Used in a list of patterns, then, the branch name will have to match all patterns. - -For example: - -```yml -patch: ['update/*', '!update/sbt-*'] -no-release: update/sbt-* -``` - -In this scenario, a branch named `update/sbt-native-package` will only have the `no-release` label - ### Default configuration When no configuration is provided, the following defaults will be used: diff --git a/__tests__/fixtures/config.yml b/__tests__/fixtures/config.yml index a9580659..236599f4 100644 --- a/__tests__/fixtures/config.yml +++ b/__tests__/fixtures/config.yml @@ -1,5 +1,5 @@ '🎉 feature': ['feature/*', 'feat/*'] fix: fix/* chore: chore/* -release: ['release/*', '!release/skip-*'] +release: ['release/*', 'hotfix/*', '!release/skip-*'] skip-release: release/skip-* diff --git a/src/action.ts b/src/action.ts index a2f46daf..54e63d38 100644 --- a/src/action.ts +++ b/src/action.ts @@ -3,11 +3,12 @@ import * as github from '@actions/github' import { Context } from '@actions/github/lib/context' import matcher from 'matcher' import getConfig, { Config } from './utils/config' +import { arrayify } from './utils/arrayify' const defaultConfig = { feature: ['feature/*', 'feat/*'], fix: 'fix/*', - chore: 'chore/*' + chore: 'chore/*', } async function action(context: Context = github.context) { @@ -30,7 +31,7 @@ async function action(context: Context = github.context) { await octokit.issues.addLabels({ ...context.repo, number: context.payload.pull_request.number, - labels: labelsToAdd + labels: labelsToAdd, }) } } catch (error) { @@ -44,23 +45,18 @@ async function action(context: Context = github.context) { } function getLabelsToAdd(config: Config, branchName: string): string[] { - return Object.entries(config).reduce( + const labelsToAdd: string[] = [] - (labels, [label, pattern]) => { - const patterns = Array.isArray(pattern) ? pattern : [pattern] + for (const label in config) { + const patterns = arrayify(config[label]) + const matches = matcher([branchName], patterns) - if ( - patterns.some(pattern => pattern.startsWith("!")) - ? patterns.every(pattern => matcher.isMatch(branchName, pattern)) - : patterns.some(pattern => matcher.isMatch(branchName, pattern)) - ) { - labels.push(label) - } + if (matches.length > 0) { + labelsToAdd.push(label) + } + } - return labels - }, - [] as string[] - ) + return labelsToAdd } export default action diff --git a/src/utils/arrayify.ts b/src/utils/arrayify.ts new file mode 100644 index 00000000..10f7bb63 --- /dev/null +++ b/src/utils/arrayify.ts @@ -0,0 +1,3 @@ +export function arrayify(x: T | T[]): T[] { + return Array.isArray(x) ? x : [x] +}