@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.
@@ -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,7 @@
1
+ import { execa } from 'execa';
2
+ function gitShow(revision, filePath, cwd) {
3
+ return execa('git', ['show', `${revision}:${filePath}`], {
4
+ cwd,
5
+ }).then(({ stdout }) => stdout);
6
+ }
7
+ export { gitShow };
@@ -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,7 @@
1
+ async function isUrlHealthy(testUrl) {
2
+ const response = await fetch(testUrl, {
3
+ method: 'HEAD',
4
+ });
5
+ return response.ok;
6
+ }
7
+ export { isUrlHealthy };
@@ -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-pkg-up';
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
- dependenciesChangelogEntries = result.trim();
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.0",
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-pkg-up": "^10.1.0",
23
+ "read-package-up": "^11.0.0",
22
24
  "semver": "^7.5.4",
23
- "update-notifier": "^6.0.2"
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.2",
30
- "@types/jest": "^29.5.5",
31
- "@types/node": "^18.15.11",
32
- "@types/semver": "^7.5.3",
33
- "@types/update-notifier": "^6.0.2",
34
- "@typescript-eslint/eslint-plugin": "^6.7.5",
35
- "@typescript-eslint/parser": "^6.7.5",
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.51.0",
40
+ "eslint": "^8.53.0",
38
41
  "eslint-config-prettier": "^9.0.0",
39
- "eslint-plugin-prettier": "^5.0.0",
42
+ "eslint-plugin-prettier": "^5.0.1",
40
43
  "jest": "^29.7.0",
41
44
  "ts-jest": "^29.1.1",
42
- "typescript": "^5.0.3"
45
+ "typescript": "^5.2.2"
43
46
  },
44
47
  "directories": {
45
48
  "test": "test"
46
49
  },
47
50
  "engines": {
48
- "node": ">=18",
49
- "npm": ">=8"
51
+ "node": ">=20",
52
+ "npm": ">=10"
50
53
  },
51
54
  "files": [
52
55
  "dist",