-
Notifications
You must be signed in to change notification settings - Fork 21
chore(ci): support independent versioning #248
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
Changes from 8 commits
0c50e44
8d5e219
b817d9c
2937162
7d3adbc
6e0aebf
5d1ef32
e778120
99c6462
eb51174
acc7b40
cc0707f
322a665
08d1e69
383a437
0975dfe
bb942af
2b81135
d16ff92
71bf7b6
29e3bee
69a1db1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,6 +9,11 @@ | |
"java": "next" | ||
}, | ||
"defaultTargetBranch": "next", | ||
"mainGenerator": { | ||
"javascript": "javascript-search", | ||
"java": "java-search", | ||
"php": "php-search" | ||
}, | ||
"gitAuthor": { | ||
"name": "api-clients-bot", | ||
"email": "[email protected]" | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,31 +1,62 @@ | ||
import { getVersionChangesText } from '../create-release-issue'; | ||
import { getVersionsToRelease, getLangsToUpdateRepo } from '../process-release'; | ||
import TEXT from '../text'; | ||
|
||
describe('process release', () => { | ||
it('gets versions to release', () => { | ||
const versions = getVersionsToRelease(` | ||
## Version Changes | ||
|
||
- [x] javascript: v1.0.0 -> v1.1.0 | ||
- [x] php: v2.0.0 -> v2.0.1 | ||
- [ ] java: v3.0.0 -> v3.0.1 | ||
- [x] javascript: v1.0.0 -> \`minor\` (e.g. v1.1.0) | ||
- [x] php: v2.0.0 -> \`patch\` (e.g. v2.0.1) | ||
- [ ] java: v3.0.0 -> \`patch\` (e.g. v3.0.1) | ||
`); | ||
|
||
expect(Object.keys(versions)).toEqual(['javascript', 'php']); | ||
expect(versions.javascript.current).toEqual('1.0.0'); | ||
expect(versions.javascript.next).toEqual('1.1.0'); | ||
expect(versions.javascript.releaseType).toEqual('minor'); | ||
expect(versions.php.current).toEqual('2.0.0'); | ||
expect(versions.php.next).toEqual('2.0.1'); | ||
expect(versions.php.releaseType).toEqual('patch'); | ||
}); | ||
|
||
it('gets langs to update', () => { | ||
expect( | ||
getLangsToUpdateRepo(` | ||
## Version Changes | ||
|
||
- [ ] javascript: v1.0.0 -> v1.1.0 | ||
- [x] php: v2.0.0 -> v2.0.1 | ||
- [ ] java: v3.0.0 -> v3.0.1 | ||
- [ ] javascript: v1.0.0 -> \`minor\` (e.g. v1.1.0) | ||
- [x] php: v2.0.0 -> \`patch\` (e.g. v2.0.1) | ||
- [ ] java: v3.0.0 -> \`patch\` (e.g. v3.0.1) | ||
`) | ||
).toEqual(['javascript', 'java']); | ||
}); | ||
|
||
it('parses parses issue body correctly', () => { | ||
eunjae-lee marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// This test is a glue between create-release-issue and process-release. | ||
const issueBody = [ | ||
shortcuts marked this conversation as resolved.
Show resolved
Hide resolved
|
||
TEXT.versionChangeHeader, | ||
getVersionChangesText({ | ||
javascript: { | ||
current: '0.0.1', | ||
releaseType: 'patch', | ||
}, | ||
php: { | ||
current: '0.0.1', | ||
releaseType: 'minor', | ||
}, | ||
java: { | ||
current: '0.0.1', | ||
releaseType: 'patch', | ||
skipRelease: true, | ||
}, | ||
}), | ||
].join('\n'); | ||
|
||
const versions = getVersionsToRelease(issueBody); | ||
expect(Object.keys(versions)).toEqual(['javascript', 'php']); | ||
expect(versions.javascript.current).toEqual('0.0.1'); | ||
expect(versions.javascript.releaseType).toEqual('patch'); | ||
expect(versions.php.current).toEqual('0.0.1'); | ||
expect(versions.php.releaseType).toEqual('minor'); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,42 +2,49 @@ | |
import { Octokit } from '@octokit/rest'; | ||
import dotenv from 'dotenv'; | ||
import semver from 'semver'; | ||
import type { ReleaseType } from 'semver'; | ||
|
||
import { GENERATORS, LANGUAGES, ROOT_ENV_PATH, run } from '../common'; | ||
import { LANGUAGES, ROOT_ENV_PATH, run, getPackageVersion } from '../common'; | ||
|
||
import { RELEASED_TAG, MAIN_BRANCH, OWNER, REPO } from './common'; | ||
import { | ||
RELEASED_TAG, | ||
MAIN_BRANCH, | ||
OWNER, | ||
REPO, | ||
MAIN_GENERATOR, | ||
} from './common'; | ||
import TEXT from './text'; | ||
|
||
dotenv.config({ path: ROOT_ENV_PATH }); | ||
|
||
type Version = { | ||
eunjae-lee marked this conversation as resolved.
Show resolved
Hide resolved
|
||
current: string; | ||
next?: string | null; | ||
noCommit?: boolean; | ||
releaseType: ReleaseType | null; | ||
skipRelease?: boolean; | ||
noCommit?: boolean; | ||
}; | ||
|
||
type Versions = { | ||
[lang: string]: Version; | ||
}; | ||
|
||
function readVersions(): Versions { | ||
const versions = {}; | ||
type VersionsWithoutReleaseType = { | ||
[lang: string]: Omit<Version, 'releaseType'>; | ||
}; | ||
|
||
Object.values(GENERATORS).forEach((gen) => { | ||
if (!versions[gen.language]) { | ||
versions[gen.language] = { | ||
current: gen.additionalProperties?.packageVersion, | ||
next: undefined, | ||
}; | ||
} | ||
}); | ||
return versions; | ||
function readVersions(): VersionsWithoutReleaseType { | ||
return Object.keys(MAIN_GENERATOR).reduce((acc, lang) => { | ||
// eslint-disable-next-line no-param-reassign | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's this one also 😇 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what a hawk eye. 69a1db1 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👀 🐦 |
||
acc[lang] = { | ||
current: getPackageVersion(lang), | ||
}; | ||
return acc; | ||
}, {}); | ||
} | ||
|
||
export function getVersionChangesText(versions: Versions): string { | ||
return LANGUAGES.map((lang) => { | ||
const { current, next, noCommit, skipRelease } = versions[lang]; | ||
const { current, releaseType, noCommit, skipRelease } = versions[lang]; | ||
|
||
if (noCommit) { | ||
return `- ~${lang}: v${current} (${TEXT.noCommit})~`; | ||
|
@@ -47,9 +54,10 @@ export function getVersionChangesText(versions: Versions): string { | |
return `- ~${lang}: (${TEXT.currentVersionNotFound})~`; | ||
} | ||
|
||
const next = semver.inc(current, releaseType!); | ||
const checked = skipRelease ? ' ' : 'x'; | ||
return [ | ||
`- [${checked}] ${lang}: v${current} -> v${next}`, | ||
`- [${checked}] ${lang}: v${current} -> \`${releaseType}\` _(e.g. v${next})_`, | ||
skipRelease && TEXT.descriptionForSkippedLang, | ||
] | ||
.filter(Boolean) | ||
|
@@ -97,54 +105,66 @@ export function parseCommit(commit: string): Commit { | |
}; | ||
} | ||
|
||
/* eslint-disable no-param-reassign */ | ||
export function decideReleaseStrategy({ | ||
versions, | ||
commits, | ||
}: { | ||
versions: Versions; | ||
versions: VersionsWithoutReleaseType; | ||
commits: PassedCommit[]; | ||
}): Versions { | ||
const ret: Versions = { ...versions }; | ||
|
||
LANGUAGES.forEach((lang) => { | ||
return Object.entries(versions).reduce((acc: Versions, [lang, version]) => { | ||
eunjae-lee marked this conversation as resolved.
Show resolved
Hide resolved
|
||
const commitsPerLang = commits.filter((commit) => commit.lang === lang); | ||
const currentVersion = versions[lang].current; | ||
|
||
if (commitsPerLang.length === 0) { | ||
ret[lang].next = currentVersion; | ||
ret[lang].noCommit = true; | ||
return; | ||
acc[lang] = { | ||
...version, | ||
noCommit: true, | ||
releaseType: null, | ||
}; | ||
return acc; | ||
} | ||
|
||
if (semver.prerelease(currentVersion)) { | ||
// if version is like 0.1.2-beta.1, it increases to 0.1.2-beta.2, even if there's a breaking change. | ||
ret[lang].next = semver.inc(currentVersion, 'prerelease'); | ||
return; | ||
acc[lang] = { | ||
...version, | ||
releaseType: 'prerelease', | ||
}; | ||
return acc; | ||
} | ||
|
||
if ( | ||
commitsPerLang.some((commit) => | ||
commit.message.includes('BREAKING CHANGE') | ||
) | ||
) { | ||
ret[lang].next = semver.inc(currentVersion, 'major'); | ||
return; | ||
acc[lang] = { | ||
...version, | ||
releaseType: 'major', | ||
}; | ||
return acc; | ||
} | ||
|
||
const commitTypes = new Set(commitsPerLang.map(({ type }) => type)); | ||
if (commitTypes.has('feat')) { | ||
ret[lang].next = semver.inc(currentVersion, 'minor'); | ||
return; | ||
} | ||
|
||
ret[lang].next = semver.inc(currentVersion, 'patch'); | ||
if (!commitTypes.has('fix')) { | ||
ret[lang].skipRelease = true; | ||
acc[lang] = { | ||
...version, | ||
releaseType: 'minor', | ||
}; | ||
return acc; | ||
} | ||
}); | ||
|
||
return ret; | ||
acc[lang] = { | ||
...version, | ||
releaseType: 'patch', | ||
...(commitTypes.has('fix') ? undefined : { skipRelease: true }), | ||
}; | ||
return acc; | ||
}, {}); | ||
} | ||
/* eslint-enable no-param-reassign */ | ||
|
||
async function createReleaseIssue(): Promise<void> { | ||
if (!process.env.GITHUB_TOKEN) { | ||
|
@@ -241,6 +261,7 @@ async function createReleaseIssue(): Promise<void> { | |
TEXT.versionChangeHeader, | ||
versionChanges, | ||
TEXT.descriptionVersionChanges, | ||
TEXT.indenpendentVersioning, | ||
TEXT.changelogHeader, | ||
TEXT.changelogDescription, | ||
changelogs, | ||
|
@@ -270,6 +291,7 @@ async function createReleaseIssue(): Promise<void> { | |
}); | ||
} | ||
|
||
// JS version of `if __name__ == '__main__'` | ||
if (require.main === module) { | ||
createReleaseIssue(); | ||
} |
Uh oh!
There was an error while loading. Please reload this page.