heroku 11.0.0-alpha.3 → 11.0.0-alpha.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/lib/commands/local/index.d.ts +19 -0
- package/lib/commands/local/index.js +77 -0
- package/lib/commands/local/run.d.ts +11 -0
- package/lib/commands/local/run.js +37 -0
- package/lib/commands/local/version.d.ts +5 -0
- package/lib/commands/local/version.js +10 -0
- package/lib/commands/members/add.d.ts +13 -0
- package/lib/commands/members/add.js +32 -0
- package/lib/commands/members/index.d.ts +12 -0
- package/lib/commands/members/index.js +80 -0
- package/lib/commands/members/remove.d.ts +10 -0
- package/lib/commands/members/remove.js +43 -0
- package/lib/commands/members/set.d.ts +11 -0
- package/lib/commands/members/set.js +24 -0
- package/lib/commands/pipelines/add.d.ts +14 -0
- package/lib/commands/pipelines/add.js +58 -0
- package/lib/commands/pipelines/connect.d.ts +12 -0
- package/lib/commands/pipelines/connect.js +49 -0
- package/lib/commands/pipelines/create.d.ts +15 -0
- package/lib/commands/pipelines/create.js +89 -0
- package/lib/commands/pipelines/destroy.d.ts +9 -0
- package/lib/commands/pipelines/destroy.js +24 -0
- package/lib/commands/pipelines/diff.d.ts +20 -0
- package/lib/commands/pipelines/diff.js +156 -0
- package/lib/commands/pipelines/index.d.ts +9 -0
- package/lib/commands/pipelines/index.js +25 -0
- package/lib/commands/pipelines/info.d.ts +13 -0
- package/lib/commands/pipelines/info.js +41 -0
- package/lib/lib/local/env-file-validator.d.ts +1 -0
- package/lib/lib/local/env-file-validator.js +10 -0
- package/lib/lib/local/fork-foreman.js +7 -0
- package/lib/lib/local/load-foreman-procfile.d.ts +1 -2
- package/lib/lib/local/load-foreman-procfile.js +5 -1
- package/lib/lib/local/{run-foreman.js → run-foreman.cjs} +2 -1
- package/lib/lib/members/team-invite-utils.d.ts +14 -0
- package/lib/lib/members/team-invite-utils.js +26 -0
- package/lib/lib/pipelines/disambiguate.js +2 -2
- package/lib/lib/pipelines/ownership.d.ts +5 -1
- package/lib/lib/pipelines/ownership.js +33 -44
- package/lib/lib/pipelines/render-pipeline.d.ts +7 -1
- package/lib/lib/pipelines/render-pipeline.js +62 -68
- package/oclif.manifest.json +7573 -0
- package/package.json +7 -16
- package/lib/lib/members/utils.d.ts +0 -2
- package/lib/lib/members/utils.js +0 -10
- package/lib/oldCommands/local/index.d.ts +0 -1
- package/lib/oldCommands/local/index.js +0 -91
- package/lib/oldCommands/local/run.d.ts +0 -1
- package/lib/oldCommands/local/run.js +0 -54
- package/lib/oldCommands/local/version.d.ts +0 -1
- package/lib/oldCommands/local/version.js +0 -17
- package/lib/oldCommands/members/add.d.ts +0 -1
- package/lib/oldCommands/members/add.js +0 -36
- package/lib/oldCommands/members/index.d.ts +0 -1
- package/lib/oldCommands/members/index.js +0 -92
- package/lib/oldCommands/members/remove.d.ts +0 -1
- package/lib/oldCommands/members/remove.js +0 -70
- package/lib/oldCommands/members/set.d.ts +0 -1
- package/lib/oldCommands/members/set.js +0 -24
- package/lib/oldCommands/pipelines/add.d.ts +0 -1
- package/lib/oldCommands/pipelines/add.js +0 -70
- package/lib/oldCommands/pipelines/connect.d.ts +0 -1
- package/lib/oldCommands/pipelines/connect.js +0 -69
- package/lib/oldCommands/pipelines/create.d.ts +0 -1
- package/lib/oldCommands/pipelines/create.js +0 -105
- package/lib/oldCommands/pipelines/destroy.d.ts +0 -1
- package/lib/oldCommands/pipelines/destroy.js +0 -34
- package/lib/oldCommands/pipelines/diff.d.ts +0 -1
- package/lib/oldCommands/pipelines/diff.js +0 -202
- package/lib/oldCommands/pipelines/index.d.ts +0 -1
- package/lib/oldCommands/pipelines/index.js +0 -34
- package/lib/oldCommands/pipelines/info.d.ts +0 -1
- package/lib/oldCommands/pipelines/info.js +0 -51
- /package/lib/lib/local/{run-foreman.d.ts → run-foreman.d.cts} +0 -0
package/package.json
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "heroku",
|
|
3
3
|
"description": "CLI to interact with Heroku",
|
|
4
|
-
"version": "11.0.0-alpha.
|
|
4
|
+
"version": "11.0.0-alpha.6",
|
|
5
5
|
"author": "Heroku",
|
|
6
6
|
"bin": "./bin/run",
|
|
7
7
|
"bugs": "https://github.com/heroku/cli/issues",
|
|
8
8
|
"dependencies": {
|
|
9
9
|
"@heroku-cli/color": "2.0.1",
|
|
10
|
-
"@heroku-cli/command": "^12.
|
|
10
|
+
"@heroku-cli/command": "^12.1.1",
|
|
11
11
|
"@heroku-cli/notifications": "^1.2.4",
|
|
12
12
|
"@heroku-cli/plugin-ps-exec": "2.6.2",
|
|
13
13
|
"@heroku-cli/schema": "^1.0.25",
|
|
14
14
|
"@heroku/buildpack-registry": "^1.0.1",
|
|
15
15
|
"@heroku/eventsource": "^1.0.7",
|
|
16
|
-
"@heroku/heroku-cli-util": "^10.
|
|
16
|
+
"@heroku/heroku-cli-util": "^10.1.2",
|
|
17
17
|
"@heroku/http-call": "^5.5.0",
|
|
18
18
|
"@heroku/mcp-server": "1.0.7-alpha.1",
|
|
19
19
|
"@heroku/plugin-ai": "^1.0.1",
|
|
@@ -121,7 +121,7 @@
|
|
|
121
121
|
"mocha": "^10.8.2",
|
|
122
122
|
"nock": "^13.5.1",
|
|
123
123
|
"nyc": "^15.1.0",
|
|
124
|
-
"oclif": "^4.22.
|
|
124
|
+
"oclif": "^4.22.27",
|
|
125
125
|
"proxyquire": "^2.1.0",
|
|
126
126
|
"qqjs": "0.3.11",
|
|
127
127
|
"read-pkg": "^9.0.1",
|
|
@@ -140,7 +140,6 @@
|
|
|
140
140
|
"/autocomplete-scripts",
|
|
141
141
|
"/bin",
|
|
142
142
|
"/lib",
|
|
143
|
-
"/npm-shrinkwrap.json",
|
|
144
143
|
"/package-lock.json",
|
|
145
144
|
"/oclif.manifest.json"
|
|
146
145
|
],
|
|
@@ -327,7 +326,7 @@
|
|
|
327
326
|
},
|
|
328
327
|
"update": {
|
|
329
328
|
"node": {
|
|
330
|
-
"version": "22.
|
|
329
|
+
"version": "22.19.0"
|
|
331
330
|
},
|
|
332
331
|
"s3": {
|
|
333
332
|
"xz": true,
|
|
@@ -372,13 +371,8 @@
|
|
|
372
371
|
"coverage:check": "nyc --check-coverage --branches 80 --statements 80 --functions 80 --lines 80 npm run test",
|
|
373
372
|
"postpublish": "rm -f oclif.manifest.json",
|
|
374
373
|
"manifest": "oclif manifest",
|
|
375
|
-
"
|
|
376
|
-
"pack:tarballs": "oclif pack:tarballs --xz --parallel",
|
|
377
|
-
"pack:win": "oclif pack:win --defender-exclusion hidden",
|
|
378
|
-
"prepack": "npm run build",
|
|
374
|
+
"prepack": "npm run build && npm run manifest",
|
|
379
375
|
"pretest": "tsc -p test --noEmit && cd ../.. && npm run build",
|
|
380
|
-
"promote:deb": "oclif promote --deb --xz --indexes",
|
|
381
|
-
"promote:win": "oclif promote --win --indexes",
|
|
382
376
|
"test:acceptance": "npm run pretest && mocha --forbid-only \"test/**/*.acceptance.test.ts\" && node ./bin/bats-test-runner",
|
|
383
377
|
"test:integration": "npm run pretest && mocha --forbid-only \"test/**/*.integration.test.ts\"",
|
|
384
378
|
"test:smoke": "npm run pretest && mocha --forbid-only \"test/**/smoke.acceptance.test.ts\"",
|
|
@@ -386,12 +380,9 @@
|
|
|
386
380
|
"test:unit:justTest:ci": "nyc --reporter=lcov --reporter=text-summary mocha --forbid-only \"test/**/*.unit.test.ts\"",
|
|
387
381
|
"test": "npm run pretest && npm run test:unit:justTest:ci",
|
|
388
382
|
"test:local": "npm run pretest && npm run test:unit:justTest:local",
|
|
389
|
-
"upload:deb": "oclif upload:deb",
|
|
390
|
-
"upload:tarballs": "oclif upload:tarballs --xz",
|
|
391
|
-
"upload:win": "oclif upload:win",
|
|
392
383
|
"version": "oclif readme --multi && git add README.md ../../docs"
|
|
393
384
|
},
|
|
394
385
|
"type": "module",
|
|
395
386
|
"types": "lib/index.d.ts",
|
|
396
|
-
"gitHead": "
|
|
387
|
+
"gitHead": "7b33023e6263f78ab23b8b211a060e0baf2a187d"
|
|
397
388
|
}
|
package/lib/lib/members/utils.js
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { ux } from '@oclif/core';
|
|
2
|
-
import { color } from '@heroku-cli/color';
|
|
3
|
-
export const addMemberToTeam = async function (email, role, groupName, heroku, method = 'PUT') {
|
|
4
|
-
ux.action.start(`Adding ${color.cyan(email)} to ${color.magenta(groupName)} as ${color.green(role)}`);
|
|
5
|
-
await heroku.request(`/teams/${groupName}/members`, {
|
|
6
|
-
method: method,
|
|
7
|
-
body: { email, role },
|
|
8
|
-
});
|
|
9
|
-
ux.action.stop();
|
|
10
|
-
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
export {};
|
|
2
|
-
/*
|
|
3
|
-
import {FileCompletion} from '@heroku-cli/command/lib/completions'
|
|
4
|
-
import {Args, Command, Flags} from '@oclif/core'
|
|
5
|
-
import * as fs from 'fs'
|
|
6
|
-
import color from '@heroku-cli/color'
|
|
7
|
-
import {fork as foreman} from '../../lib/local/fork-foreman'
|
|
8
|
-
|
|
9
|
-
// eslint-disable-next-line node/no-missing-require
|
|
10
|
-
const Procfile: any = require('../../lib/local/load-foreman-procfile')
|
|
11
|
-
|
|
12
|
-
export default class Index extends Command {
|
|
13
|
-
// \n splits the description between the title shown in the help
|
|
14
|
-
// and the DESCRIPTION section shown in the help
|
|
15
|
-
static description = 'run heroku app locally\nStart the application specified by a Procfile (defaults to ./Procfile)'
|
|
16
|
-
|
|
17
|
-
static aliases = ['local:start']
|
|
18
|
-
|
|
19
|
-
static args = {
|
|
20
|
-
processname: Args.string({required: false, description: 'name of the process'}),
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
static examples = [
|
|
24
|
-
`$ heroku local
|
|
25
|
-
$ heroku local web
|
|
26
|
-
$ heroku local web=2
|
|
27
|
-
$ heroku local web=1,worker=2`,
|
|
28
|
-
]
|
|
29
|
-
|
|
30
|
-
static flags = {
|
|
31
|
-
procfile: Flags.string({
|
|
32
|
-
char: 'f',
|
|
33
|
-
description: 'use a different Procfile',
|
|
34
|
-
completion: FileCompletion,
|
|
35
|
-
}),
|
|
36
|
-
env: Flags.string({
|
|
37
|
-
char: 'e',
|
|
38
|
-
description: 'location of env file (defaults to .env)',
|
|
39
|
-
completion: FileCompletion,
|
|
40
|
-
}),
|
|
41
|
-
port: Flags.string({
|
|
42
|
-
char: 'p',
|
|
43
|
-
description: 'port to listen on',
|
|
44
|
-
}),
|
|
45
|
-
restart: Flags.boolean({
|
|
46
|
-
char: 'r',
|
|
47
|
-
description: 'restart process if it dies',
|
|
48
|
-
hidden: true,
|
|
49
|
-
}),
|
|
50
|
-
concurrency: Flags.string({
|
|
51
|
-
char: 'c',
|
|
52
|
-
description: 'number of processes to start',
|
|
53
|
-
hidden: true,
|
|
54
|
-
}),
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
async run() {
|
|
58
|
-
const execArgv = ['start']
|
|
59
|
-
const {args, flags} = await this.parse(Index)
|
|
60
|
-
|
|
61
|
-
if (flags.restart) {
|
|
62
|
-
this.error('--restart is no longer available\nUse forego instead: https://github.com/ddollar/forego')
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
if (flags.concurrency) {
|
|
66
|
-
this.error('--concurrency is no longer available\nUse forego instead: https://github.com/ddollar/forego')
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
let envFile = flags.env || '.env'
|
|
70
|
-
if (fs.existsSync(envFile) && !fs.statSync(envFile).isFile()) {
|
|
71
|
-
this.warn(`The specified location for the env file, ${color.bold(envFile)}, is not a file, ignoring.`)
|
|
72
|
-
envFile = ''
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
if (flags.procfile) execArgv.push('--procfile', flags.procfile)
|
|
76
|
-
execArgv.push('--env', envFile)
|
|
77
|
-
if (flags.port) execArgv.push('--port', flags.port)
|
|
78
|
-
|
|
79
|
-
if (args.processname) {
|
|
80
|
-
execArgv.push(args.processname)
|
|
81
|
-
} else {
|
|
82
|
-
const procfile = flags.procfile || 'Procfile'
|
|
83
|
-
const procHash = Procfile.loadProc(procfile)
|
|
84
|
-
const processes = Object.keys(procHash).filter(x => x !== 'release')
|
|
85
|
-
execArgv.push(processes.join(','))
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
await foreman(execArgv)
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
*/
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
export {};
|
|
2
|
-
/*
|
|
3
|
-
import {FileCompletion} from '@heroku-cli/command/lib/completions'
|
|
4
|
-
import {Command, Flags} from '@oclif/core'
|
|
5
|
-
import color from '@heroku-cli/color'
|
|
6
|
-
import {fork as foreman} from '../../lib/local/fork-foreman'
|
|
7
|
-
import {revertSortedArgs} from '../../lib/run/helpers'
|
|
8
|
-
import * as fs from 'fs'
|
|
9
|
-
|
|
10
|
-
export default class Run extends Command {
|
|
11
|
-
static description = 'run a one-off command'
|
|
12
|
-
|
|
13
|
-
static examples = [
|
|
14
|
-
'$ heroku local:run bin/migrate',
|
|
15
|
-
]
|
|
16
|
-
|
|
17
|
-
static strict = false
|
|
18
|
-
|
|
19
|
-
static flags = {
|
|
20
|
-
env: Flags.string({
|
|
21
|
-
char: 'e',
|
|
22
|
-
completion: FileCompletion,
|
|
23
|
-
}),
|
|
24
|
-
port: Flags.string({
|
|
25
|
-
char: 'p',
|
|
26
|
-
}),
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
async run() {
|
|
30
|
-
const execArgv: string[] = ['run']
|
|
31
|
-
const {argv, flags} = await this.parse(Run)
|
|
32
|
-
const commandArgs = revertSortedArgs(process.argv, argv as string[])
|
|
33
|
-
|
|
34
|
-
if (commandArgs.length === 0) {
|
|
35
|
-
const errorMessage = 'Usage: heroku local:run [COMMAND]\nMust specify command to run'
|
|
36
|
-
this.error(errorMessage, {exit: -1})
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
let envFile = flags.env || '.env'
|
|
40
|
-
if (fs.existsSync(envFile) && !fs.statSync(envFile).isFile()) {
|
|
41
|
-
this.warn(`The specified location for the env file, ${color.bold(envFile)}, is not a file, ignoring.`)
|
|
42
|
-
envFile = ''
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
execArgv.push('--env', envFile)
|
|
46
|
-
if (flags.port) execArgv.push('--port', flags.port)
|
|
47
|
-
|
|
48
|
-
execArgv.push('--') // disable node-foreman flag parsing
|
|
49
|
-
execArgv.push(...commandArgs as string[]) // eslint-disable-line unicorn/no-array-push-push
|
|
50
|
-
|
|
51
|
-
await foreman(execArgv)
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
*/
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
export {};
|
|
2
|
-
/*
|
|
3
|
-
import {Command} from '@oclif/core'
|
|
4
|
-
|
|
5
|
-
import {fork as foreman} from '../../lib/local/fork-foreman'
|
|
6
|
-
|
|
7
|
-
export default class Version extends Command {
|
|
8
|
-
static description = 'display node-foreman version'
|
|
9
|
-
|
|
10
|
-
async run() {
|
|
11
|
-
await this.parse(Version)
|
|
12
|
-
|
|
13
|
-
const execArgv = ['--version']
|
|
14
|
-
await foreman(execArgv)
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
*/
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
export {};
|
|
2
|
-
/*
|
|
3
|
-
import {Command, flags} from '@heroku-cli/command'
|
|
4
|
-
import {Args} from '@oclif/core'
|
|
5
|
-
import * as Heroku from '@heroku-cli/schema'
|
|
6
|
-
import {RoleCompletion} from '@heroku-cli/command/lib/completions'
|
|
7
|
-
import {addMemberToTeam, inviteMemberToTeam} from '../../lib/members/util'
|
|
8
|
-
export default class MembersAdd extends Command {
|
|
9
|
-
static topic = 'members';
|
|
10
|
-
static description = 'adds a user to a team';
|
|
11
|
-
static flags = {
|
|
12
|
-
role: flags.string({char: 'r', required: true, description: 'member role (admin, collaborator, member, owner)', completion: RoleCompletion}),
|
|
13
|
-
team: flags.team({required: true}),
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
static args = {
|
|
17
|
-
email: Args.string({required: true, description: 'email address of the team member'}),
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
public async run(): Promise<void> {
|
|
21
|
-
const {flags, args} = await this.parse(MembersAdd)
|
|
22
|
-
const {team, role} = flags
|
|
23
|
-
const {body: teamInfo} = await this.heroku.get<Heroku.Team>(`/teams/${team}`)
|
|
24
|
-
const email = args.email
|
|
25
|
-
const {body: groupFeatures} = await this.heroku.get<Heroku.TeamFeature[]>(`/teams/${team}/features`)
|
|
26
|
-
|
|
27
|
-
if (teamInfo.type === 'team' && groupFeatures.some(feature => {
|
|
28
|
-
return feature.name === 'team-invite-acceptance' && feature.enabled
|
|
29
|
-
})) {
|
|
30
|
-
await inviteMemberToTeam(email, role, team, this.heroku)
|
|
31
|
-
} else {
|
|
32
|
-
await addMemberToTeam(email, role, team, this.heroku)
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
*/
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
export {};
|
|
2
|
-
/*
|
|
3
|
-
import color from '@heroku-cli/color'
|
|
4
|
-
import {Command, flags} from '@heroku-cli/command'
|
|
5
|
-
import {RoleCompletion} from '@heroku-cli/command/lib/completions'
|
|
6
|
-
import {ux} from '@oclif/core'
|
|
7
|
-
import {hux} from '@heroku/heroku-cli-util'
|
|
8
|
-
import * as Heroku from '@heroku-cli/schema'
|
|
9
|
-
|
|
10
|
-
const _ = require('lodash')
|
|
11
|
-
|
|
12
|
-
type MemberWithStatus = Heroku.TeamMember & { status?: string }
|
|
13
|
-
|
|
14
|
-
const buildTableColumns = (teamInvites: Heroku.TeamInvitation[]) => {
|
|
15
|
-
const baseColumns = {
|
|
16
|
-
email: {
|
|
17
|
-
get: ({email}: any):string => color.cyan(email),
|
|
18
|
-
},
|
|
19
|
-
role: {
|
|
20
|
-
get: ({role}: any):string => color.green(role),
|
|
21
|
-
},
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
if (teamInvites.length > 0) {
|
|
25
|
-
return {
|
|
26
|
-
...baseColumns,
|
|
27
|
-
status: {
|
|
28
|
-
get: ({status}: any):string => color.green(status),
|
|
29
|
-
},
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
return baseColumns
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export default class MembersIndex extends Command {
|
|
37
|
-
static topic = 'members';
|
|
38
|
-
static description = 'list members of a team';
|
|
39
|
-
static flags = {
|
|
40
|
-
role: flags.string({char: 'r', description: 'filter by role', completion: RoleCompletion}),
|
|
41
|
-
pending: flags.boolean({description: 'filter by pending team invitations'}),
|
|
42
|
-
json: flags.boolean({description: 'output in json format'}),
|
|
43
|
-
team: flags.team({required: true}),
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
public async run(): Promise<void> {
|
|
47
|
-
const {flags} = await this.parse(MembersIndex)
|
|
48
|
-
const {role, pending, json, team} = flags
|
|
49
|
-
const {body: teamInfo} = await this.heroku.get<Heroku.Team>(`/teams/${team}`)
|
|
50
|
-
let teamInvites: Heroku.TeamInvitation[] = []
|
|
51
|
-
if (teamInfo.type === 'team') {
|
|
52
|
-
const {body: orgFeatures} = await this.heroku.get<Heroku.TeamFeature[]>(`/teams/${team}/features`)
|
|
53
|
-
if (orgFeatures.some((feature => feature.name === 'team-invite-acceptance' && feature.enabled))) {
|
|
54
|
-
const invitesResponse = await this.heroku.get<Heroku.TeamInvitation[]>(
|
|
55
|
-
`/teams/${team}/invitations`,
|
|
56
|
-
{headers: {
|
|
57
|
-
Accept: 'application/vnd.heroku+json; version=3.team-invitations',
|
|
58
|
-
},
|
|
59
|
-
})
|
|
60
|
-
teamInvites = _.map(invitesResponse.body, function (invite: Heroku.TeamInvitation) {
|
|
61
|
-
return {email: invite.user?.email, role: invite.role, status: 'pending'}
|
|
62
|
-
})
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
let {body: members} = await this.heroku.get<MemberWithStatus[]>(`/teams/${team}/members`)
|
|
67
|
-
// Set status '' to all existing members
|
|
68
|
-
_.map(members, (member: MemberWithStatus) => {
|
|
69
|
-
member.status = ''
|
|
70
|
-
})
|
|
71
|
-
members = _.sortBy(_.union(members, teamInvites), 'email')
|
|
72
|
-
if (role)
|
|
73
|
-
members = members.filter(m => m.role === role)
|
|
74
|
-
if (pending)
|
|
75
|
-
members = members.filter(m => m.status === 'pending')
|
|
76
|
-
if (json) {
|
|
77
|
-
ux.log(JSON.stringify(members, null, 3))
|
|
78
|
-
} else if (members.length === 0) {
|
|
79
|
-
let msg = `No members in ${color.magenta(team || '')}`
|
|
80
|
-
if (role)
|
|
81
|
-
msg += ` with role ${color.green(role)}`
|
|
82
|
-
ux.log(msg)
|
|
83
|
-
} else {
|
|
84
|
-
const tableColumns = buildTableColumns(teamInvites)
|
|
85
|
-
hux.table(
|
|
86
|
-
members,
|
|
87
|
-
tableColumns,
|
|
88
|
-
)
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
*/
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
export {};
|
|
2
|
-
/*
|
|
3
|
-
import color from '@heroku-cli/color'
|
|
4
|
-
import {APIClient, Command, flags} from '@heroku-cli/command'
|
|
5
|
-
import {ux} from '@oclif/core'
|
|
6
|
-
import * as Heroku from '@heroku-cli/schema'
|
|
7
|
-
|
|
8
|
-
const revokeInvite = async (email: string, team: string, heroku: APIClient) => {
|
|
9
|
-
ux.action.start(`Revoking invite for ${color.cyan(email)} in ${color.magenta(team)}`)
|
|
10
|
-
await heroku.delete<Heroku.TeamInvitation[]>(
|
|
11
|
-
`/teams/${team}/invitations/${email}`,
|
|
12
|
-
{
|
|
13
|
-
headers: {
|
|
14
|
-
Accept: 'application/vnd.heroku+json; version=3.team-invitations',
|
|
15
|
-
},
|
|
16
|
-
})
|
|
17
|
-
ux.action.stop()
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const getTeamInvites = async (team: string, heroku: APIClient) => {
|
|
21
|
-
const {body: teamInvites} = await heroku.get<Heroku.TeamInvitation[]>(
|
|
22
|
-
`/teams/${team}/invitations`,
|
|
23
|
-
{
|
|
24
|
-
headers: {
|
|
25
|
-
Accept: 'application/vnd.heroku+json; version=3.team-invitations',
|
|
26
|
-
},
|
|
27
|
-
})
|
|
28
|
-
return teamInvites
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const removeUserMembership = async (email:string, team: string, heroku: APIClient) => {
|
|
32
|
-
ux.action.start(`Removing ${color.cyan(email)} from ${color.magenta(team)}`)
|
|
33
|
-
await heroku.delete(`/teams/${team}/members/${encodeURIComponent(email)}`)
|
|
34
|
-
ux.action.stop()
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export default class MembersRemove extends Command {
|
|
38
|
-
static topic = 'members';
|
|
39
|
-
static description = 'removes a user from a team';
|
|
40
|
-
static flags = {
|
|
41
|
-
team: flags.team({required: true}),
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
static strict = false
|
|
45
|
-
|
|
46
|
-
public async run(): Promise<void> {
|
|
47
|
-
const {flags, argv} = await this.parse(MembersRemove)
|
|
48
|
-
const {team} = flags
|
|
49
|
-
const email = argv[0] as string
|
|
50
|
-
const {body: teamInfo} = await this.heroku.get<Heroku.Team>(`/teams/${team}`)
|
|
51
|
-
let teamInviteFeatureEnabled = false
|
|
52
|
-
let isInvitedUser = false
|
|
53
|
-
|
|
54
|
-
if (teamInfo.type === 'team') {
|
|
55
|
-
const {body: teamFeatures} = await this.heroku.get<Heroku.TeamFeature[]>(`/teams/${team}/features`)
|
|
56
|
-
teamInviteFeatureEnabled = Boolean(teamFeatures.some(feature => feature.name === 'team-invite-acceptance' && feature.enabled))
|
|
57
|
-
if (teamInviteFeatureEnabled) {
|
|
58
|
-
const invites = await getTeamInvites(team, this.heroku)
|
|
59
|
-
isInvitedUser = Boolean(invites.some(m => m.user?.email === email))
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
if (teamInviteFeatureEnabled && isInvitedUser) {
|
|
64
|
-
await revokeInvite(email, team, this.heroku)
|
|
65
|
-
} else {
|
|
66
|
-
await removeUserMembership(email, team, this.heroku)
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
*/
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
export {};
|
|
2
|
-
/*
|
|
3
|
-
import {Command, flags} from '@heroku-cli/command'
|
|
4
|
-
import {RoleCompletion} from '@heroku-cli/command/lib/completions'
|
|
5
|
-
import {addMemberToTeam} from '../../lib/members/utils'
|
|
6
|
-
|
|
7
|
-
export default class MembersSet extends Command {
|
|
8
|
-
static topic = 'members'
|
|
9
|
-
static description = 'sets a members role in a team'
|
|
10
|
-
static strict = false
|
|
11
|
-
static flags = {
|
|
12
|
-
role: flags.string({char: 'r', required: true, description: 'member role (admin, collaborator, member, owner)', completion: RoleCompletion}),
|
|
13
|
-
team: flags.team({required: true}),
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
public async run(): Promise<void> {
|
|
17
|
-
const {flags, argv} = await this.parse(MembersSet)
|
|
18
|
-
const {role, team} = flags
|
|
19
|
-
const email = argv[0] as string
|
|
20
|
-
|
|
21
|
-
await addMemberToTeam(email, role, team, this.heroku, 'PATCH')
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
*/
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
export {};
|
|
2
|
-
/*
|
|
3
|
-
import color from '@heroku-cli/color'
|
|
4
|
-
import {Command, flags} from '@heroku-cli/command'
|
|
5
|
-
import {StageCompletion} from '@heroku-cli/command/lib/completions'
|
|
6
|
-
import {Args, ux} from '@oclif/core'
|
|
7
|
-
import {prompt} from 'inquirer'
|
|
8
|
-
|
|
9
|
-
import {createCoupling} from '../../lib/api'
|
|
10
|
-
import disambiguate from '../../lib/pipelines/disambiguate'
|
|
11
|
-
import infer from '../../lib/pipelines/infer'
|
|
12
|
-
import {inferrableStageNames as stageNames} from '../../lib/pipelines/stages'
|
|
13
|
-
|
|
14
|
-
export default class PipelinesAdd extends Command {
|
|
15
|
-
static description = `add this app to a pipeline
|
|
16
|
-
The app and pipeline names must be specified.
|
|
17
|
-
The stage of the app will be guessed based on its name if not specified.`
|
|
18
|
-
|
|
19
|
-
static examples = [
|
|
20
|
-
'$ heroku pipelines:add my-pipeline -a my-app -s production',
|
|
21
|
-
]
|
|
22
|
-
|
|
23
|
-
static flags = {
|
|
24
|
-
app: flags.app({required: true}),
|
|
25
|
-
remote: flags.remote(),
|
|
26
|
-
stage: flags.string({
|
|
27
|
-
char: 's',
|
|
28
|
-
description: 'stage of first app in pipeline',
|
|
29
|
-
completion: StageCompletion,
|
|
30
|
-
}),
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
static args = {
|
|
34
|
-
pipeline: Args.string({
|
|
35
|
-
description: 'name of pipeline',
|
|
36
|
-
required: true,
|
|
37
|
-
}),
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
async run() {
|
|
41
|
-
const {args, flags} = await this.parse(PipelinesAdd)
|
|
42
|
-
const app = flags.app
|
|
43
|
-
|
|
44
|
-
let stage
|
|
45
|
-
const guesses = infer(app)
|
|
46
|
-
const questions = []
|
|
47
|
-
|
|
48
|
-
const pipeline: any = await disambiguate(this.heroku, args.pipeline)
|
|
49
|
-
|
|
50
|
-
if (flags.stage) {
|
|
51
|
-
stage = flags.stage
|
|
52
|
-
} else {
|
|
53
|
-
questions.push({
|
|
54
|
-
type: 'list',
|
|
55
|
-
name: 'stage',
|
|
56
|
-
message: `Stage of ${app}`,
|
|
57
|
-
choices: stageNames,
|
|
58
|
-
default: guesses[1],
|
|
59
|
-
})
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
const answers: any = await prompt(questions)
|
|
63
|
-
if (answers.stage) stage = answers.stage
|
|
64
|
-
|
|
65
|
-
ux.action.start(`Adding ${color.app(app)} to ${color.pipeline(pipeline.name)} pipeline as ${stage}`)
|
|
66
|
-
await createCoupling(this.heroku, pipeline, app, stage)
|
|
67
|
-
ux.action.stop()
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
*/
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
export {};
|
|
2
|
-
/*
|
|
3
|
-
import {Command, flags} from '@heroku-cli/command'
|
|
4
|
-
import {Args, ux} from '@oclif/core'
|
|
5
|
-
|
|
6
|
-
import {getPipeline} from '../../lib/api'
|
|
7
|
-
import GitHubAPI from '../../lib/pipelines/github-api'
|
|
8
|
-
import KolkrabbiAPI from '../../lib/pipelines/kolkrabbi-api'
|
|
9
|
-
import getGitHubToken from '../../lib/pipelines/setup/get-github-token'
|
|
10
|
-
import getNameAndRepo from '../../lib/pipelines/setup/get-name-and-repo'
|
|
11
|
-
import getRepo from '../../lib/pipelines/setup/get-repo'
|
|
12
|
-
import {nameAndRepo} from '../../lib/pipelines/setup/validate'
|
|
13
|
-
|
|
14
|
-
export default class Connect extends Command {
|
|
15
|
-
static description = 'connect a GitHub repo to an existing pipeline'
|
|
16
|
-
|
|
17
|
-
static examples = [
|
|
18
|
-
'$ heroku pipelines:connect my-pipeline -r githuborg/reponame',
|
|
19
|
-
]
|
|
20
|
-
|
|
21
|
-
static flags = {
|
|
22
|
-
repo: flags.string({
|
|
23
|
-
name: 'repo',
|
|
24
|
-
char: 'r',
|
|
25
|
-
description: 'the GitHub repository to connect to',
|
|
26
|
-
required: true,
|
|
27
|
-
}),
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
static args = {
|
|
31
|
-
name: Args.string({
|
|
32
|
-
description: 'name of pipeline',
|
|
33
|
-
required: true,
|
|
34
|
-
}),
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
async run() {
|
|
38
|
-
const {args, flags} = await this.parse(Connect)
|
|
39
|
-
|
|
40
|
-
const combinedInputs = {
|
|
41
|
-
name: args.name,
|
|
42
|
-
repo: flags.repo,
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
const errors = nameAndRepo({repo: flags.repo})
|
|
46
|
-
|
|
47
|
-
if (errors.length > 0) {
|
|
48
|
-
this.error(errors.join(', '))
|
|
49
|
-
return
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const kolkrabbi = new KolkrabbiAPI(this.config.userAgent, () => this.heroku.auth)
|
|
53
|
-
const github = new GitHubAPI(this.config.userAgent, await getGitHubToken(kolkrabbi))
|
|
54
|
-
|
|
55
|
-
const {
|
|
56
|
-
name: pipelineName,
|
|
57
|
-
repo: repoName,
|
|
58
|
-
} = await getNameAndRepo(combinedInputs)
|
|
59
|
-
|
|
60
|
-
const repo = await getRepo(github, repoName)
|
|
61
|
-
|
|
62
|
-
const pipeline = await getPipeline(this.heroku, pipelineName)
|
|
63
|
-
|
|
64
|
-
ux.action.start('Linking to repo')
|
|
65
|
-
await kolkrabbi.createPipelineRepository(pipeline.body.id, repo.id)
|
|
66
|
-
ux.action.stop()
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
*/
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|