@oneblink/release-cli 3.0.1 → 3.1.0-beta.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/bin.js CHANGED
@@ -10,6 +10,7 @@ import getPreRelease from './getPreRelease.js';
10
10
  import startProductRelease from './startProductRelease.js';
11
11
  import promptForReleaseName from './promptForReleaseName.js';
12
12
  import getRepositoryPlugin from './repositories-plugins/plugins-factory.js';
13
+ import startUpdateDependents from './startUpdateDependents.js';
13
14
  const cli = meow(`
14
15
  ${chalk.bold.blue('oneblink-release product [--name]')}
15
16
 
@@ -51,6 +52,17 @@ ${chalk.bold('Examples')}
51
52
  oneblink-release repository 1.1.1
52
53
  oneblink-release repository 1.1.1 --cwd ../path/to/code
53
54
  oneblink-release repository 1.1.1-uat.1 --no-git
55
+
56
+ ${chalk.grey('Update all product code bases that depend on an NPM package.')}
57
+
58
+ --cwd .......... Directory of the repository that is the dependency relative
59
+ to the current working directory, defaults to the current
60
+ working directory.
61
+
62
+ ${chalk.bold('Examples')}
63
+
64
+ oneblink-release update-dependents
65
+ oneblink-release update-dependents --cwd ../path/to/code
54
66
  `, {
55
67
  importMeta: import.meta,
56
68
  flags: {
@@ -99,7 +111,14 @@ run().catch((error) => {
99
111
  });
100
112
  async function run() {
101
113
  const command = cli.input[0];
114
+ const cwd = path.resolve(process.cwd(), cli.flags.cwd);
102
115
  switch (command) {
116
+ case 'update-dependents': {
117
+ await startUpdateDependents({
118
+ cwd,
119
+ });
120
+ break;
121
+ }
103
122
  case 'product': {
104
123
  const releaseName = cli.flags.name || (await promptForReleaseName());
105
124
  await startProductRelease({ releaseName });
@@ -108,7 +127,7 @@ async function run() {
108
127
  case 'repository': {
109
128
  let input = cli.input[1];
110
129
  const repositoryPlugin = await getRepositoryPlugin({
111
- cwd: path.resolve(process.cwd(), cli.flags.cwd),
130
+ cwd,
112
131
  });
113
132
  if (!semver.valid(input)) {
114
133
  const { nextVersion } = await promptForNextVersion({
@@ -0,0 +1,138 @@
1
+ import path from 'path';
2
+ import prepareCloneRepository from './prepareCloneRepository.js';
3
+ const productRepositories = [
4
+ {
5
+ label: '@oneblink/apps (NPM package)',
6
+ repositoryName: 'apps',
7
+ type: 'NPM',
8
+ isPublic: true,
9
+ },
10
+ {
11
+ label: '@oneblink/apps-react (NPM package)',
12
+ repositoryName: 'apps-react',
13
+ type: 'NPM',
14
+ isPublic: true,
15
+ },
16
+ {
17
+ label: '@oneblink/cli (NPM package)',
18
+ repositoryName: 'cli',
19
+ isPublic: true,
20
+ type: 'NPM',
21
+ },
22
+ {
23
+ label: 'Embedded Forms Script',
24
+ repositoryName: 'forms-cdn',
25
+ isPublic: true,
26
+ type: 'CDN_HOSTING',
27
+ },
28
+ {
29
+ label: 'API',
30
+ repositoryName: 'product-api',
31
+ isPublic: false,
32
+ type: 'NODE_JS',
33
+ },
34
+ {
35
+ label: 'Approvals API',
36
+ repositoryName: 'product-approvals-api',
37
+ isPublic: false,
38
+ type: 'NODE_JS',
39
+ },
40
+ {
41
+ label: 'Approvals Client',
42
+ repositoryName: 'product-approvals-client',
43
+ isPublic: false,
44
+ type: 'NODE_JS',
45
+ },
46
+ {
47
+ label: 'Cognito Hosted Login CSS',
48
+ repositoryName: 'product-cognito-hosted-login-css',
49
+ isPublic: false,
50
+ type: 'NODE_JS',
51
+ },
52
+ {
53
+ label: 'Console',
54
+ repositoryName: 'product-console',
55
+ isPublic: false,
56
+ type: 'NODE_JS',
57
+ },
58
+ {
59
+ label: 'Data Manager Client',
60
+ repositoryName: 'product-form-store-client',
61
+ isPublic: false,
62
+ type: 'NODE_JS',
63
+ },
64
+ {
65
+ label: 'Lambda@Edge Functions',
66
+ repositoryName: 'product-forms-lambda-at-edge-authorisation',
67
+ isPublic: false,
68
+ type: 'NODE_JS',
69
+ },
70
+ {
71
+ label: 'Forms Renderer',
72
+ repositoryName: 'product-forms-renderer',
73
+ isPublic: false,
74
+ type: 'NODE_JS',
75
+ },
76
+ {
77
+ label: 'Infrastructure',
78
+ repositoryName: 'product-infrastructure',
79
+ isPublic: false,
80
+ type: 'NODE_JS',
81
+ },
82
+ {
83
+ label: 'PDF Service',
84
+ repositoryName: 'product-pdf',
85
+ isPublic: false,
86
+ type: 'NODE_JS',
87
+ },
88
+ {
89
+ label: 'S3 Submission Events Lambda(s)',
90
+ repositoryName: 'product-s3-submission-events',
91
+ isPublic: false,
92
+ type: 'NODE_JS',
93
+ },
94
+ {
95
+ label: 'Volunteers Client',
96
+ repositoryName: 'product-volunteers-client',
97
+ isPublic: false,
98
+ type: 'NODE_JS',
99
+ },
100
+ {
101
+ label: '@oneblink/sdk-core (NPM package)',
102
+ repositoryName: 'sdk-core-js',
103
+ isPublic: true,
104
+ type: 'NPM',
105
+ },
106
+ {
107
+ label: 'OneBlink.SDK (Nuget package)',
108
+ repositoryName: 'sdk-dotnet',
109
+ isPublic: true,
110
+ type: 'NUGET',
111
+ relativeProjectFile: path.join('OneBlink.SDK', 'OneBlink.SDK.csproj'),
112
+ },
113
+ {
114
+ label: '@oneblink/sdk (NPM package)',
115
+ repositoryName: 'sdk-node-js',
116
+ isPublic: true,
117
+ type: 'NPM',
118
+ },
119
+ ];
120
+ export default async function enumerateProductRepositories(fn) {
121
+ for (const productRepository of productRepositories) {
122
+ const { repositoryName } = productRepository;
123
+ const { cloneRepository, repositoryWorkingDirectory, removeRepositoryWorkingDirectory, } = await prepareCloneRepository({
124
+ repositoryName,
125
+ });
126
+ try {
127
+ const cloneUrl = await cloneRepository();
128
+ await fn({
129
+ cloneUrl,
130
+ repositoryWorkingDirectory,
131
+ productRepository,
132
+ });
133
+ }
134
+ finally {
135
+ await removeRepositoryWorkingDirectory();
136
+ }
137
+ }
138
+ }
@@ -0,0 +1,35 @@
1
+ import { mkdtemp, rm } from 'fs/promises';
2
+ import { join } from 'node:path';
3
+ import { tmpdir } from 'node:os';
4
+ import executeCommand from './executeCommand.js';
5
+ import wrapWithLoading from './wrapWithLoading.js';
6
+ export default async function prepareCloneRepository({ repositoryName, }) {
7
+ const repositoryWorkingDirectory = await wrapWithLoading({
8
+ startText: `Creating temporary directory to clone "${repositoryName}"`,
9
+ failText: `Failed to create temporary directory to clone "${repositoryName}"`,
10
+ }, async (spinner) => {
11
+ const directory = await mkdtemp(join(tmpdir(), repositoryName));
12
+ spinner.succeed(`Created temporary directory to clone "${repositoryName}"`);
13
+ return directory;
14
+ });
15
+ return {
16
+ repositoryWorkingDirectory,
17
+ async cloneRepository() {
18
+ const cloneUrl = `git@github.com:oneblink/${repositoryName}.git`;
19
+ await executeCommand('git', ['clone', cloneUrl, repositoryWorkingDirectory], '.');
20
+ return cloneUrl;
21
+ },
22
+ async removeRepositoryWorkingDirectory() {
23
+ await wrapWithLoading({
24
+ startText: `Removing temporary directory for "${repositoryName}"`,
25
+ failText: `Failed to remove temporary directory for "${repositoryName}"`,
26
+ }, async (spinner) => {
27
+ await rm(repositoryWorkingDirectory, {
28
+ recursive: true,
29
+ force: true,
30
+ });
31
+ spinner.succeed(`Removed temporary directory for "${repositoryName}"`);
32
+ });
33
+ },
34
+ };
35
+ }
@@ -4,6 +4,7 @@ import executeCommand from '../executeCommand.js';
4
4
  export default class NpmPlugin {
5
5
  displayType = 'NPM';
6
6
  isDeploymentRequired = false;
7
+ supportsDependencyUpdates = true;
7
8
  cwd;
8
9
  constructor({ cwd }) {
9
10
  this.cwd = cwd;
@@ -3,6 +3,7 @@ import path from 'path';
3
3
  import getPreRelease from '../getPreRelease.js';
4
4
  export default class NugetPlugin {
5
5
  isDeploymentRequired = false;
6
+ supportsDependencyUpdates = false;
6
7
  displayType = 'Nuget';
7
8
  cwd;
8
9
  relativeProjectFile;
@@ -1,201 +1,75 @@
1
- import { mkdtemp, rm } from 'fs/promises';
2
- import { join } from 'node:path';
3
- import { tmpdir } from 'node:os';
4
1
  import enquirer from 'enquirer';
5
2
  import executeCommand from './executeCommand.js';
6
3
  import parseChangelogWithLoading from './parseChangelogWithLoading.js';
7
4
  import promptForNextVersion from './promptForNextVersion.js';
8
5
  import boxen from 'boxen';
9
6
  import chalk from 'chalk';
10
- import wrapWithLoading from './wrapWithLoading.js';
11
7
  import startRepositoryRelease from './startRepositoryRelease.js';
12
- import path from 'path';
13
8
  import getRepositoryPlugin from './repositories-plugins/plugins-factory.js';
14
- const gitCloneRepositories = [
15
- {
16
- repositoryName: 'apps',
17
- type: 'NPM',
18
- isPublic: true,
19
- },
20
- {
21
- repositoryName: 'apps-react',
22
- type: 'NPM',
23
- isPublic: true,
24
- },
25
- {
26
- repositoryName: 'cli',
27
- isPublic: true,
28
- type: 'NPM',
29
- },
30
- {
31
- repositoryName: 'forms-cdn',
32
- isPublic: true,
33
- type: 'CDN_HOSTING',
34
- },
35
- {
36
- repositoryName: 'product-api',
37
- isPublic: false,
38
- type: 'NODE_JS',
39
- },
40
- {
41
- repositoryName: 'product-approvals-api',
42
- isPublic: false,
43
- type: 'NODE_JS',
44
- },
45
- {
46
- repositoryName: 'product-approvals-client',
47
- isPublic: false,
48
- type: 'NODE_JS',
49
- },
50
- {
51
- repositoryName: 'product-cognito-hosted-login-css',
52
- isPublic: false,
53
- type: 'NODE_JS',
54
- },
55
- {
56
- repositoryName: 'product-console',
57
- isPublic: false,
58
- type: 'NODE_JS',
59
- },
60
- {
61
- repositoryName: 'product-form-store-client',
62
- isPublic: false,
63
- type: 'NODE_JS',
64
- },
65
- {
66
- repositoryName: 'product-forms-lambda-at-edge-authorisation',
67
- isPublic: false,
68
- type: 'NODE_JS',
69
- },
70
- {
71
- repositoryName: 'product-forms-renderer',
72
- isPublic: false,
73
- type: 'NODE_JS',
74
- },
75
- {
76
- repositoryName: 'product-infrastructure',
77
- isPublic: false,
78
- type: 'NODE_JS',
79
- },
80
- {
81
- repositoryName: 'product-pdf',
82
- isPublic: false,
83
- type: 'NODE_JS',
84
- },
85
- {
86
- repositoryName: 'product-s3-submission-events',
87
- isPublic: false,
88
- type: 'NODE_JS',
89
- },
90
- {
91
- repositoryName: 'product-volunteers-client',
92
- isPublic: false,
93
- type: 'NODE_JS',
94
- },
95
- {
96
- repositoryName: 'sdk-core-js',
97
- isPublic: true,
98
- type: 'NPM',
99
- },
100
- {
101
- repositoryName: 'sdk-dotnet',
102
- isPublic: true,
103
- type: 'NUGET',
104
- relativeProjectFile: path.join('OneBlink.SDK', 'OneBlink.SDK.csproj'),
105
- },
106
- {
107
- repositoryName: 'sdk-node-js',
108
- isPublic: true,
109
- type: 'NPM',
110
- },
111
- ];
9
+ import enumerateProductRepositories from './enumerateProductRepositories.js';
112
10
  export default async function startProductRelease({ releaseName, }) {
113
11
  console.log('Beginning Product release process for:', releaseName);
114
12
  const deploymentRequiredUrls = [];
115
- for (const gitCloneRepository of gitCloneRepositories) {
116
- const { repositoryName } = gitCloneRepository;
117
- const repositoryWorkingDirectory = await wrapWithLoading({
118
- startText: `Creating temporary directory to clone "${repositoryName}"`,
119
- failText: `Failed to create temporary directory to clone "${repositoryName}"`,
120
- }, async (spinner) => {
121
- const directory = await mkdtemp(join(tmpdir(), repositoryName));
122
- spinner.succeed(`Created temporary directory to clone "${repositoryName}"`);
123
- return directory;
124
- });
125
- try {
126
- const cloneUrl = `git@github.com:oneblink/${repositoryName}.git`;
127
- await executeCommand('git', ['clone', cloneUrl, repositoryWorkingDirectory], '.');
128
- // Check if repository needs releasing
129
- const { parsedChangelog } = await parseChangelogWithLoading(repositoryWorkingDirectory);
130
- const unreleasedVersion = parsedChangelog.versions.find((version) => version.title.toLowerCase().includes('unreleased'));
131
- if (!unreleasedVersion) {
132
- await continuePromptWithWarning(`"${repositoryName}" CHANGELOG.md does not contain an "Unreleased" section
13
+ await enumerateProductRepositories(async ({ productRepository, cloneUrl, repositoryWorkingDirectory }) => {
14
+ const { repositoryName } = productRepository;
15
+ // Check if repository needs releasing
16
+ const { parsedChangelog } = await parseChangelogWithLoading(repositoryWorkingDirectory);
17
+ const unreleasedVersion = parsedChangelog.versions.find((version) => version.title.toLowerCase().includes('unreleased'));
18
+ if (!unreleasedVersion) {
19
+ await continuePromptWithWarning(`"${repositoryName}" CHANGELOG.md does not contain an "Unreleased" section
133
20
 
134
21
  You need to checkout "${cloneUrl}" to fix this before trying again.`);
135
- continue;
136
- }
137
- const { stdout: lastCommitMessage } = await executeCommand('git', ['log', '-1', '--pretty=oneline'], repositoryWorkingDirectory);
138
- const unreleasedChangelogEntries = unreleasedVersion.body.trim() ||
139
- chalk.italic('There are no entries under the "Unreleased" heading.');
140
- console.log(boxen(chalk.blue(`${unreleasedChangelogEntries}
22
+ return;
23
+ }
24
+ const { stdout: lastCommitMessage } = await executeCommand('git', ['log', '-1', '--pretty=oneline'], repositoryWorkingDirectory);
25
+ const unreleasedChangelogEntries = unreleasedVersion.body.trim() ||
26
+ chalk.italic('There are no entries under the "Unreleased" heading.');
27
+ console.log(boxen(chalk.blue(`${unreleasedChangelogEntries}
141
28
 
142
29
  Last Commit: ${lastCommitMessage}`), {
143
- title: 'Unreleased Entries',
144
- padding: 1,
145
- margin: {
146
- top: 1,
147
- bottom: 1,
30
+ title: 'Unreleased Entries',
31
+ padding: 1,
32
+ margin: {
33
+ top: 1,
34
+ bottom: 1,
35
+ },
36
+ }));
37
+ const { isReleasing } = await enquirer.prompt({
38
+ type: 'select',
39
+ name: 'isReleasing',
40
+ message: `Would you like to release "${repositoryName}"? See unreleased section from changelog above to decide.`,
41
+ choices: [
42
+ {
43
+ message: `No! "${repositoryName}" does not need to be released.`,
44
+ name: 'no',
45
+ },
46
+ {
47
+ message: 'Yes, release away!',
48
+ name: 'yes',
148
49
  },
149
- }));
150
- const { isReleasing } = await enquirer.prompt({
151
- type: 'select',
152
- name: 'isReleasing',
153
- message: `Would you like to release "${repositoryName}"? See unreleased section from changelog above to decide.`,
154
- choices: [
155
- {
156
- message: `No! "${repositoryName}" does not need to be released.`,
157
- name: 'no',
158
- },
159
- {
160
- message: 'Yes, release away!',
161
- name: 'yes',
162
- },
163
- ],
164
- });
165
- if (isReleasing === 'no') {
166
- continue;
167
- }
168
- const repositoryPlugin = await getRepositoryPlugin({
169
- cwd: repositoryWorkingDirectory,
170
- repositoryType: gitCloneRepository,
171
- });
172
- const { nextVersion } = await promptForNextVersion({
173
- repositoryPlugin,
174
- noPreRelease: true,
175
- });
176
- await startRepositoryRelease({
177
- nextVersion,
178
- git: true,
179
- releaseName: gitCloneRepository.isPublic ? undefined : releaseName,
180
- repositoryPlugin,
181
- });
182
- if (repositoryPlugin.isDeploymentRequired) {
183
- deploymentRequiredUrls.push(`https://github.com/oneblink/${repositoryName}/actions`);
184
- }
50
+ ],
51
+ });
52
+ if (isReleasing === 'no') {
53
+ return;
185
54
  }
186
- finally {
187
- await wrapWithLoading({
188
- startText: `Removing temporary directory for "${repositoryName}"`,
189
- failText: `Failed to remove temporary directory for "${repositoryName}"`,
190
- }, async (spinner) => {
191
- await rm(repositoryWorkingDirectory, {
192
- recursive: true,
193
- force: true,
194
- });
195
- spinner.succeed(`Removed temporary directory for "${repositoryName}"`);
196
- });
55
+ const repositoryPlugin = await getRepositoryPlugin({
56
+ cwd: repositoryWorkingDirectory,
57
+ repositoryType: productRepository,
58
+ });
59
+ const { nextVersion } = await promptForNextVersion({
60
+ repositoryPlugin,
61
+ noPreRelease: true,
62
+ });
63
+ await startRepositoryRelease({
64
+ nextVersion,
65
+ git: true,
66
+ releaseName: productRepository.isPublic ? undefined : releaseName,
67
+ repositoryPlugin,
68
+ });
69
+ if (repositoryPlugin.isDeploymentRequired) {
70
+ deploymentRequiredUrls.push(`https://github.com/oneblink/${repositoryName}/actions`);
197
71
  }
198
- }
72
+ });
199
73
  console.log(boxen(chalk.green('Product Release Complete!!!'), {
200
74
  padding: 1,
201
75
  }));
@@ -1,5 +1,4 @@
1
1
  import fs from 'fs';
2
- import path from 'path';
3
2
  import util from 'util';
4
3
  import prettier from 'prettier';
5
4
  import semver from 'semver';
@@ -8,7 +7,6 @@ import wrapWithLoading from './wrapWithLoading.js';
8
7
  import executeCommand from './executeCommand.js';
9
8
  import parseChangelogWithLoading from './parseChangelogWithLoading.js';
10
9
  import getPreRelease from './getPreRelease.js';
11
- const readFileAsync = util.promisify(fs.readFile);
12
10
  const writeFileAsync = util.promisify(fs.writeFile);
13
11
  const UNRELEASED_VERSION_INDEX = 0;
14
12
  const GIT_TAG_PREFIX = 'v';
@@ -68,14 +66,6 @@ ${dependenciesChangelog.entries}
68
66
  startText: `Updating CHANGELOG.md with next release (${nextReleaseTitle})`,
69
67
  failText: `Failed to update CHANGELOG.md with next release (${nextReleaseTitle})`,
70
68
  }, async (spinner) => {
71
- let prettierOptions = {};
72
- try {
73
- const s = await readFileAsync(path.join(repositoryPlugin.cwd, '.prettierrc'), 'utf-8');
74
- prettierOptions = JSON.parse(s);
75
- }
76
- catch (error) {
77
- // ignore errors attempting to find prettier configuration
78
- }
79
69
  const changelog = await prettier.format(`
80
70
  # ${parsedChangelog.title}
81
71
 
@@ -101,7 +91,6 @@ ${body}
101
91
  `;
102
92
  })
103
93
  .join('')}`, {
104
- ...prettierOptions,
105
94
  parser: 'markdown',
106
95
  });
107
96
  await writeFileAsync(changelogPath, changelog, 'utf-8');
@@ -0,0 +1,95 @@
1
+ import { readPackageUp } from 'read-package-up';
2
+ import enumerateProductRepositories from './enumerateProductRepositories.js';
3
+ import getRepositoryPlugin from './repositories-plugins/plugins-factory.js';
4
+ import enquirer from 'enquirer';
5
+ import executeCommand from './executeCommand.js';
6
+ import boxen from 'boxen';
7
+ export default async function startUpdateDependents({ cwd }) {
8
+ const dependencyRepositoryPlugin = await getRepositoryPlugin({
9
+ cwd,
10
+ });
11
+ if (!dependencyRepositoryPlugin.supportsDependencyUpdates) {
12
+ console.log(`"${dependencyRepositoryPlugin.displayType}" repositories do not support updating dependencies.`);
13
+ return;
14
+ }
15
+ const dependencyResult = await readPackageUp({
16
+ cwd,
17
+ });
18
+ if (!dependencyResult) {
19
+ return;
20
+ }
21
+ const dependency = dependencyResult.packageJson.name;
22
+ console.log('Beginning to update the dependents of:', dependency);
23
+ const { jiraTicket } = await enquirer.prompt({
24
+ type: 'input',
25
+ name: 'jiraTicket',
26
+ message: `JIRA ticket to associate with pull requests? (e.g. ON-4323)`,
27
+ required: true,
28
+ validate: (input) => {
29
+ if (!/^ON-\d+$/.test(input)) {
30
+ return 'JIRA ticket must be "ON-" followed by a number';
31
+ }
32
+ return true;
33
+ },
34
+ });
35
+ const createPullRequestUrls = [];
36
+ await enumerateProductRepositories(async ({ productRepository, repositoryWorkingDirectory }) => {
37
+ const repositoryPlugin = await getRepositoryPlugin({
38
+ cwd: repositoryWorkingDirectory,
39
+ repositoryType: productRepository,
40
+ });
41
+ if (!repositoryPlugin.supportsDependencyUpdates) {
42
+ console.log(`Skipping "${productRepository.repositoryName}" as "${repositoryPlugin.displayType}" does not support updating dependencies.`);
43
+ return;
44
+ }
45
+ const result = await readPackageUp({
46
+ cwd: repositoryWorkingDirectory,
47
+ });
48
+ const currentDependencyVersion = result?.packageJson.dependencies?.[dependency];
49
+ if (!currentDependencyVersion) {
50
+ console.log(`Skipping "${productRepository.repositoryName}" as it does not contain "${dependency}" as a dependency.`);
51
+ return;
52
+ }
53
+ if (currentDependencyVersion === `^${dependencyResult.packageJson.version}`) {
54
+ console.log(`Skipping "${productRepository.repositoryName}" as it's version of "${dependency}" is already "${currentDependencyVersion}".`);
55
+ return;
56
+ }
57
+ const { isUpdating } = await enquirer.prompt({
58
+ type: 'select',
59
+ name: 'isUpdating',
60
+ message: `Would you like to update "${dependency}" in "${productRepository.repositoryName}" (${currentDependencyVersion} > ${dependencyResult.packageJson.version})?`,
61
+ choices: [
62
+ {
63
+ message: 'Yes, update dependency!',
64
+ name: 'yes',
65
+ },
66
+ {
67
+ message: `No! "${productRepository.repositoryName}" does not need to be updated.`,
68
+ name: 'no',
69
+ },
70
+ ],
71
+ });
72
+ if (isUpdating === 'no') {
73
+ return;
74
+ }
75
+ await executeCommand('git', ['checkout', '-b', jiraTicket], repositoryWorkingDirectory);
76
+ await executeCommand('npm', [
77
+ 'install',
78
+ '--package-lock-only',
79
+ '--save',
80
+ `${dependency}@${dependencyResult.packageJson.version}`,
81
+ ], repositoryWorkingDirectory);
82
+ await executeCommand('git', ['add', '-A'], repositoryWorkingDirectory);
83
+ await executeCommand('git', ['commit', '--message', `${jiraTicket} # Bumped ${dependency}`], repositoryWorkingDirectory);
84
+ await executeCommand('git', ['push', '-u', 'origin', jiraTicket], repositoryWorkingDirectory);
85
+ createPullRequestUrls.push(`https://github.com/oneblink/${productRepository.repositoryName}/pull/new/${jiraTicket}`);
86
+ });
87
+ if (createPullRequestUrls.length) {
88
+ console.log(boxen(`The following Pull Requests can be created:
89
+
90
+ ${createPullRequestUrls.join(`
91
+ `)}`, {
92
+ padding: 1,
93
+ }));
94
+ }
95
+ }
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 repositories quickly and consistently",
4
- "version": "3.0.1",
4
+ "version": "3.1.0-beta.1",
5
5
  "author": "OneBlink <developers@oneblink> (https://github.com/oneblink)",
6
6
  "bin": {
7
7
  "oneblink-release": "dist/bin.js"