contensis-cli 1.0.0-beta.95 → 1.0.0-beta.97
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/commands/dev.js +2 -6
- package/dist/commands/dev.js.map +2 -2
- package/dist/commands/import.js +18 -0
- package/dist/commands/import.js.map +2 -2
- package/dist/localisation/en-GB.js +28 -11
- package/dist/localisation/en-GB.js.map +2 -2
- package/dist/mappers/DevInit-to-CIWorkflow.js +251 -136
- package/dist/mappers/DevInit-to-CIWorkflow.js.map +3 -3
- package/dist/models/DevService.d.js.map +1 -1
- package/dist/services/ContensisCliService.js +64 -0
- package/dist/services/ContensisCliService.js.map +2 -2
- package/dist/services/ContensisDevService.js +65 -18
- package/dist/services/ContensisDevService.js.map +2 -2
- package/dist/services/ContensisRoleService.js +31 -4
- package/dist/services/ContensisRoleService.js.map +3 -3
- package/dist/util/diff.js +3 -1
- package/dist/util/diff.js.map +2 -2
- package/dist/util/git.js +4 -2
- package/dist/util/git.js.map +2 -2
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +2 -1
- package/src/commands/dev.ts +7 -7
- package/src/commands/import.ts +25 -0
- package/src/localisation/en-GB.ts +43 -9
- package/src/mappers/DevInit-to-CIWorkflow.ts +386 -196
- package/src/models/DevService.d.ts +14 -0
- package/src/services/ContensisCliService.ts +84 -0
- package/src/services/ContensisDevService.ts +80 -21
- package/src/services/ContensisRoleService.ts +33 -1
- package/src/util/diff.ts +4 -1
- package/src/util/git.ts +4 -3
- package/src/version.ts +1 -1
|
@@ -2,6 +2,8 @@ export type EnvContentsToAdd = {
|
|
|
2
2
|
ALIAS: string;
|
|
3
3
|
PROJECT: string;
|
|
4
4
|
ACCESS_TOKEN?: string;
|
|
5
|
+
CONTENSIS_CLIENT_ID?: string;
|
|
6
|
+
CONTENSIS_CLIENT_SECRET?: string;
|
|
5
7
|
};
|
|
6
8
|
|
|
7
9
|
export type GitHubActionPushBlockJobStep = {
|
|
@@ -24,3 +26,15 @@ export type GitHubActionPushBlockJob = {
|
|
|
24
26
|
needs?: string;
|
|
25
27
|
steps: GitHubActionPushBlockJobStep[];
|
|
26
28
|
};
|
|
29
|
+
|
|
30
|
+
export type GitLabPushBlockJobStage = {
|
|
31
|
+
stage: string;
|
|
32
|
+
variables: {
|
|
33
|
+
alias: string;
|
|
34
|
+
project_id: string;
|
|
35
|
+
block_id: string;
|
|
36
|
+
image_uri?: string;
|
|
37
|
+
client_id: string;
|
|
38
|
+
shared_secret: string;
|
|
39
|
+
};
|
|
40
|
+
};
|
|
@@ -71,6 +71,10 @@ class ContensisCli {
|
|
|
71
71
|
contensisOpts: Partial<MigrateRequest>;
|
|
72
72
|
currentProject: string;
|
|
73
73
|
|
|
74
|
+
clientDetailsLocation?: 'env' | 'git';
|
|
75
|
+
clientId?: string;
|
|
76
|
+
clientSecret?: string;
|
|
77
|
+
|
|
74
78
|
sourceAlias?: string;
|
|
75
79
|
targetEnv?: string;
|
|
76
80
|
urls:
|
|
@@ -290,6 +294,7 @@ class ContensisCli {
|
|
|
290
294
|
| 'contentTypes'
|
|
291
295
|
| 'components'
|
|
292
296
|
| 'models'
|
|
297
|
+
| 'nodes'
|
|
293
298
|
| 'user-input';
|
|
294
299
|
}) => {
|
|
295
300
|
const source: 'contensis' | 'file' = fromFile ? 'file' : 'contensis';
|
|
@@ -1736,6 +1741,85 @@ class ContensisCli {
|
|
|
1736
1741
|
}
|
|
1737
1742
|
};
|
|
1738
1743
|
|
|
1744
|
+
ImportNodes = async ({
|
|
1745
|
+
commit,
|
|
1746
|
+
fromFile,
|
|
1747
|
+
logOutput,
|
|
1748
|
+
}: {
|
|
1749
|
+
commit: boolean;
|
|
1750
|
+
fromFile: string;
|
|
1751
|
+
logOutput: string;
|
|
1752
|
+
}) => {
|
|
1753
|
+
const { currentEnv, currentProject, log, messages } = this;
|
|
1754
|
+
|
|
1755
|
+
const contensis = await this.ConnectContensisImport({
|
|
1756
|
+
commit,
|
|
1757
|
+
fromFile,
|
|
1758
|
+
importDataType: 'nodes',
|
|
1759
|
+
});
|
|
1760
|
+
|
|
1761
|
+
if (contensis) {
|
|
1762
|
+
log.line();
|
|
1763
|
+
if (contensis.isPreview) {
|
|
1764
|
+
console.log(log.successText(` -- IMPORT PREVIEW -- `));
|
|
1765
|
+
} else {
|
|
1766
|
+
console.log(log.warningText(` *** COMMITTING IMPORT *** `));
|
|
1767
|
+
}
|
|
1768
|
+
|
|
1769
|
+
const [err, result] = await contensis.MigrateNodes();
|
|
1770
|
+
|
|
1771
|
+
if (err) logError(err);
|
|
1772
|
+
else
|
|
1773
|
+
this.HandleFormattingAndOutput(result, () => {
|
|
1774
|
+
// print the migrateResult to console
|
|
1775
|
+
// TODO: fix
|
|
1776
|
+
printMigrateResult(this, result, {
|
|
1777
|
+
showAllEntries: logOutput === 'all',
|
|
1778
|
+
showChangedEntries: logOutput === 'changes',
|
|
1779
|
+
});
|
|
1780
|
+
});
|
|
1781
|
+
|
|
1782
|
+
const nodesTotalCount = result?.nodesToMigrate[currentProject].totalCount;
|
|
1783
|
+
const nodesCreated = result?.nodesResult?.['created'] || 0;
|
|
1784
|
+
const nodesUpdated = result?.nodesResult?.['updated'] || 0;
|
|
1785
|
+
const noChange = result.nodesToMigrate[currentProject]['no change'] !== 0;
|
|
1786
|
+
|
|
1787
|
+
if (
|
|
1788
|
+
!err &&
|
|
1789
|
+
!result.errors?.length &&
|
|
1790
|
+
((!commit && nodesTotalCount) ||
|
|
1791
|
+
(commit && (nodesCreated || nodesUpdated)))
|
|
1792
|
+
) {
|
|
1793
|
+
let totalCount: number;
|
|
1794
|
+
if (commit) {
|
|
1795
|
+
let created = typeof nodesCreated === 'number' ? nodesCreated : 0;
|
|
1796
|
+
let updated = typeof nodesUpdated === 'number' ? nodesUpdated : 0;
|
|
1797
|
+
|
|
1798
|
+
totalCount = created + updated;
|
|
1799
|
+
} else {
|
|
1800
|
+
totalCount =
|
|
1801
|
+
typeof nodesTotalCount === 'number' ? nodesTotalCount : 0;
|
|
1802
|
+
}
|
|
1803
|
+
|
|
1804
|
+
log.success(messages.nodes.imported(currentEnv, commit, totalCount));
|
|
1805
|
+
if (!commit) {
|
|
1806
|
+
log.raw(``);
|
|
1807
|
+
log.help(messages.nodes.commitTip());
|
|
1808
|
+
}
|
|
1809
|
+
} else {
|
|
1810
|
+
if (noChange) {
|
|
1811
|
+
log.help(messages.nodes.noChange(currentEnv), err);
|
|
1812
|
+
} else {
|
|
1813
|
+
log.error(messages.nodes.failedImport(currentEnv), err);
|
|
1814
|
+
if (!nodesTotalCount) log.help(messages.nodes.notFound(currentEnv));
|
|
1815
|
+
}
|
|
1816
|
+
}
|
|
1817
|
+
} else {
|
|
1818
|
+
log.warning(messages.models.noList(currentProject));
|
|
1819
|
+
log.help(messages.connect.tip());
|
|
1820
|
+
}
|
|
1821
|
+
};
|
|
1822
|
+
|
|
1739
1823
|
PrintWebhookSubscriptions = async (subscriptionIdsOrNames?: string[]) => {
|
|
1740
1824
|
const { currentEnv, log, messages } = this;
|
|
1741
1825
|
const contensis = await this.ConnectContensis();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import to from 'await-to-js';
|
|
2
|
-
import {
|
|
2
|
+
import { spawn } from 'child_process';
|
|
3
3
|
import inquirer from 'inquirer';
|
|
4
4
|
import path from 'path';
|
|
5
5
|
|
|
@@ -21,10 +21,13 @@ import { mergeDotEnvFileContents } from '~/util/dotenv';
|
|
|
21
21
|
import { findByIdOrName } from '~/util/find';
|
|
22
22
|
import { GitHelper } from '~/util/git';
|
|
23
23
|
import { jsonFormatter } from '~/util/json.formatter';
|
|
24
|
-
import {
|
|
24
|
+
import { winSlash } from '~/util/os';
|
|
25
25
|
import { stringifyYaml } from '~/util/yaml';
|
|
26
|
+
import { createSpinner } from 'nanospinner';
|
|
26
27
|
|
|
27
28
|
class ContensisDev extends ContensisRole {
|
|
29
|
+
git!: GitHelper;
|
|
30
|
+
|
|
28
31
|
constructor(
|
|
29
32
|
args: string[],
|
|
30
33
|
outputOpts?: OutputOptionsConstructorArg,
|
|
@@ -52,7 +55,7 @@ class ContensisDev extends ContensisRole {
|
|
|
52
55
|
);
|
|
53
56
|
|
|
54
57
|
// Retrieve git info
|
|
55
|
-
const git = new GitHelper(projectHome);
|
|
58
|
+
const git = (this.git = new GitHelper(projectHome));
|
|
56
59
|
|
|
57
60
|
// Retrieve ci workflow info
|
|
58
61
|
const workflowFiles = git.workflows;
|
|
@@ -116,10 +119,39 @@ class ContensisDev extends ContensisRole {
|
|
|
116
119
|
|
|
117
120
|
log.raw(log.infoText(messages.devinit.ciDetails(ciFileName)));
|
|
118
121
|
|
|
119
|
-
|
|
120
|
-
|
|
122
|
+
let mappedWorkflow;
|
|
123
|
+
// Location for Client ID / Secret.
|
|
124
|
+
const { clientDetailsOption } = await inquirer.prompt({
|
|
125
|
+
name: 'clientDetailsOption',
|
|
126
|
+
type: 'list',
|
|
127
|
+
prefix: '🔑',
|
|
128
|
+
// Where would you like to store your Client ID/Secret?
|
|
129
|
+
message: messages.devinit.clientDetailsLocation(),
|
|
130
|
+
choices: [
|
|
131
|
+
messages.devinit.clientDetailsInGit(git),
|
|
132
|
+
messages.devinit.clientDetailsInEnv(),
|
|
133
|
+
],
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
// global 'clientDetailsLocation' variable stores users input on where client id / secert are stored
|
|
137
|
+
if (clientDetailsOption === messages.devinit.clientDetailsInEnv()) {
|
|
138
|
+
this.clientDetailsLocation = 'env';
|
|
139
|
+
} else {
|
|
140
|
+
this.clientDetailsLocation = 'git';
|
|
141
|
+
}
|
|
121
142
|
|
|
122
|
-
|
|
143
|
+
if (this.clientDetailsLocation === 'env') {
|
|
144
|
+
// Update CI Workflow to pull from ENV variables
|
|
145
|
+
mappedWorkflow = await mapCIWorkflowContent(this);
|
|
146
|
+
// Add client id and secret to global 'this'
|
|
147
|
+
this.clientId = existingDeployKey?.id;
|
|
148
|
+
this.clientSecret = existingDeployKey?.sharedSecret;
|
|
149
|
+
log.help(messages.devinit.ciIntro(git, this.clientDetailsLocation));
|
|
150
|
+
} else {
|
|
151
|
+
// Look at the workflow file content and make updates
|
|
152
|
+
mappedWorkflow = await mapCIWorkflowContent(this);
|
|
153
|
+
log.help(messages.devinit.ciIntro(git, this.clientDetailsLocation));
|
|
154
|
+
}
|
|
123
155
|
|
|
124
156
|
if (!dryRun) {
|
|
125
157
|
// Confirm prompt
|
|
@@ -136,16 +168,37 @@ class ContensisDev extends ContensisRole {
|
|
|
136
168
|
}
|
|
137
169
|
|
|
138
170
|
// Access token prompt
|
|
139
|
-
|
|
171
|
+
let accessToken: string | undefined = undefined;
|
|
172
|
+
const { canContinue } = await inquirer.prompt([
|
|
140
173
|
{
|
|
141
|
-
type: '
|
|
174
|
+
type: 'confirm',
|
|
142
175
|
prefix: '🛡️',
|
|
176
|
+
// We're all set to grab your access token. Can we proceed? (⏎ continue)
|
|
143
177
|
message: messages.devinit.accessTokenPrompt(),
|
|
144
|
-
name: '
|
|
178
|
+
name: 'canContinue',
|
|
145
179
|
},
|
|
146
180
|
]);
|
|
147
181
|
log.raw('');
|
|
148
182
|
|
|
183
|
+
if (!canContinue) return;
|
|
184
|
+
if (canContinue) {
|
|
185
|
+
const spinner = createSpinner(messages.devinit.accessTokenFetch());
|
|
186
|
+
spinner.start();
|
|
187
|
+
|
|
188
|
+
// Fetching access token
|
|
189
|
+
const token = await this.GetDeliveryApiKey();
|
|
190
|
+
|
|
191
|
+
if (token) {
|
|
192
|
+
spinner.success();
|
|
193
|
+
this.log.success(messages.devinit.accessTokenSuccess(token));
|
|
194
|
+
accessToken = token;
|
|
195
|
+
} else {
|
|
196
|
+
spinner.error();
|
|
197
|
+
this.log.error(messages.devinit.accessTokenFailed());
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
149
202
|
// Magic happens...
|
|
150
203
|
const checkpoint = (op: string) => {
|
|
151
204
|
if (errors.length) throw errors[0];
|
|
@@ -207,6 +260,12 @@ class ContensisDev extends ContensisRole {
|
|
|
207
260
|
PROJECT: currentProject,
|
|
208
261
|
};
|
|
209
262
|
if (accessToken) envContentsToAdd['ACCESS_TOKEN'] = accessToken;
|
|
263
|
+
if (this.clientDetailsLocation === 'env') {
|
|
264
|
+
if (git.type === 'github') {
|
|
265
|
+
envContentsToAdd['CONTENSIS_CLIENT_ID'] = this.clientId;
|
|
266
|
+
envContentsToAdd['CONTENSIS_CLIENT_SECRET'] = this.clientSecret;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
210
269
|
|
|
211
270
|
const envFilePath = `${projectHome}/.env`;
|
|
212
271
|
const existingEnvFile = readFile(envFilePath);
|
|
@@ -214,9 +273,7 @@ class ContensisDev extends ContensisRole {
|
|
|
214
273
|
(existingEnvFile || '').split('\n').filter(l => !!l),
|
|
215
274
|
envContentsToAdd
|
|
216
275
|
);
|
|
217
|
-
const newEnvFileContent =
|
|
218
|
-
`${envFileLines.join('\n')}\n`
|
|
219
|
-
);
|
|
276
|
+
const newEnvFileContent = envFileLines.join('\n');
|
|
220
277
|
const envDiff = diffFileContent(existingEnvFile || '', newEnvFileContent);
|
|
221
278
|
|
|
222
279
|
if (dryRun) {
|
|
@@ -258,15 +315,17 @@ class ContensisDev extends ContensisRole {
|
|
|
258
315
|
}
|
|
259
316
|
}
|
|
260
317
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
318
|
+
if (this.clientDetailsLocation === 'git') {
|
|
319
|
+
// Echo Deployment API key to console, ask user to add secrets to repo
|
|
320
|
+
log.warning(messages.devinit.addGitSecretsIntro());
|
|
321
|
+
log.help(
|
|
322
|
+
messages.devinit.addGitSecretsHelp(
|
|
323
|
+
git,
|
|
324
|
+
existingDeployKey?.id,
|
|
325
|
+
existingDeployKey?.sharedSecret
|
|
326
|
+
)
|
|
327
|
+
);
|
|
328
|
+
}
|
|
270
329
|
|
|
271
330
|
if (dryRun) {
|
|
272
331
|
log.success(messages.devinit.dryRun());
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { Role } from 'contensis-management-api/lib/models';
|
|
2
2
|
import { ApiKey, MigrateRequest } from 'migratortron';
|
|
3
|
-
|
|
3
|
+
import to from 'await-to-js';
|
|
4
4
|
import ContensisCli from './ContensisCliService';
|
|
5
5
|
import { OutputOptionsConstructorArg } from '~/models/CliService';
|
|
6
|
+
import { Logger } from '~/util/logger';
|
|
6
7
|
|
|
7
8
|
class ContensisRole extends ContensisCli {
|
|
8
9
|
constructor(
|
|
@@ -13,6 +14,37 @@ class ContensisRole extends ContensisCli {
|
|
|
13
14
|
super(args, outputOpts, contensisOpts);
|
|
14
15
|
}
|
|
15
16
|
|
|
17
|
+
GetDeliveryApiKey = async () => {
|
|
18
|
+
const { contensis, currentEnv } = this;
|
|
19
|
+
|
|
20
|
+
const CMS = `https://cms-${currentEnv}.cloud.contensis.com`;
|
|
21
|
+
const API = 'api/contensis-cli/settings/defaultDeliveryApiAccessToken';
|
|
22
|
+
|
|
23
|
+
if (contensis) {
|
|
24
|
+
const [error, bearerToken] = await to(
|
|
25
|
+
contensis.content.sourceRepo.repo.BearerToken()
|
|
26
|
+
);
|
|
27
|
+
if (error) Logger.error(error.message);
|
|
28
|
+
|
|
29
|
+
const token = fetch(`${CMS}/${API}`, {
|
|
30
|
+
method: 'GET',
|
|
31
|
+
headers: {
|
|
32
|
+
'Content-Type': 'application/json',
|
|
33
|
+
Authorization: `Bearer ${bearerToken}`,
|
|
34
|
+
},
|
|
35
|
+
})
|
|
36
|
+
.then(repsonse => repsonse.json())
|
|
37
|
+
.then(({ value }) => {
|
|
38
|
+
if (value) return value;
|
|
39
|
+
})
|
|
40
|
+
.catch(error => {
|
|
41
|
+
throw new Error(error);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
return token;
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
|
|
16
48
|
CreateOrUpdateApiKey = async (
|
|
17
49
|
existingKey: ApiKey | undefined,
|
|
18
50
|
name: string,
|
package/src/util/diff.ts
CHANGED
|
@@ -47,7 +47,10 @@ export const diffFileContent = (
|
|
|
47
47
|
const colour = part.added ? 'green' : part.removed ? 'red' : 'grey';
|
|
48
48
|
|
|
49
49
|
if (part.value !== '\n') {
|
|
50
|
-
if (needsNewLine)
|
|
50
|
+
if (needsNewLine) {
|
|
51
|
+
output.push('\n### --');
|
|
52
|
+
needsNewLine = false;
|
|
53
|
+
}
|
|
51
54
|
output.push(
|
|
52
55
|
`\n${part.value
|
|
53
56
|
.split('\n')
|
package/src/util/git.ts
CHANGED
|
@@ -111,13 +111,14 @@ export class GitHelper {
|
|
|
111
111
|
githubWorkflows = () => {
|
|
112
112
|
const workflowPath = path.join(this.gitcwd(), '.github/workflows');
|
|
113
113
|
const workflowFiles = readFiles(workflowPath, false);
|
|
114
|
-
// console.log('gh workflows: ', workflowFiles);
|
|
115
114
|
const addFolderSuffix = (files: string[]) =>
|
|
116
115
|
files.map(f => `.github/workflows/${f}`);
|
|
117
116
|
|
|
118
|
-
if (workflowFiles.some(f => f.includes('build')))
|
|
117
|
+
if (workflowFiles.some(f => f.includes('build'))) {
|
|
119
118
|
return addFolderSuffix(workflowFiles.filter(f => f.includes('build')));
|
|
120
|
-
|
|
119
|
+
} else {
|
|
120
|
+
return addFolderSuffix(workflowFiles);
|
|
121
|
+
}
|
|
121
122
|
};
|
|
122
123
|
gitlabWorkflow = (ciFileName = GITLAB_CI_FILENAME) => {
|
|
123
124
|
const workflowPath = this.gitcwd();
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const LIB_VERSION = "1.0.0-beta.
|
|
1
|
+
export const LIB_VERSION = "1.0.0-beta.97";
|