@oneblink/release-cli 3.0.2 → 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 +20 -1
- package/dist/enumerateProductRepositories.js +138 -0
- package/dist/prepareCloneRepository.js +35 -0
- package/dist/repositories-plugins/NpmPlugin.js +1 -0
- package/dist/repositories-plugins/NugetPlugin.js +1 -0
- package/dist/startProductRelease.js +54 -180
- package/dist/startUpdateDependents.js +95 -0
- package/package.json +1 -1
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
|
|
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
|
+
}
|
|
@@ -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
|
-
|
|
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
|
-
|
|
116
|
-
const { repositoryName } =
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
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
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
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
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
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
|
-
|
|
151
|
-
|
|
152
|
-
|
|
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
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
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
|
}));
|
|
@@ -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.
|
|
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"
|