@adinsure-ops/ops-cli 4.0.0-rc10
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/CHANGELOGS.md +56 -0
- package/LICENSE +1 -0
- package/README.md +725 -0
- package/bin/run +5 -0
- package/bin/run.cmd +3 -0
- package/lib/command.base.d.ts +17 -0
- package/lib/command.base.jira.d.ts +11 -0
- package/lib/command.base.jira.js +37 -0
- package/lib/command.base.js +73 -0
- package/lib/commands/doctor.d.ts +54 -0
- package/lib/commands/doctor.js +311 -0
- package/lib/commands/download/client.d.ts +17 -0
- package/lib/commands/download/client.js +71 -0
- package/lib/commands/download/identity-server.d.ts +17 -0
- package/lib/commands/download/identity-server.js +71 -0
- package/lib/commands/download/platform.d.ts +18 -0
- package/lib/commands/download/platform.js +72 -0
- package/lib/commands/download/scheduler.d.ts +17 -0
- package/lib/commands/download/scheduler.js +71 -0
- package/lib/commands/download/server.d.ts +17 -0
- package/lib/commands/download/server.js +71 -0
- package/lib/commands/download/studio.d.ts +19 -0
- package/lib/commands/download/studio.js +88 -0
- package/lib/commands/gitlab/next-nightly-tag.d.ts +29 -0
- package/lib/commands/gitlab/next-nightly-tag.js +169 -0
- package/lib/commands/jira/issue.d.ts +17 -0
- package/lib/commands/jira/issue.js +31 -0
- package/lib/commands/jira/labels.d.ts +22 -0
- package/lib/commands/jira/labels.js +70 -0
- package/lib/commands/log/add.d.ts +17 -0
- package/lib/commands/log/add.js +107 -0
- package/lib/commands/log/generate.d.ts +22 -0
- package/lib/commands/log/generate.js +155 -0
- package/lib/commands/log/validate.d.ts +11 -0
- package/lib/commands/log/validate.js +58 -0
- package/lib/commands/login.d.ts +24 -0
- package/lib/commands/login.js +154 -0
- package/lib/commands/npm/check-publish.d.ts +16 -0
- package/lib/commands/npm/check-publish.js +77 -0
- package/lib/commands/npm/publish.d.ts +22 -0
- package/lib/commands/npm/publish.js +162 -0
- package/lib/commands/prepare-content.d.ts +29 -0
- package/lib/commands/prepare-content.js +386 -0
- package/lib/commands/sql.d.ts +24 -0
- package/lib/commands/sql.js +147 -0
- package/lib/commands/translate.d.ts +37 -0
- package/lib/commands/translate.js +149 -0
- package/lib/commands/version.d.ts +48 -0
- package/lib/commands/version.js +267 -0
- package/lib/config.d.ts +7 -0
- package/lib/config.js +9 -0
- package/lib/hooks/init/version-override.d.ts +2 -0
- package/lib/hooks/init/version-override.js +15 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +4 -0
- package/lib/lib/command.d.ts +9 -0
- package/lib/lib/command.js +71 -0
- package/lib/lib/npm.d.ts +15 -0
- package/lib/lib/npm.js +79 -0
- package/lib/lib/npmrc.d.ts +17 -0
- package/lib/lib/npmrc.js +44 -0
- package/lib/security/cache.d.ts +7 -0
- package/lib/security/cache.js +33 -0
- package/lib/security/context.d.ts +58 -0
- package/lib/security/context.js +228 -0
- package/lib/types/changelog.types.d.ts +6 -0
- package/lib/types/changelog.types.js +2 -0
- package/lib/types/npm.types.d.ts +34 -0
- package/lib/types/npm.types.js +2 -0
- package/oclif.manifest.json +1 -0
- package/package.json +116 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const command_base_jira_1 = require("../../command.base.jira");
|
|
4
|
+
class JiraLabels extends command_base_jira_1.default {
|
|
5
|
+
async run() {
|
|
6
|
+
const { args, flags } = this.parse(JiraLabels);
|
|
7
|
+
const jira = await this.jiraInit(flags.hostname, flags.username, flags.password);
|
|
8
|
+
try {
|
|
9
|
+
let issue = await jira.findIssue(args.issue);
|
|
10
|
+
this.log(JSON.stringify(issue));
|
|
11
|
+
}
|
|
12
|
+
catch (err) {
|
|
13
|
+
this.error(err);
|
|
14
|
+
this.exit(1);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
exports.default = JiraLabels;
|
|
19
|
+
JiraLabels.description = 'get Jira issue';
|
|
20
|
+
JiraLabels.usage = 'jira:issue <issue>';
|
|
21
|
+
JiraLabels.examples = [
|
|
22
|
+
`$ ops jira:issue LJADIRD-1337`,
|
|
23
|
+
];
|
|
24
|
+
JiraLabels.args = [
|
|
25
|
+
{
|
|
26
|
+
name: 'issue',
|
|
27
|
+
description: 'Jira issue number',
|
|
28
|
+
required: true
|
|
29
|
+
}
|
|
30
|
+
];
|
|
31
|
+
JiraLabels.flags = Object.assign({}, command_base_jira_1.default.flags);
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { flags } from '@oclif/command';
|
|
2
|
+
import JiraApi = require('jira-client');
|
|
3
|
+
import CommandBaseJira from '../../command.base.jira';
|
|
4
|
+
export default class JiraLabels extends CommandBaseJira {
|
|
5
|
+
static description: string;
|
|
6
|
+
static usage: string;
|
|
7
|
+
static examples: string[];
|
|
8
|
+
static args: {
|
|
9
|
+
name: string;
|
|
10
|
+
description: string;
|
|
11
|
+
required: boolean;
|
|
12
|
+
}[];
|
|
13
|
+
static flags: {
|
|
14
|
+
add: flags.IOptionFlag<string[]>;
|
|
15
|
+
remove: flags.IOptionFlag<string[]>;
|
|
16
|
+
username: flags.IOptionFlag<string>;
|
|
17
|
+
password: flags.IOptionFlag<string>;
|
|
18
|
+
hostname: flags.IOptionFlag<string>;
|
|
19
|
+
};
|
|
20
|
+
setLabels(jira: JiraApi, issue: string, add?: string[], remove?: string[]): Promise<JiraApi.JsonResponse>;
|
|
21
|
+
run(): Promise<void>;
|
|
22
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const command_1 = require("@oclif/command");
|
|
4
|
+
const chalk_1 = require("chalk");
|
|
5
|
+
const cli_ux_1 = require("cli-ux");
|
|
6
|
+
const command_base_jira_1 = require("../../command.base.jira");
|
|
7
|
+
class JiraLabels extends command_base_jira_1.default {
|
|
8
|
+
async setLabels(jira, issue, add = [], remove = []) {
|
|
9
|
+
let labels = [];
|
|
10
|
+
add.forEach(label => {
|
|
11
|
+
let add = {
|
|
12
|
+
add: label
|
|
13
|
+
};
|
|
14
|
+
labels.push(add);
|
|
15
|
+
});
|
|
16
|
+
remove.forEach(label => {
|
|
17
|
+
let remove = {
|
|
18
|
+
remove: label
|
|
19
|
+
};
|
|
20
|
+
labels.push(remove);
|
|
21
|
+
});
|
|
22
|
+
let edit = {
|
|
23
|
+
update: {
|
|
24
|
+
labels
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
return jira.updateIssue(issue, edit);
|
|
28
|
+
}
|
|
29
|
+
async run() {
|
|
30
|
+
const { args, flags } = this.parse(JiraLabels);
|
|
31
|
+
const jira = await this.jiraInit(flags.hostname, flags.username, flags.password);
|
|
32
|
+
if (flags.remove || flags.add) {
|
|
33
|
+
cli_ux_1.default.action.start(`adding "${flags.add}" and removing "${flags.remove}" labels to Jira issue ${args.issue}`, undefined, { stdout: true });
|
|
34
|
+
try {
|
|
35
|
+
await this.setLabels(jira, args.issue, flags.add, flags.remove);
|
|
36
|
+
cli_ux_1.default.action.stop(`${chalk_1.default.green('done')}`);
|
|
37
|
+
}
|
|
38
|
+
catch (_a) {
|
|
39
|
+
cli_ux_1.default.action.stop(`${chalk_1.default.red('error')}`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
let issue = await jira.findIssue(args.issue);
|
|
44
|
+
this.log(JSON.stringify(issue.fields.labels));
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
exports.default = JiraLabels;
|
|
49
|
+
// static aliases = ['jira:edit:labels'];
|
|
50
|
+
JiraLabels.description = 'list or edit labels on Jira issue';
|
|
51
|
+
JiraLabels.usage = 'jira:labels <issue> -a [label] -r [label]';
|
|
52
|
+
JiraLabels.examples = [
|
|
53
|
+
`$ ops jira:labels LJADIRD-1337`,
|
|
54
|
+
];
|
|
55
|
+
JiraLabels.args = [
|
|
56
|
+
{
|
|
57
|
+
name: 'issue',
|
|
58
|
+
description: 'Jira issue number',
|
|
59
|
+
required: true
|
|
60
|
+
}
|
|
61
|
+
];
|
|
62
|
+
JiraLabels.flags = Object.assign(Object.assign({}, command_base_jira_1.default.flags), { add: command_1.flags.string({
|
|
63
|
+
char: 'a',
|
|
64
|
+
description: 'add label',
|
|
65
|
+
multiple: true
|
|
66
|
+
}), remove: command_1.flags.string({
|
|
67
|
+
char: 'r',
|
|
68
|
+
description: 'remove label',
|
|
69
|
+
multiple: true
|
|
70
|
+
}) });
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { flags } from '@oclif/command';
|
|
2
|
+
import CommandBase from '../../command.base';
|
|
3
|
+
export default class Changelog extends CommandBase {
|
|
4
|
+
static aliases: string[];
|
|
5
|
+
static description: string;
|
|
6
|
+
static usage: string;
|
|
7
|
+
static examples: string[];
|
|
8
|
+
static args: {
|
|
9
|
+
name: string;
|
|
10
|
+
description: string;
|
|
11
|
+
}[];
|
|
12
|
+
static flags: {
|
|
13
|
+
type: flags.IOptionFlag<string | undefined>;
|
|
14
|
+
component: flags.IOptionFlag<string>;
|
|
15
|
+
};
|
|
16
|
+
run(): Promise<void>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const command_1 = require("@oclif/command");
|
|
4
|
+
const fs = require("fs-extra");
|
|
5
|
+
const matter = require("gray-matter");
|
|
6
|
+
const inquirer = require("inquirer");
|
|
7
|
+
const path = require("path");
|
|
8
|
+
const command_base_1 = require("../../command.base");
|
|
9
|
+
class Changelog extends command_base_1.default {
|
|
10
|
+
async run() {
|
|
11
|
+
const { args, flags } = this.parse(Changelog);
|
|
12
|
+
// Validation of input parameters
|
|
13
|
+
let changelogFolderBase = await this.getChangelogsRoot();
|
|
14
|
+
let possibleComponents = new Array();
|
|
15
|
+
fs.readdirSync(changelogFolderBase).forEach(file => {
|
|
16
|
+
if (fs.statSync(path.resolve(changelogFolderBase, file)).isDirectory()) {
|
|
17
|
+
possibleComponents.push(file);
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
// Validate JIRA ticket
|
|
21
|
+
const issueRegex = /\w+-\d+/;
|
|
22
|
+
let changelogIssue = args.issue;
|
|
23
|
+
if (!issueRegex.test(changelogIssue)) {
|
|
24
|
+
let responses = await inquirer.prompt([{
|
|
25
|
+
name: 'issue',
|
|
26
|
+
message: 'select a JIRA issue',
|
|
27
|
+
type: 'input',
|
|
28
|
+
validate(value) {
|
|
29
|
+
if (issueRegex.test(value)) {
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
return 'Please enter a valid JIRA ticket';
|
|
33
|
+
}
|
|
34
|
+
}]);
|
|
35
|
+
changelogIssue = responses.issue;
|
|
36
|
+
}
|
|
37
|
+
// Validate changelog type
|
|
38
|
+
let changelogType = flags.type;
|
|
39
|
+
if (!changelogType) {
|
|
40
|
+
let responses = await inquirer.prompt([{
|
|
41
|
+
name: 'type',
|
|
42
|
+
message: 'select a changelog type',
|
|
43
|
+
type: 'list',
|
|
44
|
+
choices: [{ name: 'feature' }, { name: 'fixed' }, { name: 'improve' }, { name: 'breaking' }],
|
|
45
|
+
}]);
|
|
46
|
+
changelogType = responses.type;
|
|
47
|
+
}
|
|
48
|
+
// Validate changelog component
|
|
49
|
+
let changelogComponent = flags.component;
|
|
50
|
+
let changelogFolder = path.resolve(changelogFolderBase, changelogComponent);
|
|
51
|
+
if ((possibleComponents.length !== 0 && !changelogComponent) || !fs.pathExistsSync(path.resolve(changelogFolderBase, changelogComponent))) {
|
|
52
|
+
let responses = await inquirer.prompt([{
|
|
53
|
+
name: 'component',
|
|
54
|
+
message: 'Multiple components found. Select a changelog componet',
|
|
55
|
+
type: 'list',
|
|
56
|
+
choices: possibleComponents
|
|
57
|
+
}]);
|
|
58
|
+
changelogComponent = responses.component;
|
|
59
|
+
changelogFolder = path.resolve(changelogFolderBase, changelogComponent);
|
|
60
|
+
}
|
|
61
|
+
let fileName = `${changelogIssue.toUpperCase()}.md`;
|
|
62
|
+
let changelogPath = path.resolve(changelogFolder, fileName);
|
|
63
|
+
if (!(await fs.pathExists(changelogFolder))) {
|
|
64
|
+
await fs.mkdirp(changelogFolder);
|
|
65
|
+
}
|
|
66
|
+
if (await fs.pathExists(changelogPath)) {
|
|
67
|
+
this.error(`Changelog for '${changelogIssue}' in '${changelogComponent}' already exists`);
|
|
68
|
+
}
|
|
69
|
+
let entry = {
|
|
70
|
+
meta: {
|
|
71
|
+
issue: changelogIssue,
|
|
72
|
+
type: changelogType,
|
|
73
|
+
},
|
|
74
|
+
content: 'Explain your changes here'
|
|
75
|
+
};
|
|
76
|
+
await fs.writeFile(changelogPath, matter.stringify(entry.content, entry.meta));
|
|
77
|
+
this.log(`Created changelog for ${changelogIssue} in '${changelogPath}'`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
exports.default = Changelog;
|
|
81
|
+
Changelog.aliases = ['log', 'log:add'];
|
|
82
|
+
Changelog.description = 'creates a new changelog entry';
|
|
83
|
+
Changelog.usage = 'log <issue> -t [type] -c [options]';
|
|
84
|
+
Changelog.examples = [
|
|
85
|
+
`$ ops log LJADIRD-1234 -t feature`,
|
|
86
|
+
`$ ops log LJADIRD-5678 -t fixed`,
|
|
87
|
+
`$ ops log LJADIRD-8765 -t breaking -c Platform`,
|
|
88
|
+
`$ ops log LJADIRD-4321 -t improve -c Configuration`
|
|
89
|
+
];
|
|
90
|
+
Changelog.args = [
|
|
91
|
+
{
|
|
92
|
+
name: 'issue',
|
|
93
|
+
description: 'Jira issue number'
|
|
94
|
+
}
|
|
95
|
+
];
|
|
96
|
+
Changelog.flags = {
|
|
97
|
+
type: command_1.flags.string({
|
|
98
|
+
char: 't',
|
|
99
|
+
description: 'type of changelog',
|
|
100
|
+
options: ['feature', 'fixed', 'improve', 'breaking'],
|
|
101
|
+
}),
|
|
102
|
+
component: command_1.flags.string({
|
|
103
|
+
char: 'c',
|
|
104
|
+
description: 'Component for which new changelog should be generated',
|
|
105
|
+
default: ''
|
|
106
|
+
})
|
|
107
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { flags } from '@oclif/command';
|
|
2
|
+
import CommandBase from '../../command.base';
|
|
3
|
+
import { ChangelogEntry } from '../../types/changelog.types';
|
|
4
|
+
export default class Generate extends CommandBase {
|
|
5
|
+
static aliases: string[];
|
|
6
|
+
static description: string;
|
|
7
|
+
static usage: string;
|
|
8
|
+
static examples: string[];
|
|
9
|
+
static flags: {
|
|
10
|
+
components: flags.IOptionFlag<string>;
|
|
11
|
+
file: flags.IOptionFlag<string>;
|
|
12
|
+
force: import("@oclif/parser/lib/flags").IBooleanFlag<boolean>;
|
|
13
|
+
preview: import("@oclif/parser/lib/flags").IBooleanFlag<boolean>;
|
|
14
|
+
version: flags.IOptionFlag<string | undefined>;
|
|
15
|
+
'ignore-no-changelogs': import("@oclif/parser/lib/flags").IBooleanFlag<boolean>;
|
|
16
|
+
};
|
|
17
|
+
private readonly _entryTypes;
|
|
18
|
+
private readonly _mdFileTypeRegex;
|
|
19
|
+
readChangelogs(dir: string): Promise<ChangelogEntry[]>;
|
|
20
|
+
generateLog(entries: ChangelogEntry[], components: string[]): Promise<string>;
|
|
21
|
+
run(): Promise<void>;
|
|
22
|
+
}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const command_1 = require("@oclif/command");
|
|
4
|
+
const cli_ux_1 = require("cli-ux");
|
|
5
|
+
const fs = require("fs-extra");
|
|
6
|
+
const matter = require("gray-matter");
|
|
7
|
+
const _ = require("lodash");
|
|
8
|
+
const moment = require("moment");
|
|
9
|
+
const path = require("path");
|
|
10
|
+
const rimraf = require("rimraf");
|
|
11
|
+
const command_base_1 = require("../../command.base");
|
|
12
|
+
class Generate extends command_base_1.default {
|
|
13
|
+
constructor() {
|
|
14
|
+
super(...arguments);
|
|
15
|
+
this._entryTypes = [
|
|
16
|
+
{ types: ['BreakingChange', 'breaking'], text: 'Breaking Changes' },
|
|
17
|
+
{ types: ['Feature', 'feature'], text: 'New Features' },
|
|
18
|
+
{ types: ['Improvement', 'improve'], text: 'Improvements' },
|
|
19
|
+
{ types: ['Fixed', 'fixed'], text: 'Fixed' }
|
|
20
|
+
];
|
|
21
|
+
this._mdFileTypeRegex = /\.md$/i;
|
|
22
|
+
}
|
|
23
|
+
async readChangelogs(dir) {
|
|
24
|
+
let result = [];
|
|
25
|
+
let files = await this.getFilesRecursive(dir, dir, this._mdFileTypeRegex);
|
|
26
|
+
for (let fileName of files) {
|
|
27
|
+
let filePath = path.resolve(dir, fileName);
|
|
28
|
+
let fileComponent = path.basename(path.dirname(filePath));
|
|
29
|
+
fileComponent = fileComponent === 'unreleased' ? '' : fileComponent;
|
|
30
|
+
let contents = matter.read(filePath);
|
|
31
|
+
result.push({
|
|
32
|
+
type: contents.data.type,
|
|
33
|
+
issue: contents.data.issue,
|
|
34
|
+
component: fileComponent,
|
|
35
|
+
content: contents.content.trim()
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
return result;
|
|
39
|
+
}
|
|
40
|
+
async generateLog(entries, components) {
|
|
41
|
+
let content = '';
|
|
42
|
+
// First group by component, then re-sort the components to get the desired output ordering
|
|
43
|
+
let componentGroups = _.groupBy(entries, 'component');
|
|
44
|
+
for (let group of components) {
|
|
45
|
+
if (group !== '') {
|
|
46
|
+
content += `## ${_.capitalize(group)}\r\n\r\n`;
|
|
47
|
+
}
|
|
48
|
+
// tslint:disable-next-line: strict-type-predicates
|
|
49
|
+
if (componentGroups[group] === undefined || componentGroups[group].length === 0) {
|
|
50
|
+
content += `No changes were introduced in this version.\r\n\r\n`;
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
for (let type of this._entryTypes) {
|
|
54
|
+
let batch = _.remove(componentGroups[group], e => _.indexOf(type.types, e.type) > -1);
|
|
55
|
+
if (batch.length === 0) {
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
content += `### ${type.text} (${batch.length} changes)\r\n\r\n`;
|
|
59
|
+
for (let log of batch) {
|
|
60
|
+
if (log.content.startsWith('-') || log.content.startsWith('* ')) {
|
|
61
|
+
content += `- [${log.issue}](https://jira.adacta-fintech.com/browse/${log.issue}):\r\n`;
|
|
62
|
+
content += ' ' + log.content.replace(/\n/g, '\n ');
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
content += `- [${log.issue}](https://jira.adacta-fintech.com/browse/${log.issue}): `;
|
|
66
|
+
content += log.content.replace(/\n/g, '\n ') + '\r\n';
|
|
67
|
+
}
|
|
68
|
+
content += '\r\n';
|
|
69
|
+
}
|
|
70
|
+
content += '\r\n';
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
// We only want 1 new line at the end of this changelog
|
|
74
|
+
return content.trimRight() + '\r\n\r\n';
|
|
75
|
+
}
|
|
76
|
+
async run() {
|
|
77
|
+
const { flags } = this.parse(Generate);
|
|
78
|
+
const root = path.resolve(process.cwd());
|
|
79
|
+
const changelogFolder = await this.getChangelogsRoot();
|
|
80
|
+
const version = flags.version || await this.getVersion();
|
|
81
|
+
const components = flags.components.split(',');
|
|
82
|
+
this.log(`Inspecting ${changelogFolder} ...`);
|
|
83
|
+
cli_ux_1.default.action.start(`generating for ${version}`, undefined, { stdout: true });
|
|
84
|
+
let changelogs = await this.readChangelogs(changelogFolder);
|
|
85
|
+
if (!flags['ignore-no-changelogs'] && !changelogs.length) {
|
|
86
|
+
cli_ux_1.default.action.stop('done, no changelogs found.');
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
const content = `# ${version} (${moment().format('YYYY-MM-DD')})\r\n\r\n${await this.generateLog(changelogs, components)}`;
|
|
90
|
+
if (flags.preview) {
|
|
91
|
+
fs.writeFileSync(path.resolve(root, 'preview.md'), content, 'utf-8');
|
|
92
|
+
cli_ux_1.default.action.stop('generated preview.md');
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
this.warn(`The following action will update ${flags.file} and remove all unreleased changelogs in '${changelogFolder}'`);
|
|
96
|
+
const confirm = flags.force || await cli_ux_1.default.confirm(`Do you want to continue? [y/n/yes/no]`);
|
|
97
|
+
if (confirm) {
|
|
98
|
+
let changelogFile = path.resolve(root, flags.file);
|
|
99
|
+
const currentContents = fs.readFileSync(changelogFile, { encoding: 'utf-8', flag: 'a+' });
|
|
100
|
+
fs.writeFileSync(changelogFile, content + currentContents, { encoding: 'utf-8', flag: 'w' });
|
|
101
|
+
// delete unreleased changelogs
|
|
102
|
+
for (let group of components) {
|
|
103
|
+
let componentChangelogFolder = path.join(changelogFolder, group);
|
|
104
|
+
this.log(`Removing unreleased changelogs from ${componentChangelogFolder}`);
|
|
105
|
+
let changelogFiles = await fs.readdir(componentChangelogFolder);
|
|
106
|
+
for (let file of changelogFiles) {
|
|
107
|
+
if (this._mdFileTypeRegex.test(file)) {
|
|
108
|
+
rimraf.sync(path.resolve(componentChangelogFolder, file));
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
cli_ux_1.default.action.stop('done');
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
exports.default = Generate;
|
|
117
|
+
Generate.aliases = ['log:gen'];
|
|
118
|
+
Generate.description = 'generates final changelog from unreleased notes';
|
|
119
|
+
Generate.usage = 'log:gen [options]';
|
|
120
|
+
Generate.examples = [
|
|
121
|
+
`$ ops log:gen`,
|
|
122
|
+
`$ ops log:gen -p`,
|
|
123
|
+
`$ ops log:gen -c Platform`,
|
|
124
|
+
`$ ops log:gen -c Platform,Configuration`,
|
|
125
|
+
`$ ops log:gen -c Implementation -f CHANGELOG.Implementation.md`
|
|
126
|
+
];
|
|
127
|
+
Generate.flags = {
|
|
128
|
+
components: command_1.flags.string({
|
|
129
|
+
char: 'c',
|
|
130
|
+
description: 'components separated by comma (,) to process for final changelog',
|
|
131
|
+
default: ''
|
|
132
|
+
}),
|
|
133
|
+
file: command_1.flags.string({
|
|
134
|
+
char: 'f',
|
|
135
|
+
description: 'file to update with new changelogs',
|
|
136
|
+
default: 'CHANGELOG.md'
|
|
137
|
+
}),
|
|
138
|
+
force: command_1.flags.boolean({
|
|
139
|
+
description: 'update target file without prompting for confirmation',
|
|
140
|
+
default: false
|
|
141
|
+
}),
|
|
142
|
+
preview: command_1.flags.boolean({
|
|
143
|
+
char: 'p',
|
|
144
|
+
description: 'generates a preview markdown of current unreleased changelogs',
|
|
145
|
+
default: false
|
|
146
|
+
}),
|
|
147
|
+
version: command_1.flags.string({
|
|
148
|
+
char: 'v',
|
|
149
|
+
description: 'version for which you\'re generating changelogs'
|
|
150
|
+
}),
|
|
151
|
+
'ignore-no-changelogs': command_1.flags.boolean({
|
|
152
|
+
description: 'generate final changelog even if no unreleased changelogs exist',
|
|
153
|
+
default: false
|
|
154
|
+
})
|
|
155
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import CommandBase from '../../command.base';
|
|
2
|
+
export default class Validate extends CommandBase {
|
|
3
|
+
static aliases: string[];
|
|
4
|
+
static description: string;
|
|
5
|
+
static usage: string;
|
|
6
|
+
static examples: string[];
|
|
7
|
+
private readonly _typeRegex;
|
|
8
|
+
private readonly _issueRegex;
|
|
9
|
+
getProblems(path: string): Promise<string[]>;
|
|
10
|
+
run(): Promise<void>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const cli_ux_1 = require("cli-ux");
|
|
4
|
+
const matter = require("gray-matter");
|
|
5
|
+
const path = require("path");
|
|
6
|
+
const command_base_1 = require("../../command.base");
|
|
7
|
+
class Validate extends command_base_1.default {
|
|
8
|
+
constructor() {
|
|
9
|
+
super(...arguments);
|
|
10
|
+
// Added capitalized types for compatibility with current scripts until we migrate away
|
|
11
|
+
this._typeRegex = /^(feature|fixed|improve|breaking|Fixed|BreakingChange|Improvement|Feature)$/;
|
|
12
|
+
this._issueRegex = /\w+-\d+/;
|
|
13
|
+
}
|
|
14
|
+
async getProblems(path) {
|
|
15
|
+
let problems = [];
|
|
16
|
+
let contents = matter.read(path);
|
|
17
|
+
if (contents.data.issue === undefined) {
|
|
18
|
+
problems.push('Missing \'issue\' in front-matter');
|
|
19
|
+
}
|
|
20
|
+
else if (!this._issueRegex.test(contents.data.issue)) {
|
|
21
|
+
problems.push(`\'issue\' is not a valid Jira issue number (got: ${contents.data.issue})`);
|
|
22
|
+
}
|
|
23
|
+
if (contents.data.type === undefined) {
|
|
24
|
+
problems.push('Missing \'type\' in front-matter');
|
|
25
|
+
}
|
|
26
|
+
else if (!this._typeRegex.test(contents.data.type)) {
|
|
27
|
+
problems.push(`Invalid \'type\' used (got: ${contents.data.type})`);
|
|
28
|
+
}
|
|
29
|
+
return problems;
|
|
30
|
+
}
|
|
31
|
+
async run() {
|
|
32
|
+
const directory = await this.getChangelogsRoot();
|
|
33
|
+
let files = await this.getFilesRecursive(directory, directory, /\.md$/i);
|
|
34
|
+
cli_ux_1.default.action.start('validating changelogs', undefined, { stdout: true });
|
|
35
|
+
let problemsFound = 0;
|
|
36
|
+
for (let fileName of files) {
|
|
37
|
+
const filePath = path.resolve(directory, fileName);
|
|
38
|
+
const problems = await this.getProblems(filePath);
|
|
39
|
+
if (problems.length > 0) {
|
|
40
|
+
this.log(filePath);
|
|
41
|
+
problems.forEach(val => this.warn(val));
|
|
42
|
+
problemsFound += problems.length;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (problemsFound > 0) {
|
|
46
|
+
cli_ux_1.default.action.stop('failed');
|
|
47
|
+
this.error(`Found ${problemsFound} problem(s), please correct and re-run`, { exit: 1 });
|
|
48
|
+
}
|
|
49
|
+
cli_ux_1.default.action.stop('success');
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
exports.default = Validate;
|
|
53
|
+
Validate.aliases = ['log:validate'];
|
|
54
|
+
Validate.description = 'validates formatting of all unreleased changelogs';
|
|
55
|
+
Validate.usage = 'log:validate [options]';
|
|
56
|
+
Validate.examples = [
|
|
57
|
+
'$ ops log:validate'
|
|
58
|
+
];
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { flags } from '@oclif/command';
|
|
2
|
+
import CommandBase from '../command.base';
|
|
3
|
+
export default class Login extends CommandBase {
|
|
4
|
+
static description: string;
|
|
5
|
+
static usage: string;
|
|
6
|
+
static examples: string[];
|
|
7
|
+
static flags: {
|
|
8
|
+
servicePrincipal: import("@oclif/parser/lib/flags").IBooleanFlag<boolean>;
|
|
9
|
+
deviceFlow: import("@oclif/parser/lib/flags").IBooleanFlag<boolean>;
|
|
10
|
+
clientId: flags.IOptionFlag<string | undefined>;
|
|
11
|
+
secret: flags.IOptionFlag<string | undefined>;
|
|
12
|
+
npm: import("@oclif/parser/lib/flags").IBooleanFlag<boolean>;
|
|
13
|
+
skipCI: flags.IOptionFlag<string | undefined>;
|
|
14
|
+
};
|
|
15
|
+
static responsePageContent: string;
|
|
16
|
+
private readonly npmRegistries;
|
|
17
|
+
/**
|
|
18
|
+
* Get NPM token for adinsure npm repositories
|
|
19
|
+
*
|
|
20
|
+
* @returns [[Promise<string>]]
|
|
21
|
+
*/
|
|
22
|
+
setNPM(): Promise<void>;
|
|
23
|
+
run(): Promise<void>;
|
|
24
|
+
}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const command_1 = require("@oclif/command");
|
|
4
|
+
const chalk_1 = require("chalk");
|
|
5
|
+
const http = require("http");
|
|
6
|
+
const open = require("open");
|
|
7
|
+
const url = require("url");
|
|
8
|
+
const command_base_1 = require("../command.base");
|
|
9
|
+
const npmrc_1 = require("../lib/npmrc");
|
|
10
|
+
class Login extends command_base_1.default {
|
|
11
|
+
constructor() {
|
|
12
|
+
super(...arguments);
|
|
13
|
+
this.npmRegistries = [
|
|
14
|
+
'https://pkgs.dev.azure.com/adacta-fintech/adinsure/_packaging/feed/npm/registry/',
|
|
15
|
+
'https://pkgs.dev.azure.com/adinsure-test/_packaging/TestFeed/npm/registry/',
|
|
16
|
+
];
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Get NPM token for adinsure npm repositories
|
|
20
|
+
*
|
|
21
|
+
* @returns [[Promise<string>]]
|
|
22
|
+
*/
|
|
23
|
+
async setNPM() {
|
|
24
|
+
return new Promise(async (resolve, reject) => {
|
|
25
|
+
try {
|
|
26
|
+
let npmRc = new npmrc_1.default();
|
|
27
|
+
let token;
|
|
28
|
+
token = await this.security.getNPMToken();
|
|
29
|
+
this.npmRegistries.forEach(registry => {
|
|
30
|
+
const registryUrl = url.parse(registry);
|
|
31
|
+
// tslint:disable-next-line: no-floating-promises
|
|
32
|
+
npmRc.set(`//${registryUrl.hostname}${registryUrl.pathname}:_authToken`, token);
|
|
33
|
+
});
|
|
34
|
+
// tslint:disable-next-line: no-floating-promises
|
|
35
|
+
npmRc.save();
|
|
36
|
+
this.log(`${chalk_1.default.green('NPM token generated!')}`);
|
|
37
|
+
resolve();
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
reject(err);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
async run() {
|
|
45
|
+
const { flags } = this.parse(Login);
|
|
46
|
+
if (flags.skipCI && process.env[flags.skipCI]) {
|
|
47
|
+
this.log(`${chalk_1.default.yellow('Note: skipping login because variables was set for CI')}`);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
if (flags.npm) {
|
|
51
|
+
try {
|
|
52
|
+
await this.setNPM();
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
catch (_a) {
|
|
56
|
+
this.log(`${chalk_1.default.yellow('Note: Login is needed to get NPM token!')}`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
if (flags.deviceFlow) {
|
|
60
|
+
try {
|
|
61
|
+
await this.security.acquireTokenDeviceFlow();
|
|
62
|
+
this.log(`${chalk_1.default.green('Login Successful!')}`);
|
|
63
|
+
}
|
|
64
|
+
catch (err) {
|
|
65
|
+
this.error(err);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
else if (flags.servicePrincipal || flags.clientId || flags.secret) {
|
|
69
|
+
this.warn(`${chalk_1.default.red('[DEPRECATED] --servicePrincipal parameter is deprecated. To use with service principal, please set environment variables AZURE_CLIENT_ID and AZURE_CLIENT_SECRET! Login is not required!')}`);
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
this.log(`${chalk_1.default.yellow('Note: We have launched a browser for you to login.')}`);
|
|
73
|
+
let loginUrl = await this.security.getLoginUrl();
|
|
74
|
+
await open(loginUrl);
|
|
75
|
+
let server = http.createServer(async (req, res) => {
|
|
76
|
+
// First let the user know everything was OK
|
|
77
|
+
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
78
|
+
res.write(Login.responsePageContent);
|
|
79
|
+
res.end();
|
|
80
|
+
this.log(`${chalk_1.default.yellow('You have logged in successfully. Acquiring your access token...')}`);
|
|
81
|
+
// Then let's acquire an authentication token from AAD
|
|
82
|
+
try {
|
|
83
|
+
let query = url.parse(req.url, true).query;
|
|
84
|
+
let name = await this.security.acquireToken(query);
|
|
85
|
+
this.log(`Hello ${name}!`);
|
|
86
|
+
}
|
|
87
|
+
catch (err) {
|
|
88
|
+
this.error(err, { exit: false });
|
|
89
|
+
}
|
|
90
|
+
if (flags.npm) {
|
|
91
|
+
try {
|
|
92
|
+
await this.setNPM();
|
|
93
|
+
}
|
|
94
|
+
catch (err) {
|
|
95
|
+
this.error(err, { exit: false });
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
server.close();
|
|
99
|
+
});
|
|
100
|
+
server.listen(3044);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
exports.default = Login;
|
|
105
|
+
Login.description = 'log in to use ops services';
|
|
106
|
+
Login.usage = 'login';
|
|
107
|
+
Login.examples = [
|
|
108
|
+
`$ ops login`,
|
|
109
|
+
`$ ops login --npm`,
|
|
110
|
+
`$ ops login --skipCi CI`,
|
|
111
|
+
`$ ops login --deviceFlow`
|
|
112
|
+
];
|
|
113
|
+
Login.flags = {
|
|
114
|
+
servicePrincipal: command_1.flags.boolean({
|
|
115
|
+
description: 'authenticate using service principal credentials',
|
|
116
|
+
default: false
|
|
117
|
+
}),
|
|
118
|
+
deviceFlow: command_1.flags.boolean({
|
|
119
|
+
description: 'authenticate using device flow',
|
|
120
|
+
default: false
|
|
121
|
+
}),
|
|
122
|
+
clientId: command_1.flags.string({
|
|
123
|
+
char: 'c',
|
|
124
|
+
env: 'AZURE_CLIENT_ID',
|
|
125
|
+
description: '[DEPRECATED] (application) client id'
|
|
126
|
+
}),
|
|
127
|
+
secret: command_1.flags.string({
|
|
128
|
+
char: 's',
|
|
129
|
+
env: 'AZURE_CLIENT_SECRET',
|
|
130
|
+
description: '[DEPRECATED] client secret'
|
|
131
|
+
}),
|
|
132
|
+
npm: command_1.flags.boolean({
|
|
133
|
+
description: 'register also for npm',
|
|
134
|
+
default: false
|
|
135
|
+
}),
|
|
136
|
+
skipCI: command_1.flags.string({
|
|
137
|
+
description: 'Skip login if environment variables is set'
|
|
138
|
+
})
|
|
139
|
+
};
|
|
140
|
+
Login.responsePageContent = `
|
|
141
|
+
<!DOCTYPE html>
|
|
142
|
+
<html>
|
|
143
|
+
<head>
|
|
144
|
+
<title>ops-cli authenticate</title>
|
|
145
|
+
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
|
|
146
|
+
</head>
|
|
147
|
+
<body>
|
|
148
|
+
<p><strong>Your login was successful!</strong></p>
|
|
149
|
+
<p>This page will automatically close after 10 seconds OR you can close it yourself immediately.</p>
|
|
150
|
+
<script type="text/javascript">
|
|
151
|
+
setTimeout("self.close()", 10000);
|
|
152
|
+
</script>
|
|
153
|
+
</body>
|
|
154
|
+
</html>`;
|