heroku 10.0.0-beta.0 → 10.0.0-beta.3

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.
@@ -36,7 +36,7 @@ GitRemote.example = `# set git remote heroku to https://git.heroku.com/example.g
36
36
  $ heroku git:remote -a example
37
37
 
38
38
  # set git remote heroku-staging to https://git.heroku.com/example.git
39
- $ heroku git:remote --remote heroku-staging -a example`;
39
+ $ heroku git:remote --remote heroku-staging -a example-staging`;
40
40
  GitRemote.flags = {
41
41
  app: command_1.flags.string({ char: 'a', description: 'the Heroku app to use' }),
42
42
  remote: command_1.flags.string({ char: 'r', description: 'the git remote to create' }),
@@ -1,14 +1,18 @@
1
1
  import { Command } from '@heroku-cli/command';
2
2
  export default class RunInside extends Command {
3
3
  static description: string;
4
- static hidden: boolean;
5
- static examples: string[];
4
+ static strict: boolean;
5
+ static args: {
6
+ dyno_name: import("@oclif/core/lib/interfaces/parser").Arg<string, Record<string, unknown>>;
7
+ command: import("@oclif/core/lib/interfaces/parser").Arg<string, Record<string, unknown>>;
8
+ };
6
9
  static flags: {
7
10
  app: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
8
- remote: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
9
11
  'exit-code': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
10
12
  listen: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
13
+ 'no-launcher': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
14
+ remote: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
11
15
  };
12
- static strict: boolean;
16
+ static examples: string[];
13
17
  run(): Promise<void>;
14
18
  }
@@ -3,22 +3,27 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const command_1 = require("@heroku-cli/command");
4
4
  const core_1 = require("@oclif/core");
5
5
  const debug_1 = require("debug");
6
+ const tsheredoc_1 = require("tsheredoc");
6
7
  const dyno_1 = require("../../lib/run/dyno");
7
8
  const helpers_1 = require("../../lib/run/helpers");
8
9
  const debug = (0, debug_1.default)('heroku:run:inside');
9
10
  class RunInside extends command_1.Command {
10
11
  async run() {
11
- const { flags, argv } = await this.parse(RunInside);
12
- if (argv.length < 2) {
13
- throw new Error('Usage: heroku run:inside DYNO COMMAND\n\nExample: heroku run:inside web.1 bash');
14
- }
12
+ const { args, argv, flags } = await this.parse(RunInside);
13
+ const { dyno_name: dynoName } = args;
14
+ const { app: appName, 'exit-code': exitCode, listen, 'no-launcher': noLauncher } = flags;
15
+ const prependLauncher = !noLauncher;
16
+ const { body: app } = await this.heroku.get(`/apps/${appName}`, {
17
+ headers: { Accept: 'application/vnd.heroku+json; version=3.sdk' },
18
+ });
19
+ const appStackIsCnb = app.stack.name === 'cnb';
15
20
  const opts = {
16
- 'exit-code': flags['exit-code'],
17
- app: flags.app,
18
- command: (0, helpers_1.buildCommand)(argv.slice(1)),
19
- dyno: argv[0],
21
+ app: appName,
22
+ command: (0, helpers_1.buildCommand)(argv.slice(1), appStackIsCnb && prependLauncher),
23
+ dyno: dynoName,
24
+ 'exit-code': exitCode,
20
25
  heroku: this.heroku,
21
- listen: flags.listen,
26
+ listen,
22
27
  };
23
28
  const dyno = new dyno_1.default(opts);
24
29
  try {
@@ -36,15 +41,42 @@ class RunInside extends command_1.Command {
36
41
  }
37
42
  }
38
43
  exports.default = RunInside;
39
- RunInside.description = 'run a one-off process inside an existing heroku dyno';
40
- RunInside.hidden = true;
41
- RunInside.examples = [
42
- '$ heroku run:inside web.1 bash',
43
- ];
44
+ RunInside.description = 'run a command inside an existing dyno (for Fir-generation apps only)';
45
+ RunInside.strict = false;
46
+ RunInside.args = {
47
+ dyno_name: core_1.Args.string({
48
+ description: 'name of the dyno to run command inside',
49
+ required: true,
50
+ }),
51
+ command: core_1.Args.string({
52
+ description: 'command to run (Heroku automatically prepends ‘launcher’ to the command)',
53
+ required: true,
54
+ }),
55
+ };
44
56
  RunInside.flags = {
45
57
  app: command_1.flags.app({ required: true }),
46
- remote: command_1.flags.remote(),
47
- 'exit-code': command_1.flags.boolean({ char: 'x', description: 'passthrough the exit code of the remote command' }),
58
+ 'exit-code': command_1.flags.boolean({
59
+ char: 'x',
60
+ description: 'passthrough the exit code of the remote command',
61
+ }),
48
62
  listen: command_1.flags.boolean({ description: 'listen on a local port', hidden: true }),
63
+ 'no-launcher': command_1.flags.boolean({
64
+ description: 'don’t prepend ‘launcher’ before a command',
65
+ default: false,
66
+ }),
67
+ remote: command_1.flags.remote(),
49
68
  };
50
- RunInside.strict = false;
69
+ RunInside.examples = [
70
+ (0, tsheredoc_1.default) `
71
+ Run bash
72
+ heroku run:inside web-848cd4f64d-pvpr2 bash -a my-app
73
+ `,
74
+ (0, tsheredoc_1.default) `
75
+ Run a command supplied by a script taking option flags
76
+ heroku run:inside web-848cd4f64d-pvpr2 -a my-app -- myscript.sh -x --log-level=warn
77
+ `,
78
+ (0, tsheredoc_1.default) `
79
+ Run a command declared for the worker process type in a Procfile
80
+ heroku run:inside web-848cd4f64d-pvpr2 worker -a my-app
81
+ `,
82
+ ];
@@ -21,6 +21,20 @@ class Create extends command_1.Command {
21
21
  const dollarAmountMonthly = shield ? '$3000' : '$1000';
22
22
  const dollarAmountHourly = shield ? '$4.17' : '$1.39';
23
23
  const spaceType = shield ? 'Shield' : 'Standard';
24
+ if (generation === 'fir') {
25
+ core_1.ux.warn((0, tsheredoc_1.default) `
26
+ Fir Pilot Features
27
+ Fir is currently a pilot service that is subject to the Beta Services Terms
28
+ (https://www.salesforce.com/company/legal/) or a written Unified Pilot Agreement
29
+ if executed by Customer, and applicable terms in the Product Terms Directory
30
+ (https://ptd.salesforce.com/?_ga=2.247987783.1372150065.1709219475-629000709.1639001992).
31
+ Use of this pilot or beta service is at the Customer's sole discretion.
32
+
33
+ Please note that we’re actively developing and adding new features, and not all
34
+ existing features are currently available. See the Dev Center
35
+ (https://devcenter.heroku.com/articles/generations) for more info.
36
+ `);
37
+ }
24
38
  core_1.ux.action.start(`Creating space ${color_1.default.green(spaceName)} in team ${color_1.default.cyan(team)}`);
25
39
  const { body: space } = await this.heroku.post('/spaces', {
26
40
  headers: {
@@ -3,13 +3,13 @@ export default class Add extends Command {
3
3
  static description: string;
4
4
  static flags: {
5
5
  app: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
6
+ headers: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
6
7
  space: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
7
8
  signals: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
8
- endpoint: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
9
9
  transport: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
10
10
  };
11
11
  static args: {
12
- headers: import("@oclif/core/lib/interfaces/parser").Arg<string, Record<string, unknown>>;
12
+ endpoint: import("@oclif/core/lib/interfaces/parser").Arg<string, Record<string, unknown>>;
13
13
  };
14
14
  static example: string;
15
15
  run(): Promise<void>;
@@ -7,8 +7,8 @@ const util_1 = require("../../lib/telemetry/util");
7
7
  class Add extends command_1.Command {
8
8
  async run() {
9
9
  const { flags, args } = await this.parse(Add);
10
- const { app, space, signals, endpoint, transport } = flags;
11
- const { headers } = args;
10
+ const { app, headers, space, signals, transport } = flags;
11
+ const { endpoint } = args;
12
12
  let id;
13
13
  if (app) {
14
14
  const { body: herokuApp } = await this.heroku.get(`/apps/${app}`, {
@@ -20,6 +20,7 @@ class Add extends command_1.Command {
20
20
  const { body: herokuSpace } = await this.heroku.get(`/spaces/${space}`);
21
21
  id = herokuSpace.id;
22
22
  }
23
+ const exporterHeaders = headers || '{}';
23
24
  const drainConfig = {
24
25
  owner: {
25
26
  type: app ? 'app' : 'space',
@@ -29,7 +30,7 @@ class Add extends command_1.Command {
29
30
  exporter: {
30
31
  endpoint,
31
32
  type: `otlp${transport}`,
32
- headers: JSON.parse(headers),
33
+ headers: JSON.parse(exporterHeaders),
33
34
  },
34
35
  };
35
36
  const { body: drain } = await this.heroku.post('/telemetry-drains', {
@@ -45,15 +46,15 @@ exports.default = Add;
45
46
  Add.description = 'Add and configure a new telemetry drain. Defaults to collecting all telemetry unless otherwise specified.';
46
47
  Add.flags = {
47
48
  app: command_1.flags.string({ char: 'a', exactlyOne: ['app', 'space'], description: 'app to add a drain to' }),
49
+ headers: command_1.flags.string({ description: 'custom headers to configure the drain in json format' }),
48
50
  space: command_1.flags.string({ char: 's', description: 'space to add a drain to' }),
49
51
  signals: command_1.flags.string({ default: 'all', description: 'comma-delimited list of signals to collect (traces, metrics, logs). Use "all" to collect all signals.' }),
50
- endpoint: command_1.flags.string({ required: true, description: 'drain url' }),
51
- transport: command_1.flags.string({ required: true, options: ['http', 'grpc'], description: 'transport protocol for the drain' }),
52
+ transport: command_1.flags.string({ default: 'http', options: ['http', 'grpc'], description: 'transport protocol for the drain' }),
52
53
  };
53
54
  Add.args = {
54
- headers: core_1.Args.string({ required: true, description: 'custom headers to configure the drain in json format' }),
55
+ endpoint: core_1.Args.string({ required: true, description: 'drain url' }),
55
56
  };
56
57
  Add.example = (0, tsheredoc_1.default)(`
57
58
  Add a telemetry drain to an app to collect logs and traces:
58
- $ heroku telemetry:add --app myapp --signals logs,traces --endpoint https://my-endpoint.com --transport http '{"x-drain-example-team": "API_KEY", "x-drain-example-dataset": "METRICS_DATASET"}'
59
+ $ heroku telemetry:add https://my-endpoint.com --app myapp --signals logs,traces --headers '{"x-drain-example-team": "API_KEY", "x-drain-example-dataset": "METRICS_DATASET"}'
59
60
  `);
@@ -4,11 +4,11 @@ export default class Update extends Command {
4
4
  static description: string;
5
5
  static args: {
6
6
  telemetry_drain_id: import("@oclif/core/lib/interfaces/parser").Arg<string, Record<string, unknown>>;
7
- headers: import("@oclif/core/lib/interfaces/parser").Arg<string | undefined, Record<string, unknown>>;
8
7
  };
9
8
  static flags: {
10
- signals: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
11
9
  endpoint: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
10
+ headers: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
11
+ signals: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
12
12
  transport: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
13
13
  };
14
14
  static example: string;
@@ -7,9 +7,9 @@ const util_1 = require("../../lib/telemetry/util");
7
7
  class Update extends command_1.Command {
8
8
  async run() {
9
9
  const { args, flags } = await this.parse(Update);
10
- const { telemetry_drain_id, headers } = args;
11
- const { signals, endpoint, transport } = flags;
12
- if (!(headers || signals || endpoint || transport)) {
10
+ const { telemetry_drain_id } = args;
11
+ const { endpoint, headers, signals, transport } = flags;
12
+ if (!(endpoint || headers || signals || transport)) {
13
13
  core_1.ux.error((0, tsheredoc_1.default)(`
14
14
  Requires either --signals, --endpoint, --transport or HEADERS to be provided.
15
15
  See more help with --help
@@ -48,11 +48,11 @@ Update.topic = 'telemetry';
48
48
  Update.description = 'updates a telemetry drain with provided attributes (attributes not provided remain unchanged)';
49
49
  Update.args = {
50
50
  telemetry_drain_id: core_1.Args.string({ required: true, description: 'ID of the drain to update' }),
51
- headers: core_1.Args.string({ description: 'custom headers to configure the drain in json format' }),
52
51
  };
53
52
  Update.flags = {
54
- signals: command_1.flags.string({ description: 'comma-delimited list of signals to collect (traces, metrics, logs). Use "all" to collect all signals.' }),
55
53
  endpoint: command_1.flags.string({ description: 'drain url' }),
54
+ headers: command_1.flags.string({ description: 'custom headers to configure the drain in json format' }),
55
+ signals: command_1.flags.string({ description: 'comma-delimited list of signals to collect (traces, metrics, logs). Use "all" to collect all signals.' }),
56
56
  transport: command_1.flags.string({ options: ['http', 'grpc'], description: 'transport protocol for the drain' }),
57
57
  };
58
58
  Update.example = (0, tsheredoc_1.default)(`
@@ -43,7 +43,7 @@ const provider = new NodeTracerProvider({
43
43
  });
44
44
  const headers = { Authorization: `Bearer ${process.env.IS_HEROKU_TEST_ENV !== 'true' ? getToken() : ''}` };
45
45
  const exporter = new OTLPTraceExporter({
46
- url: isDev ? 'https://backboard-staging.herokuapp.com/otel/v1/traces' : 'https://backboard.heroku.com/otel/v1/traces',
46
+ url: isDev ? 'https://backboard.staging.herokudev.com/otel/v1/traces' : 'https://backboard.heroku.com/otel/v1/traces',
47
47
  headers,
48
48
  compression: 'none',
49
49
  });
@@ -1,3 +1,3 @@
1
1
  export declare function revertSortedArgs(processArgs: Array<string>, argv: Array<string>): string[];
2
- export declare function buildCommand(args: Array<string>): string;
2
+ export declare function buildCommand(args: Array<string>, prependLauncher?: boolean): string;
3
3
  export declare function buildEnvFromFlag(flag: string): {};
@@ -26,11 +26,12 @@ function revertSortedArgs(processArgs, argv) {
26
26
  return originalInputOrder;
27
27
  }
28
28
  exports.revertSortedArgs = revertSortedArgs;
29
- function buildCommand(args) {
29
+ function buildCommand(args, prependLauncher = false) {
30
+ const prependText = prependLauncher ? 'launcher ' : '';
30
31
  if (args.length === 1) {
31
32
  // do not add quotes around arguments if there is only one argument
32
33
  // `heroku run "rake test"` should work like `heroku run rake test`
33
- return args[0];
34
+ return `${prependText}${args[0]}`;
34
35
  }
35
36
  let cmd = '';
36
37
  for (let arg of args) {
@@ -39,7 +40,7 @@ function buildCommand(args) {
39
40
  }
40
41
  cmd = cmd + ' ' + arg;
41
42
  }
42
- return cmd.trim();
43
+ return `${prependText}${cmd.trim()}`;
43
44
  }
44
45
  exports.buildCommand = buildCommand;
45
46
  function buildEnvFromFlag(flag) {