- provide alternative method to sort tags
- introduce option configuration allowing to specify which method to pick - semver (default) - alphabetical sort order (sort)
This commit is contained in:
+40
-4
@@ -2,7 +2,7 @@ import { resolveConfiguration } from '../src/utils';
|
|||||||
import { ReleaseNotesBuilder } from '../src/releaseNotesBuilder';
|
import { ReleaseNotesBuilder } from '../src/releaseNotesBuilder';
|
||||||
import { TagInfo, sortTags } from '../src/tags';
|
import { TagInfo, sortTags } from '../src/tags';
|
||||||
|
|
||||||
it('Should order tags correctly', async () => {
|
it('Should order tags correctly using semver', async () => {
|
||||||
jest.setTimeout(180000)
|
jest.setTimeout(180000)
|
||||||
|
|
||||||
const tags: TagInfo[] = [
|
const tags: TagInfo[] = [
|
||||||
@@ -16,7 +16,10 @@ it('Should order tags correctly', async () => {
|
|||||||
{ name: "v2020.3.0", commit: "" }
|
{ name: "v2020.3.0", commit: "" }
|
||||||
]
|
]
|
||||||
|
|
||||||
const sorted = sortTags(tags).map(function (tag) {
|
const tagResolver = {
|
||||||
|
method: "semver"
|
||||||
|
}
|
||||||
|
const sorted = sortTags(tags, tagResolver).map(function (tag) {
|
||||||
return tag.name
|
return tag.name
|
||||||
}).join(",")
|
}).join(",")
|
||||||
|
|
||||||
@@ -24,7 +27,7 @@ it('Should order tags correctly', async () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
it('Should order tags correctly', async () => {
|
it('Should order tags correctly using semver', async () => {
|
||||||
jest.setTimeout(180000)
|
jest.setTimeout(180000)
|
||||||
|
|
||||||
const tags: TagInfo[] = [
|
const tags: TagInfo[] = [
|
||||||
@@ -43,9 +46,42 @@ it('Should order tags correctly', async () => {
|
|||||||
{ name: "1000.0.0", commit: "" },
|
{ name: "1000.0.0", commit: "" },
|
||||||
]
|
]
|
||||||
|
|
||||||
const sorted = sortTags(tags).map(function (tag) {
|
const tagResolver = {
|
||||||
|
method: "non-existing-method"
|
||||||
|
}
|
||||||
|
const sorted = sortTags(tags, tagResolver).map(function (tag) {
|
||||||
return tag.name
|
return tag.name
|
||||||
}).join(",")
|
}).join(",")
|
||||||
|
|
||||||
expect(sorted).toStrictEqual(`1000.0.0,100.0.0,20.0.2,10.1.0,10.1.0-2,10.0.0,2.0.0,1.0.0,1.0.0-a01,0.1.0,0.1.0-b01,0.0.1,0.0.1-rc01`)
|
expect(sorted).toStrictEqual(`1000.0.0,100.0.0,20.0.2,10.1.0,10.1.0-2,10.0.0,2.0.0,1.0.0,1.0.0-a01,0.1.0,0.1.0-b01,0.0.1,0.0.1-rc01`)
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
it('Should order tags alphabetical', async () => {
|
||||||
|
jest.setTimeout(180000)
|
||||||
|
|
||||||
|
const tags: TagInfo[] = [
|
||||||
|
{ name: "0.0.1", commit: "" },
|
||||||
|
{ name: "0.0.1-rc01", commit: "" },
|
||||||
|
{ name: "0.1.0-b01", commit: "" },
|
||||||
|
{ name: "1.0.0", commit: "" },
|
||||||
|
{ name: "a", commit: "" },
|
||||||
|
{ name: "1.0.0-a01", commit: "" },
|
||||||
|
{ name: "2.0.0", commit: "" },
|
||||||
|
{ name: "10.0.0", commit: "" },
|
||||||
|
{ name: "v1", commit: "" },
|
||||||
|
{ name: "10.1.0", commit: "" },
|
||||||
|
{ name: "10.1.0-2", commit: "" },
|
||||||
|
{ name: "20.0.2", commit: "" },
|
||||||
|
{ name: "1000.0.0", commit: "" },
|
||||||
|
]
|
||||||
|
|
||||||
|
const tagResolver = {
|
||||||
|
method: "sort"
|
||||||
|
}
|
||||||
|
const sorted = sortTags(tags, tagResolver).map(function (tag) {
|
||||||
|
return tag.name
|
||||||
|
}).join(",")
|
||||||
|
|
||||||
|
expect(sorted).toStrictEqual(`a,20.0.2,2.0.0,1000.0.0,10.1.0,10.1.0-2,10.0.0,1.0.0,1.0.0-a01,v1,0.1.0-b01,0.0.1,0.0.1-rc01`)
|
||||||
})
|
})
|
||||||
+10
-1
@@ -9,6 +9,7 @@ export interface Configuration {
|
|||||||
empty_template: string
|
empty_template: string
|
||||||
categories: Category[]
|
categories: Category[]
|
||||||
transformers: Transformer[]
|
transformers: Transformer[]
|
||||||
|
tag_resolver: TagResolver
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Category {
|
export interface Category {
|
||||||
@@ -21,6 +22,10 @@ export interface Transformer {
|
|||||||
target: string
|
target: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface TagResolver {
|
||||||
|
method: string // semver, sort
|
||||||
|
}
|
||||||
|
|
||||||
export const DefaultConfiguration: Configuration = {
|
export const DefaultConfiguration: Configuration = {
|
||||||
max_tags_to_fetch: 200, // the amount of tags to fetch from the github API
|
max_tags_to_fetch: 200, // the amount of tags to fetch from the github API
|
||||||
max_pull_requests: 200, // the amount of pull requests to process
|
max_pull_requests: 200, // the amount of pull requests to process
|
||||||
@@ -44,5 +49,9 @@ export const DefaultConfiguration: Configuration = {
|
|||||||
labels: ['test']
|
labels: ['test']
|
||||||
}
|
}
|
||||||
], // the categories to support for the ordering
|
], // the categories to support for the ordering
|
||||||
transformers: [] // transformers to apply on the PR description according to the `pr_template`
|
transformers: [], // transformers to apply on the PR description according to the `pr_template`
|
||||||
|
tag_resolver: {
|
||||||
|
// defines the logic on how to resolve the previous tag, only relevant if `fromTag` is not specified
|
||||||
|
method: 'semver' // defines which method to use, by default it will use `semver` (dropping all non matching tags). Alternative `sort` is also available.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,7 +83,8 @@ export class ReleaseNotesBuilder {
|
|||||||
this.toTag,
|
this.toTag,
|
||||||
this.ignorePreReleases,
|
this.ignorePreReleases,
|
||||||
this.configuration.max_tags_to_fetch ||
|
this.configuration.max_tags_to_fetch ||
|
||||||
DefaultConfiguration.max_tags_to_fetch
|
DefaultConfiguration.max_tags_to_fetch,
|
||||||
|
this.configuration.tag_resolver || DefaultConfiguration.tag_resolver
|
||||||
)
|
)
|
||||||
if (previousTag == null) {
|
if (previousTag == null) {
|
||||||
failOrError(
|
failOrError(
|
||||||
|
|||||||
+39
-5
@@ -2,6 +2,7 @@ import {Octokit, RestEndpointMethodTypes} from '@octokit/rest'
|
|||||||
import * as core from '@actions/core'
|
import * as core from '@actions/core'
|
||||||
import * as semver from 'semver'
|
import * as semver from 'semver'
|
||||||
import {SemVer} from 'semver'
|
import {SemVer} from 'semver'
|
||||||
|
import {TagResolver} from './configuration'
|
||||||
|
|
||||||
export interface TagInfo {
|
export interface TagInfo {
|
||||||
name: string
|
name: string
|
||||||
@@ -52,9 +53,13 @@ export class Tags {
|
|||||||
repo: string,
|
repo: string,
|
||||||
tag: string,
|
tag: string,
|
||||||
ignorePreReleases: boolean,
|
ignorePreReleases: boolean,
|
||||||
maxTagsToFetch: number
|
maxTagsToFetch: number,
|
||||||
|
tagResolver: TagResolver
|
||||||
): Promise<TagInfo | null> {
|
): Promise<TagInfo | null> {
|
||||||
const tags = sortTags(await this.getTags(owner, repo, maxTagsToFetch))
|
const tags = sortTags(
|
||||||
|
await this.getTags(owner, repo, maxTagsToFetch),
|
||||||
|
tagResolver
|
||||||
|
)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const length = tags.length
|
const length = tags.length
|
||||||
@@ -94,12 +99,22 @@ export class Tags {
|
|||||||
2020.3.1-a01
|
2020.3.1-a01
|
||||||
2020.3.0
|
2020.3.0
|
||||||
*/
|
*/
|
||||||
export function sortTags(tags: TagInfo[]): TagInfo[] {
|
export function sortTags(tags: TagInfo[], tagResolver: TagResolver): TagInfo[] {
|
||||||
|
if (tagResolver.method === 'sort') {
|
||||||
|
return stringSorting(tags)
|
||||||
|
} else {
|
||||||
|
return semVerSorting(tags)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function semVerSorting(tags: TagInfo[]): TagInfo[] {
|
||||||
// filter out tags which do not follow semver
|
// filter out tags which do not follow semver
|
||||||
const validatedTags = tags.filter(tag => {
|
const validatedTags = tags.filter(tag => {
|
||||||
const isValid = semver.valid(tag.name) !== null
|
const isValid = semver.valid(tag.name) !== null
|
||||||
if(!isValid) {
|
if (!isValid) {
|
||||||
core.debug(`⚠️ dropped tag ${tag.name} because it is not a valid semver tag`)
|
core.debug(
|
||||||
|
`⚠️ dropped tag ${tag.name} because it is not a valid semver tag`
|
||||||
|
)
|
||||||
}
|
}
|
||||||
return isValid
|
return isValid
|
||||||
})
|
})
|
||||||
@@ -110,3 +125,22 @@ export function sortTags(tags: TagInfo[]): TagInfo[] {
|
|||||||
})
|
})
|
||||||
return validatedTags
|
return validatedTags
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function stringSorting(tags: TagInfo[]): TagInfo[] {
|
||||||
|
return tags.sort((b, a) => {
|
||||||
|
const partsA = a.name.replace(/^v/, '').split('-')
|
||||||
|
const partsB = b.name.replace(/^v/, '').split('-')
|
||||||
|
const versionCompare = partsA[0].localeCompare(partsB[0])
|
||||||
|
if (versionCompare !== 0) {
|
||||||
|
return versionCompare
|
||||||
|
} else {
|
||||||
|
if (partsA.length === 1) {
|
||||||
|
return 0
|
||||||
|
} else if (partsB.length === 1) {
|
||||||
|
return 1
|
||||||
|
} else {
|
||||||
|
return partsA[1].localeCompare(partsB[1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user