@oneblink/release-cli 2.1.0 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/package-diff-summary/diff.js +78 -0
- package/dist/package-diff-summary/git.js +7 -0
- package/dist/package-diff-summary/github.js +37 -0
- package/dist/package-diff-summary/http.js +7 -0
- package/dist/package-diff-summary/index.js +13 -0
- package/dist/package-diff-summary/npm.js +27 -0
- package/dist/startReleaseProcess.js +5 -3
- package/package.json +19 -16
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import os from 'os';
|
|
2
|
+
import depDiff from 'dependency-diff';
|
|
3
|
+
import semver from 'semver';
|
|
4
|
+
import * as npm from './npm.js';
|
|
5
|
+
// http://semver.org/#spec-item-9
|
|
6
|
+
// 1.0.0, 1.0.0-foo1, 1.0.0-foo1.blah2, 1.0.0-foo1.blah2.abc3, ...
|
|
7
|
+
const VERSION_REGEXP = /\d+\.\d+\.\d+(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?/;
|
|
8
|
+
function lineForDelete(nameMd) {
|
|
9
|
+
return `- no longer depend upon ${nameMd}`;
|
|
10
|
+
}
|
|
11
|
+
function lineForNew(nameMd, versionMd) {
|
|
12
|
+
return `- depend upon ${nameMd} ${versionMd}`;
|
|
13
|
+
}
|
|
14
|
+
function lineForRollback(nameMd, versionMd, oldVersionMd) {
|
|
15
|
+
return `- rollback ${nameMd} to ${versionMd} (from ${oldVersionMd})`;
|
|
16
|
+
}
|
|
17
|
+
function lineForUpdate(nameMd, versionMd, oldVersionMd) {
|
|
18
|
+
return `- update ${nameMd} to ${versionMd} (from ${oldVersionMd})`;
|
|
19
|
+
}
|
|
20
|
+
// strips any sloppy / range characters, e.g. ^ or >=
|
|
21
|
+
function strictVersion(version) {
|
|
22
|
+
const [versionNumbers] = version.match(VERSION_REGEXP) || [];
|
|
23
|
+
return versionNumbers || '';
|
|
24
|
+
}
|
|
25
|
+
function versionToMarkdown(version, // assumed strict, no sloppy / range, etc
|
|
26
|
+
changelogUrl) {
|
|
27
|
+
if (changelogUrl) {
|
|
28
|
+
return `[${version}](${changelogUrl})`;
|
|
29
|
+
}
|
|
30
|
+
return version;
|
|
31
|
+
}
|
|
32
|
+
function wrapWithEol(text) {
|
|
33
|
+
return os.EOL + text + os.EOL;
|
|
34
|
+
}
|
|
35
|
+
function deltaToMarkdown(diff, oldPkg, cwd) {
|
|
36
|
+
const oldDependencies = oldPkg.dependencies || {};
|
|
37
|
+
const depDeltas = diff.dependencies || [];
|
|
38
|
+
// serial iteration with Promises
|
|
39
|
+
return depDeltas.reduce((promise, depDelta) => {
|
|
40
|
+
const { name, operation, version: versionRange } = depDelta;
|
|
41
|
+
const version = strictVersion(versionRange);
|
|
42
|
+
let oldVersionRange, oldVersion;
|
|
43
|
+
if (operation === 'edit') {
|
|
44
|
+
oldVersionRange = oldDependencies[name];
|
|
45
|
+
oldVersion = strictVersion(oldVersionRange);
|
|
46
|
+
}
|
|
47
|
+
return Promise.all([
|
|
48
|
+
npm.nameToMarkdown(name),
|
|
49
|
+
npm.changelogUrlFor(name, cwd),
|
|
50
|
+
npm.releaseUrlFor(name, version, cwd),
|
|
51
|
+
oldVersion && npm.releaseUrlFor(name, oldVersion, cwd),
|
|
52
|
+
promise, // -> result
|
|
53
|
+
]).then(([nameMd, changelogUrl, releaseUrl, oldReleaseUrl, result]) => {
|
|
54
|
+
const versionMd = versionToMarkdown(version, releaseUrl || changelogUrl);
|
|
55
|
+
if (operation === 'delete') {
|
|
56
|
+
return result + wrapWithEol(lineForDelete(nameMd));
|
|
57
|
+
}
|
|
58
|
+
if (operation === 'new') {
|
|
59
|
+
return result + wrapWithEol(lineForNew(nameMd, versionMd));
|
|
60
|
+
}
|
|
61
|
+
if (operation === 'edit' && oldVersion) {
|
|
62
|
+
const oldVersionMd = versionToMarkdown(oldVersion, oldReleaseUrl || changelogUrl);
|
|
63
|
+
if (oldVersion && semver.lt(oldVersion, version)) {
|
|
64
|
+
return (result + wrapWithEol(lineForUpdate(nameMd, versionMd, oldVersionMd)));
|
|
65
|
+
}
|
|
66
|
+
if (oldVersion && semver.gt(oldVersion, version)) {
|
|
67
|
+
return (result +
|
|
68
|
+
wrapWithEol(lineForRollback(nameMd, versionMd, oldVersionMd)));
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return result;
|
|
72
|
+
});
|
|
73
|
+
}, Promise.resolve(os.EOL));
|
|
74
|
+
}
|
|
75
|
+
function diffPackages(oldPkg, pkg) {
|
|
76
|
+
return depDiff().left(oldPkg).right(pkg).toObject();
|
|
77
|
+
}
|
|
78
|
+
export { deltaToMarkdown, diffPackages, versionToMarkdown };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Octokit } from '@octokit/rest';
|
|
2
|
+
import githubUrlFrom from 'github-url-from-git';
|
|
3
|
+
import * as http from './http.js';
|
|
4
|
+
import * as npm from './npm.js';
|
|
5
|
+
const octokit = new Octokit({
|
|
6
|
+
auth: process.env.GITHUB_OAUTH_TOKEN,
|
|
7
|
+
});
|
|
8
|
+
function changelogUrlAt(projectUrl) {
|
|
9
|
+
const changelogUrl = projectUrl + '/blob/master/CHANGELOG.md';
|
|
10
|
+
return http
|
|
11
|
+
.isUrlHealthy(changelogUrl)
|
|
12
|
+
.then((yes) => (yes ? changelogUrl : ''));
|
|
13
|
+
}
|
|
14
|
+
function projectUrlFor(name, cwd) {
|
|
15
|
+
return npm.repositoryUrlFor(name, cwd).then(githubUrlFrom);
|
|
16
|
+
}
|
|
17
|
+
function releaseUrlFor(projectUrl, version) {
|
|
18
|
+
const [owner, repo] = projectUrl.split('/').slice(-2);
|
|
19
|
+
const variations = [version, 'v' + version];
|
|
20
|
+
// iterate serially to be friendlier to the GitHub API
|
|
21
|
+
return variations
|
|
22
|
+
.reduce((promise, variation) => {
|
|
23
|
+
return promise.then((results) => {
|
|
24
|
+
return (octokit.rest.repos
|
|
25
|
+
.getReleaseByTag({ owner, repo, tag: variation })
|
|
26
|
+
.then((release) => {
|
|
27
|
+
// add this result to the array we're accumulating
|
|
28
|
+
return results.concat([release]);
|
|
29
|
+
})
|
|
30
|
+
// no result, just return the accumulated array so far
|
|
31
|
+
.catch(() => results));
|
|
32
|
+
});
|
|
33
|
+
}, Promise.resolve([]))
|
|
34
|
+
.then((results) => results.filter((result) => !!result)[0])
|
|
35
|
+
.then((release) => release && release.data && release.data.html_url);
|
|
36
|
+
}
|
|
37
|
+
export { changelogUrlAt, projectUrlFor, releaseUrlFor };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { readPackageUp } from 'read-package-up';
|
|
2
|
+
import * as git from './git.js';
|
|
3
|
+
import * as diff from './diff.js';
|
|
4
|
+
async function main({ previousVersion, cwd, }) {
|
|
5
|
+
const oldPkg = JSON.parse(await git.gitShow(previousVersion, 'package.json', cwd));
|
|
6
|
+
const result = await readPackageUp({ cwd });
|
|
7
|
+
if (result) {
|
|
8
|
+
const delta = diff.diffPackages(oldPkg, result.packageJson);
|
|
9
|
+
const text = await diff.deltaToMarkdown(delta, oldPkg, cwd); // CLI tool, relax!
|
|
10
|
+
return text;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export { main };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { execa } from 'execa';
|
|
2
|
+
import * as http from './http.js';
|
|
3
|
+
import * as github from './github.js';
|
|
4
|
+
function changelogUrlFor(name, cwd) {
|
|
5
|
+
return github
|
|
6
|
+
.projectUrlFor(name, cwd)
|
|
7
|
+
.then((projectUrl) => (projectUrl ? github.changelogUrlAt(projectUrl) : ''));
|
|
8
|
+
}
|
|
9
|
+
function nameToMarkdown(name) {
|
|
10
|
+
const pkgUrl = 'https://www.npmjs.com/package/' + name;
|
|
11
|
+
return http
|
|
12
|
+
.isUrlHealthy(pkgUrl)
|
|
13
|
+
.then((yes) => (yes ? `[${name}](${pkgUrl})` : name));
|
|
14
|
+
}
|
|
15
|
+
function releaseUrlFor(name, version, cwd) {
|
|
16
|
+
return github
|
|
17
|
+
.projectUrlFor(name, cwd)
|
|
18
|
+
.then((projectUrl) => projectUrl ? github.releaseUrlFor(projectUrl, version) : '');
|
|
19
|
+
}
|
|
20
|
+
function repositoryUrlFor(name, cwd) {
|
|
21
|
+
return execa('npm', ['view', name, 'repository.url'], {
|
|
22
|
+
cwd,
|
|
23
|
+
})
|
|
24
|
+
.then(({ stdout }) => stdout)
|
|
25
|
+
.catch(() => '');
|
|
26
|
+
}
|
|
27
|
+
export { changelogUrlFor, nameToMarkdown, releaseUrlFor, repositoryUrlFor };
|
|
@@ -4,10 +4,10 @@ import util from 'util';
|
|
|
4
4
|
import { execa } from 'execa';
|
|
5
5
|
import prettier from 'prettier';
|
|
6
6
|
import parseChangelog from 'changelog-parser';
|
|
7
|
-
import { main as packageDiffSummary } from 'package-diff-summary';
|
|
7
|
+
import { main as packageDiffSummary } from './package-diff-summary/index.js';
|
|
8
8
|
import semver from 'semver';
|
|
9
9
|
import ora from 'ora';
|
|
10
|
-
import { readPackageUp } from 'read-
|
|
10
|
+
import { readPackageUp } from 'read-package-up';
|
|
11
11
|
const readFileAsync = util.promisify(fs.readFile);
|
|
12
12
|
const writeFileAsync = util.promisify(fs.writeFile);
|
|
13
13
|
const UNRELEASED_VERSION_INDEX = 0;
|
|
@@ -62,7 +62,9 @@ async function updateChangelog({ nextSemverVersion, cwd, releaseName, }) {
|
|
|
62
62
|
cwd,
|
|
63
63
|
previousVersion: lastGitTag,
|
|
64
64
|
});
|
|
65
|
-
|
|
65
|
+
if (result) {
|
|
66
|
+
dependenciesChangelogEntries = result.trim();
|
|
67
|
+
}
|
|
66
68
|
}
|
|
67
69
|
catch (error) {
|
|
68
70
|
if (error.message.includes(`git show ${lastGitTag}:package.json`)) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oneblink/release-cli",
|
|
3
3
|
"description": "Used internally by OneBlink to release code bases quickly and consistently",
|
|
4
|
-
"version": "2.1.
|
|
4
|
+
"version": "2.1.1",
|
|
5
5
|
"author": "OneBlink <developers@oneblink> (https://github.com/oneblink)",
|
|
6
6
|
"bin": {
|
|
7
7
|
"oneblink-release": "dist/bin.js"
|
|
@@ -10,43 +10,46 @@
|
|
|
10
10
|
"url": "https://github.com/oneblink/release-cli/issues"
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
|
+
"@octokit/rest": "^20.0.2",
|
|
13
14
|
"changelog-parser": "^3.0.1",
|
|
15
|
+
"dependency-diff": "^1.0.4",
|
|
14
16
|
"enquirer": "^2.4.1",
|
|
15
17
|
"execa": "^8.0.1",
|
|
18
|
+
"github-url-from-git": "^1.5.0",
|
|
16
19
|
"meow": "^12.1.1",
|
|
17
20
|
"ora": "^7.0.1",
|
|
18
|
-
"package-diff-summary": "^3.0.1",
|
|
19
21
|
"patch-package": "^8.0.0",
|
|
20
22
|
"prettier": "^3.0.3",
|
|
21
|
-
"read-
|
|
23
|
+
"read-package-up": "^11.0.0",
|
|
22
24
|
"semver": "^7.5.4",
|
|
23
|
-
"update-notifier": "^
|
|
25
|
+
"update-notifier": "^7.0.0"
|
|
24
26
|
},
|
|
25
27
|
"bundleDependencies": [
|
|
26
28
|
"changelog-parser"
|
|
27
29
|
],
|
|
28
30
|
"devDependencies": {
|
|
29
|
-
"@types/changelog-parser": "^2.8.
|
|
30
|
-
"@types/
|
|
31
|
-
"@types/
|
|
32
|
-
"@types/
|
|
33
|
-
"@types/
|
|
34
|
-
"@
|
|
35
|
-
"@typescript-eslint/
|
|
31
|
+
"@types/changelog-parser": "^2.8.3",
|
|
32
|
+
"@types/github-url-from-git": "^1.5.2",
|
|
33
|
+
"@types/jest": "^29.5.7",
|
|
34
|
+
"@types/node": "^20.8.10",
|
|
35
|
+
"@types/semver": "^7.5.4",
|
|
36
|
+
"@types/update-notifier": "^6.0.6",
|
|
37
|
+
"@typescript-eslint/eslint-plugin": "^6.10.0",
|
|
38
|
+
"@typescript-eslint/parser": "^6.10.0",
|
|
36
39
|
"cross-env": "^7.0.3",
|
|
37
|
-
"eslint": "^8.
|
|
40
|
+
"eslint": "^8.53.0",
|
|
38
41
|
"eslint-config-prettier": "^9.0.0",
|
|
39
|
-
"eslint-plugin-prettier": "^5.0.
|
|
42
|
+
"eslint-plugin-prettier": "^5.0.1",
|
|
40
43
|
"jest": "^29.7.0",
|
|
41
44
|
"ts-jest": "^29.1.1",
|
|
42
|
-
"typescript": "^5.
|
|
45
|
+
"typescript": "^5.2.2"
|
|
43
46
|
},
|
|
44
47
|
"directories": {
|
|
45
48
|
"test": "test"
|
|
46
49
|
},
|
|
47
50
|
"engines": {
|
|
48
|
-
"node": ">=
|
|
49
|
-
"npm": ">=
|
|
51
|
+
"node": ">=20",
|
|
52
|
+
"npm": ">=10"
|
|
50
53
|
},
|
|
51
54
|
"files": [
|
|
52
55
|
"dist",
|