npm-update-package 0.10.0 → 0.12.0

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/README.md CHANGED
@@ -9,31 +9,44 @@ CLI tool for creating pull request to update npm packages
9
9
 
10
10
  This package is currently under development, so the major version is 0 yet.
11
11
 
12
- ## Installation
12
+ ## Requirements
13
13
 
14
- If you are using npm:
14
+ - Git v2.23.0 or higher
15
15
 
16
- ```sh
17
- npm i -g npm-update-package
18
- ```
19
-
20
- If you are using Yarn:
16
+ ## Usage
21
17
 
22
18
  ```sh
23
- yarn global add npm-update-package
19
+ npx npm-update-package --github-token $GITHUB_TOKEN
24
20
  ```
25
21
 
26
- Or, you can use [npx](https://docs.npmjs.com/cli/v8/commands/npx).
27
-
28
- ```sh
29
- npx npm-update-package
22
+ ## Examples
23
+
24
+ Example of running npm-update-package on GitHub Actions at 0:00 (UTC) every day:
25
+
26
+ ```yaml
27
+ name: npm-update-package
28
+ on:
29
+ schedule:
30
+ - cron: '0 0 * * *'
31
+ jobs:
32
+ npm-update-package:
33
+ runs-on: ubuntu-latest
34
+ steps:
35
+ - uses: actions/checkout@v2
36
+ - uses: actions/setup-node@v2
37
+ - run: |
38
+ git config user.name $GIT_USER_NAME
39
+ git config user.email $GIT_USER_EMAIL
40
+ npx npm-update-package --github-token $GITHUB_TOKEN
41
+ env:
42
+ GIT_USER_EMAIL: 41898282+github-actions[bot]@users.noreply.github.com
43
+ GIT_USER_NAME: github-actions[bot]
44
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
30
45
  ```
31
46
 
32
- ## Usage
47
+ Actual working examples can be seen in these repositories.
33
48
 
34
- ```sh
35
- npm-update-package --github-token $GITHUB_TOKEN
36
- ```
49
+ - [npm-update-package/example-npm](https://github.com/npm-update-package/example-npm)
37
50
 
38
51
  ## Options
39
52
 
@@ -45,7 +58,7 @@ Template strings such as `--branch-name` can embed variables like `{{packageName
45
58
  Branch name template
46
59
 
47
60
  - value: template string
48
- - embeddable variables:
61
+ - variables:
49
62
  - `currentVersion`
50
63
  - `newVersion`
51
64
  - `packageName`
@@ -58,7 +71,7 @@ Branch name template
58
71
  Commit message template
59
72
 
60
73
  - value: template string
61
- - embeddable variables:
74
+ - variables:
62
75
  - `currentVersion`
63
76
  - `newVersion`
64
77
  - `packageName`
@@ -78,6 +91,7 @@ GitHub token
78
91
  Log level to show
79
92
 
80
93
  - value: string
94
+ - `error`
81
95
  - `info`
82
96
  - `debug`
83
97
  - required: false
@@ -98,7 +112,7 @@ Package manager of your project
98
112
  Pull request body template
99
113
 
100
114
  - value: template string
101
- - embeddable variables:
115
+ - variables:
102
116
  - `appName`
103
117
  - `appVersion`
104
118
  - `appWeb`
@@ -125,7 +139,7 @@ This PR has been generated by [{{{appName}}}]({{{appWeb}}}) v{{appVersion}}
125
139
  Pull request title template
126
140
 
127
141
  - value: template string
128
- - embeddable variables:
142
+ - variables:
129
143
  - `currentVersion`
130
144
  - `newVersion`
131
145
  - `packageName`
package/dist/app.js CHANGED
@@ -3,6 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.app = void 0;
4
4
  exports.app = {
5
5
  name: 'npm-update-package',
6
- version: '0.10.0',
6
+ version: '0.12.0',
7
7
  web: 'https://github.com/npm-update-package/npm-update-package'
8
8
  };
package/dist/bin.js CHANGED
@@ -12,8 +12,10 @@ logger.info(`Start ${app_1.app.name} v${app_1.app.version}`);
12
12
  options,
13
13
  logger
14
14
  })
15
- .then(() => logger.info(`End ${app_1.app.name} v${app_1.app.version}`))
16
- .catch((e) => {
17
- // TODO: improve error handling
18
- logger.fatal('Unexpected error has occurred.', e);
15
+ .then(() => {
16
+ logger.info(`End ${app_1.app.name} v${app_1.app.version}`);
17
+ })
18
+ .catch((error) => {
19
+ logger.fatal(error);
20
+ throw error;
19
21
  });
package/dist/git/Git.js CHANGED
@@ -10,14 +10,11 @@ class Git {
10
10
  async add(...files) {
11
11
  await this.terminal.run('git', 'add', ...files);
12
12
  }
13
- async checkout(branchName) {
14
- await this.terminal.run('git', 'checkout', branchName);
15
- }
16
13
  async commit(message) {
17
14
  await this.terminal.run('git', 'commit', '--message', message);
18
15
  }
19
16
  async createBranch(branchName) {
20
- await this.terminal.run('git', 'checkout', '-b', branchName);
17
+ await this.terminal.run('git', 'switch', '-c', branchName);
21
18
  }
22
19
  async getConfig(key) {
23
20
  const { stdout } = await this.terminal.run('git', 'config', key);
@@ -41,8 +38,14 @@ class Git {
41
38
  async removeBranch(branchName) {
42
39
  await this.terminal.run('git', 'branch', '-D', branchName);
43
40
  }
41
+ async restore(...files) {
42
+ await this.terminal.run('git', 'restore', '--worktree', '--staged', ...files);
43
+ }
44
44
  async setConfig(key, value) {
45
45
  await this.terminal.run('git', 'config', key, value);
46
46
  }
47
+ async switch(branchName) {
48
+ await this.terminal.run('git', 'switch', branchName);
49
+ }
47
50
  }
48
51
  exports.Git = Git;
@@ -2,8 +2,9 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.isLogLevel = exports.LogLevel = void 0;
4
4
  exports.LogLevel = {
5
- Info: 'info',
6
- Debug: 'debug'
5
+ Debug: 'debug',
6
+ Error: 'error',
7
+ Info: 'info'
7
8
  };
8
9
  const logLevels = Object.values(exports.LogLevel);
9
10
  const isLogLevel = (value) => logLevels.includes(value);
package/dist/main.js CHANGED
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.main = void 0;
4
+ const Either_1 = require("fp-ts/lib/Either");
4
5
  const git_1 = require("./git");
5
6
  const github_1 = require("./github");
6
7
  const ncu_1 = require("./ncu");
@@ -75,14 +76,24 @@ const main = async ({ options, logger }) => {
75
76
  });
76
77
  const results = await outdatedPackagesProcessor.process(outdatedPackages);
77
78
  logger.debug(`results=${JSON.stringify(results)}`);
78
- const updatedPackages = results
79
+ const succeededResults = results.filter(Either_1.isRight).map(({ right }) => right);
80
+ logger.debug(`succeededResults=${JSON.stringify(succeededResults)}`);
81
+ const updatedPackages = succeededResults
79
82
  .filter(({ updated }) => updated)
80
83
  .map(({ outdatedPackage }) => outdatedPackage);
81
84
  logger.debug(`updatedPackages=${JSON.stringify(updatedPackages)}`);
82
- const skippedPackages = results
85
+ const skippedPackages = succeededResults
83
86
  .filter(({ skipped }) => skipped)
84
87
  .map(({ outdatedPackage }) => outdatedPackage);
85
88
  logger.debug(`skippedPackages=${JSON.stringify(skippedPackages)}`);
86
- logger.info(`${updatedPackages.length} packages has updated. ${skippedPackages.length} packages has skipped.`);
89
+ const failedResults = results.filter(Either_1.isLeft).map(({ left }) => left);
90
+ logger.debug(`failedResults=${JSON.stringify(failedResults)}`);
91
+ const failedPackages = failedResults.map(({ outdatedPackage }) => outdatedPackage);
92
+ logger.debug(`failedPackages=${JSON.stringify(failedPackages)}`);
93
+ // TODO: show as table
94
+ logger.info(`Processed ${succeededResults.length + failedPackages.length} packages:
95
+ - ${updatedPackages.length} packages has updated: ${updatedPackages.map(({ name }) => name).join(',')}
96
+ - ${skippedPackages.length} packages has skipped: ${skippedPackages.map(({ name }) => name).join(',')}
97
+ - ${failedPackages.length} packages has failed: ${failedPackages.map(({ name }) => name).join(',')}`);
87
98
  };
88
99
  exports.main = main;
package/dist/ncu/Ncu.js CHANGED
@@ -2,8 +2,8 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Ncu = void 0;
4
4
  const npm_check_updates_1 = require("npm-check-updates");
5
- const isNcuOutdatedPackages_1 = require("./isNcuOutdatedPackages");
6
- const NcuOutdatedPackagesConverter_1 = require("./NcuOutdatedPackagesConverter");
5
+ const NcuResult_1 = require("./NcuResult");
6
+ const NcuResultConverter_1 = require("./NcuResultConverter");
7
7
  // TODO: add test
8
8
  class Ncu {
9
9
  constructor(packageJsonReader) {
@@ -30,11 +30,11 @@ class Ncu {
30
30
  ...pkg.optionalDependencies
31
31
  };
32
32
  const result = await (0, npm_check_updates_1.run)(options);
33
- if (!(0, isNcuOutdatedPackages_1.isNcuOutdatedPackages)(result)) {
34
- throw new Error('result is not NcuOutdatedPackages');
33
+ if (!(0, NcuResult_1.isNcuResult)(result)) {
34
+ throw new Error('result is not NcuResult');
35
35
  }
36
- const ncuOutdatedPackagesConverter = new NcuOutdatedPackagesConverter_1.NcuOutdatedPackagesConverter(currentDependencies);
37
- return ncuOutdatedPackagesConverter.toOutdatedPackages(result);
36
+ const ncuResultConverter = new NcuResultConverter_1.NcuResultConverter(currentDependencies);
37
+ return ncuResultConverter.toOutdatedPackages(result);
38
38
  }
39
39
  }
40
40
  exports.Ncu = Ncu;
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isNcuResult = exports.NcuResult = void 0;
4
+ const io_ts_1 = require("io-ts");
5
+ exports.NcuResult = (0, io_ts_1.record)(io_ts_1.string, io_ts_1.string);
6
+ exports.isNcuResult = exports.NcuResult.is;
@@ -1,15 +1,15 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.NcuOutdatedPackagesConverter = void 0;
3
+ exports.NcuResultConverter = void 0;
4
4
  const PackageVersion_1 = require("./PackageVersion");
5
5
  const toUpdateType_1 = require("./toUpdateType");
6
6
  // TODO: add test
7
- class NcuOutdatedPackagesConverter {
7
+ class NcuResultConverter {
8
8
  constructor(currentDependencies) {
9
9
  this.currentDependencies = currentDependencies;
10
10
  }
11
- toOutdatedPackages(outdatedPackages) {
12
- return Object.entries(outdatedPackages)
11
+ toOutdatedPackages(result) {
12
+ return Object.entries(result)
13
13
  .map(([name, newVersion]) => ({
14
14
  name,
15
15
  currentVersion: PackageVersion_1.PackageVersion.of(this.currentDependencies[name]),
@@ -23,4 +23,4 @@ class NcuOutdatedPackagesConverter {
23
23
  }));
24
24
  }
25
25
  }
26
- exports.NcuOutdatedPackagesConverter = NcuOutdatedPackagesConverter;
26
+ exports.NcuResultConverter = NcuResultConverter;
@@ -8,7 +8,7 @@ const Options = (0, io_ts_1.type)({
8
8
  branchName: io_ts_1.string,
9
9
  commitMessage: io_ts_1.string,
10
10
  githubToken: io_ts_1.string,
11
- logLevel: (0, io_ts_1.union)([(0, io_ts_1.literal)(logger_1.LogLevel.Info), (0, io_ts_1.literal)(logger_1.LogLevel.Debug)]),
11
+ logLevel: (0, io_ts_1.union)([(0, io_ts_1.literal)(logger_1.LogLevel.Error), (0, io_ts_1.literal)(logger_1.LogLevel.Info), (0, io_ts_1.literal)(logger_1.LogLevel.Debug)]),
12
12
  packageManager: (0, io_ts_1.union)([(0, io_ts_1.literal)(package_manager_1.PackageManagerName.Npm), (0, io_ts_1.literal)(package_manager_1.PackageManagerName.Yarn)]),
13
13
  pullRequestBody: io_ts_1.string,
14
14
  pullRequestTitle: io_ts_1.string
@@ -15,6 +15,7 @@ const initOptions = () => {
15
15
  .requiredOption('--github-token <value>', 'GitHub token')
16
16
  .addOption(new commander_1.Option('--log-level <value>', 'Log level to show')
17
17
  .choices([
18
+ logger_1.LogLevel.Error,
18
19
  logger_1.LogLevel.Info,
19
20
  logger_1.LogLevel.Debug
20
21
  ])
@@ -5,14 +5,12 @@ exports.Npm = void 0;
5
5
  class Npm {
6
6
  constructor(terminal) {
7
7
  this.terminal = terminal;
8
- this.packageFiles = [
9
- 'package.json',
10
- 'package-lock.json'
11
- ];
8
+ this.packageFile = 'package.json';
9
+ this.lockFile = 'package-lock.json';
12
10
  }
13
11
  /**
14
- * @see https://docs.npmjs.com/cli/v8/commands/npm-install
15
- */
12
+ * @see https://docs.npmjs.com/cli/v8/commands/npm-install
13
+ */
16
14
  async install() {
17
15
  await this.terminal.run('npm', 'install');
18
16
  }
@@ -5,10 +5,8 @@ exports.Yarn = void 0;
5
5
  class Yarn {
6
6
  constructor(terminal) {
7
7
  this.terminal = terminal;
8
- this.packageFiles = [
9
- 'package.json',
10
- 'yarn.lock'
11
- ];
8
+ this.packageFile = 'package.json';
9
+ this.lockFile = 'yarn.lock';
12
10
  }
13
11
  /**
14
12
  * @see https://classic.yarnpkg.com/en/docs/cli/install
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.OutdatedPackageProcessor = void 0;
4
+ const Either_1 = require("fp-ts/lib/Either");
4
5
  // TODO: add test
5
6
  class OutdatedPackageProcessor {
6
7
  constructor({ git, ncu, packageManager, pullRequestCreator, remoteBranchExistenceChecker, logger, branchNameCreator, commitMessageCreator }) {
@@ -21,35 +22,49 @@ class OutdatedPackageProcessor {
21
22
  this.logger.debug(`branchName=${branchName}`);
22
23
  if (this.remoteBranchExistenceChecker.check(branchName)) {
23
24
  this.logger.info(`Skip ${outdatedPackage.name} because ${branchName} branch already exists on remote.`);
24
- return {
25
+ return (0, Either_1.right)({
25
26
  outdatedPackage,
26
27
  skipped: true
27
- };
28
+ });
28
29
  }
29
30
  await this.git.createBranch(branchName);
30
31
  this.logger.info(`${branchName} branch has created.`);
31
- const updatedPackages = await this.ncu.update(outdatedPackage);
32
- if (updatedPackages.length !== 1) {
33
- throw new Error(`Failed to update ${outdatedPackage.name}.`);
32
+ try {
33
+ try {
34
+ const updatedPackages = await this.ncu.update(outdatedPackage);
35
+ if (updatedPackages.length !== 1) {
36
+ throw new Error(`Failed to update ${outdatedPackage.name}.`);
37
+ }
38
+ await this.packageManager.install();
39
+ }
40
+ catch (error) {
41
+ this.logger.error(error);
42
+ return (0, Either_1.left)({
43
+ outdatedPackage,
44
+ error
45
+ });
46
+ }
47
+ this.logger.info(`${outdatedPackage.name} has updated from v${outdatedPackage.currentVersion.version} to v${outdatedPackage.newVersion.version}`);
48
+ await this.git.add(this.packageManager.packageFile, this.packageManager.lockFile);
49
+ const message = this.commitMessageCreator.create(outdatedPackage);
50
+ this.logger.debug(`message=${message}`);
51
+ await this.git.commit(message);
52
+ await this.git.push(branchName);
53
+ await this.pullRequestCreator.create({
54
+ outdatedPackage,
55
+ branchName
56
+ });
57
+ return (0, Either_1.right)({
58
+ outdatedPackage,
59
+ updated: true
60
+ });
61
+ }
62
+ finally {
63
+ await this.git.restore(this.packageManager.packageFile, this.packageManager.lockFile);
64
+ await this.git.switch('-');
65
+ await this.git.removeBranch(branchName);
66
+ this.logger.info(`${branchName} branch has removed.`);
34
67
  }
35
- await this.packageManager.install();
36
- this.logger.info(`${outdatedPackage.name} has updated from v${outdatedPackage.currentVersion.version} to v${outdatedPackage.newVersion.version}`);
37
- await this.git.add(...this.packageManager.packageFiles);
38
- const message = this.commitMessageCreator.create(outdatedPackage);
39
- this.logger.debug(`message=${message}`);
40
- await this.git.commit(message);
41
- await this.git.push(branchName);
42
- await this.pullRequestCreator.create({
43
- outdatedPackage,
44
- branchName
45
- });
46
- await this.git.checkout('-');
47
- await this.git.removeBranch(branchName);
48
- this.logger.info(`${branchName} branch has removed.`);
49
- return {
50
- outdatedPackage,
51
- updated: true
52
- };
53
68
  }
54
69
  }
55
70
  exports.OutdatedPackageProcessor = OutdatedPackageProcessor;
@@ -5,25 +5,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.Terminal = void 0;
7
7
  const execa_1 = __importDefault(require("execa"));
8
- const isExecaReturnValue_1 = require("./isExecaReturnValue");
9
8
  // TODO: add test
10
9
  class Terminal {
11
10
  async run(command, ...args) {
12
11
  return await (0, execa_1.default)(command, args);
13
12
  }
14
- async runWithErrorHandling(command, ...args) {
15
- try {
16
- return await this.run(command, ...args);
17
- }
18
- catch (e) {
19
- const value = e instanceof Error ? JSON.parse(JSON.stringify(e)) : e;
20
- if ((0, isExecaReturnValue_1.isExecaReturnValue)(value)) {
21
- return value;
22
- }
23
- else {
24
- throw e;
25
- }
26
- }
27
- }
28
13
  }
29
14
  exports.Terminal = Terminal;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "npm-update-package",
3
- "version": "0.10.0",
3
+ "version": "0.12.0",
4
4
  "description": "CLI tool for creating pull request to update npm packages",
5
5
  "scripts": {
6
6
  "build": "tsc --project tsconfig.build.json",
@@ -24,7 +24,7 @@
24
24
  "io-ts": "2.2.16",
25
25
  "log4js": "6.3.0",
26
26
  "mustache": "4.1.0",
27
- "npm-check-updates": "12.0.2",
27
+ "npm-check-updates": "12.0.3",
28
28
  "parse-github-url": "1.0.2",
29
29
  "semver": "7.3.5"
30
30
  },
@@ -36,8 +36,8 @@
36
36
  "@types/node": "12.20.15",
37
37
  "@types/parse-github-url": "1.0.0",
38
38
  "@types/semver": "7.3.9",
39
- "@typescript-eslint/eslint-plugin": "5.5.0",
40
- "eslint": "8.3.0",
39
+ "@typescript-eslint/eslint-plugin": "5.6.0",
40
+ "eslint": "8.4.1",
41
41
  "eslint-config-standard-with-typescript": "21.0.1",
42
42
  "eslint-plugin-import": "2.25.3",
43
43
  "eslint-plugin-jest": "25.3.0",
@@ -49,9 +49,9 @@
49
49
  "lint-staged": "12.1.2",
50
50
  "npm-run-all": "4.1.5",
51
51
  "rimraf": "3.0.2",
52
- "ts-jest": "27.0.7",
52
+ "ts-jest": "27.1.1",
53
53
  "ts-node": "10.4.0",
54
- "typescript": "4.4.4",
54
+ "typescript": "4.5.3",
55
55
  "utility-types": "3.10.0"
56
56
  },
57
57
  "repository": {
@@ -1,8 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isNcuOutdatedPackages = void 0;
4
- // TODO: add test
5
- const isNcuOutdatedPackages = (value) => {
6
- return typeof value === 'object' && value !== null && Object.values(value).every(value => typeof value === 'string');
7
- };
8
- exports.isNcuOutdatedPackages = isNcuOutdatedPackages;
@@ -1,24 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isExecaReturnValue = void 0;
4
- const io_ts_1 = require("io-ts");
5
- const ExecaReturnValueType = (0, io_ts_1.intersection)([
6
- (0, io_ts_1.type)({
7
- command: io_ts_1.string,
8
- escapedCommand: io_ts_1.string,
9
- exitCode: io_ts_1.number,
10
- failed: io_ts_1.boolean,
11
- timedOut: io_ts_1.boolean,
12
- killed: io_ts_1.boolean,
13
- isCanceled: io_ts_1.boolean
14
- }),
15
- (0, io_ts_1.partial)({
16
- signal: io_ts_1.string,
17
- signalDescription: io_ts_1.string
18
- })
19
- ]);
20
- // TODO: add test
21
- const isExecaReturnValue = (value) => {
22
- return ExecaReturnValueType.is(value);
23
- };
24
- exports.isExecaReturnValue = isExecaReturnValue;