Merge pull request #654 from mikepenz/feature/651

Add ability to specify `on_property` as array
This commit is contained in:
Mike Penz
2022-01-28 20:37:02 +01:00
committed by GitHub
6 changed files with 122 additions and 26 deletions
+3 -3
View File
@@ -340,14 +340,14 @@ Table of descriptions for the `configuration.json` options to configure the resu
# Install the dependencies
$ npm install
# Verify lint is happy
$ npm run lint -- --fix
# Build the typescript and package it for distribution
$ npm run build && npm run package
# Run the tests, use to debug, and test it out
$ npm test
# Verify lint is happy
$ npm run lint -- --fix
```
It's suggested to export the token to your path before running the tests so that API calls can be done to GitHub.
+43
View File
@@ -90,6 +90,22 @@ mergedPullRequests.push(
}
)
const pullRequestWithLabelInBody: PullRequestInfo = {
number: 5,
title: 'label in body',
htmlURL: '',
baseBranch: '',
mergedAt: moment(),
mergeCommitSha: 'sha1',
author: 'Mike',
repoName: 'test-repo',
labels: new Set<string>(),
milestone: '',
body: '[Issue][Feature][AB-1234321] - no magic body for this matter',
assignees: [],
requestedReviewers: []
}
it('Extract label from title, combined regex', async () => {
configuration.label_extractor = [
{
@@ -114,6 +130,33 @@ it('Extract label from title, combined regex', async () => {
)
})
it('Extract label from title and body, combined regex', async () => {
configuration.label_extractor = [
{
pattern: '.*(\\[Feature\\]|\\[Issue\\]).*',
target: '$1',
on_property: ['title', 'body']
}
]
let prs = Array.from(mergedPullRequests)
prs.push(pullRequestWithLabelInBody)
const resultChangelog = buildChangelog(prs, {
owner: 'mikepenz',
repo: 'test-repo',
fromTag: '1.0.0',
toTag: '2.0.0',
failOnError: false,
commitMode: false,
configuration
})
expect(resultChangelog).toStrictEqual(
`## 🚀 Features\n\n- [Feature][AB-1234] - this is a PR 1 title message\n - PR: #1\n- [Issue][Feature][AB-1234321] - this is a PR 3 title message\n - PR: #3\n- label in body\n - PR: #5\n\n## 🐛 Fixes\n\n- [Issue][AB-4321] - this is a PR 2 title message\n - PR: #2\n\n`
)
})
it('Extract label from title, split regex', async () => {
configuration.label_extractor = [
{
Generated Vendored
+29 -9
View File
@@ -1402,6 +1402,12 @@ function validateTransformer(transformer) {
method = transformer.method;
onEmpty = transformer.on_empty;
}
// legacy handling, transform single value input to array
if (!Array.isArray(onProperty)) {
if (onProperty !== undefined) {
onProperty = [onProperty];
}
}
return {
pattern: new RegExp(transformer.pattern.replace('\\\\', '\\'), (_a = transformer.flags) !== null && _a !== void 0 ? _a : 'gu'),
target: transformer.target || '',
@@ -1420,26 +1426,40 @@ function extractValues(pr, extractor, extractor_usecase) {
if (extractor.pattern == null) {
return null;
}
let onValue;
if (extractor.onProperty !== undefined) {
let value = pr[extractor.onProperty];
if (value === undefined) {
core.warning(`⚠️ the provided property '${extractor.onProperty}' for \`${extractor_usecase}\` is not valid`);
value = pr['body'];
let results = [];
const list = extractor.onProperty;
// eslint-disable-next-line @typescript-eslint/prefer-for-of
for (let i = 0; i < list.length; i++) {
const prop = list[i];
let value = pr[prop];
if (value === undefined) {
core.warning(`⚠️ the provided property '${extractor.onProperty}' for \`${extractor_usecase}\` is not valid`);
value = pr['body'];
}
const values = extractValuesFromString(value, extractor);
if (values !== null) {
results = results.concat(values);
}
}
onValue = value;
return results;
}
else {
onValue = pr.body;
return extractValuesFromString(pr.body, extractor);
}
}
function extractValuesFromString(value, extractor) {
if (extractor.pattern == null) {
return null;
}
if (extractor.method === 'match') {
const lables = onValue.match(extractor.pattern);
const lables = value.match(extractor.pattern);
if (lables !== null && lables.length > 0) {
return lables.map(label => label.toLocaleLowerCase('en'));
}
}
else {
const label = onValue.replace(extractor.pattern, extractor.target);
const label = value.replace(extractor.pattern, extractor.target);
if (label !== '') {
return [label.toLocaleLowerCase('en')];
}
Generated Vendored
+1 -1
View File
File diff suppressed because one or more lines are too long
+7 -1
View File
@@ -32,7 +32,13 @@ export interface Transformer extends Regex {
}
export interface Extractor extends Transformer {
on_property?: 'title' | 'author' | 'milestone' | 'body' | undefined // retrieve the property to extract the value from
on_property?:
| ('title' | 'author' | 'milestone' | 'body')[]
| 'title'
| 'author'
| 'milestone'
| 'body'
| undefined // retrieve the property to extract the value from
method?: 'replace' | 'match' | undefined // the method to use to extract the value, `match` will not use the `target` property
on_empty?: string | undefined // in case the regex results in an empty string, this value is gonna be used instead (only for label_extractor currently)
}
+39 -12
View File
@@ -309,6 +309,13 @@ export function validateTransformer(
onEmpty = (transformer as Extractor).on_empty
}
// legacy handling, transform single value input to array
if (!Array.isArray(onProperty)) {
if (onProperty !== undefined) {
onProperty = [onProperty]
}
}
return {
pattern: new RegExp(
transformer.pattern.replace('\\\\', '\\'),
@@ -334,27 +341,47 @@ function extractValues(
return null
}
let onValue
if (extractor.onProperty !== undefined) {
let value: string = pr[extractor.onProperty]
if (value === undefined) {
core.warning(
`⚠️ the provided property '${extractor.onProperty}' for \`${extractor_usecase}\` is not valid`
)
value = pr['body']
let results: string[] = []
const list: ('title' | 'author' | 'milestone' | 'body')[] =
extractor.onProperty
// eslint-disable-next-line @typescript-eslint/prefer-for-of
for (let i = 0; i < list.length; i++) {
const prop = list[i]
let value: string = pr[prop]
if (value === undefined) {
core.warning(
`⚠️ the provided property '${extractor.onProperty}' for \`${extractor_usecase}\` is not valid`
)
value = pr['body']
}
const values = extractValuesFromString(value, extractor)
if (values !== null) {
results = results.concat(values)
}
}
onValue = value
return results
} else {
onValue = pr.body
return extractValuesFromString(pr.body, extractor)
}
}
function extractValuesFromString(
value: string,
extractor: RegexTransformer
): string[] | null {
if (extractor.pattern == null) {
return null
}
if (extractor.method === 'match') {
const lables = onValue.match(extractor.pattern)
const lables = value.match(extractor.pattern)
if (lables !== null && lables.length > 0) {
return lables.map(label => label.toLocaleLowerCase('en'))
}
} else {
const label = onValue.replace(extractor.pattern, extractor.target)
const label = value.replace(extractor.pattern, extractor.target)
if (label !== '') {
return [label.toLocaleLowerCase('en')]
}
@@ -368,7 +395,7 @@ function extractValues(
export interface RegexTransformer {
pattern: RegExp | null
target: string
onProperty?: 'title' | 'author' | 'milestone' | 'body' | undefined
onProperty?: ('title' | 'author' | 'milestone' | 'body')[] | undefined
method?: 'replace' | 'match' | undefined
onEmpty?: string | undefined
}