Skip to content

Commit

Permalink
feat: more scratch org creation flags (#641)
Browse files Browse the repository at this point in the history
* feat: more scratch org creation flags

* fix: edit messages for new flags

* feat: edition overrides definition file, both are allowed

* test: allow edition with config file

* test: remove unused test dep

---------

Co-authored-by: Juliet Shackell <[email protected]>
  • Loading branch information
mshanemc and jshackell-sfdc authored Apr 18, 2023
1 parent c133036 commit c09d229
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 14 deletions.
4 changes: 4 additions & 0 deletions command-snapshot.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,18 @@
"async",
"client-id",
"definition-file",
"description",
"duration-days",
"edition",
"json",
"name",
"no-ancestors",
"no-namespace",
"release",
"set-default",
"target-dev-hub",
"track-source",
"username",
"wait"
],
"alias": ["env:create:scratch"]
Expand Down
48 changes: 44 additions & 4 deletions messages/create_scratch.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,17 @@ Create a scratch org.

# description

There are two ways to create a scratch org: specify a definition file that contains the options or use the --edition flag to specify the one required option. If you want to set options other than the edition, such as org features or settings, you must use a definition file.
There are two ways to create a scratch org: either specify a definition file that contains the options or use the --edition flag to specify the one required option.

For either method, you can also use these flags; if you use them with --definition-file, they override their equivalent option in the scratch org definition file:

* --description
* --name (equivalent to the "orgName" option)
* --username
* --release
* --edition

If you want to set options other than the preceding ones, such as org features or settings, you must use a definition file.

You must specify a Dev Hub to create a scratch org, either with the --target-dev-hub flag or by setting your default Dev Hub with the target-dev-hub configuration variable.

Expand All @@ -14,9 +24,13 @@ You must specify a Dev Hub to create a scratch org, either with the --target-dev

<%= config.bin %> <%= command.id %> --edition=developer --alias my-scratch-org

- Specify the Dev Hub using its alias and a scratch org definition file. Set the scratch org as your default and specify that it expires in 3 days:
- Create a scratch org with a definition file. Specify the Dev Hub using its alias, set the scratch org as your default, and specify that it expires in 3 days:

<%= config.bin %> <%= command.id %> --target-dev-hub MyHub --definition-file config/project-scratch-def.json --set-default --duration-days 3

- Create a preview Enterprise edition scratch org; for use only during Salesforce release transition periods:

<%= config.bin %> <%= command.id %> --target-dev-hub=MyHub --definition-file config/project-scratch-def.json --set-default --duration-days 3
<%= config.bin %> <%= command.id %> --edition=enterprise --alias my-scratch-org --target-dev-hub MyHub --release preview

# flags.target-hub.summary

Expand Down Expand Up @@ -44,7 +58,7 @@ Don't include second-generation managed package (2GP) ancestors in the scratch o

# flags.edition.summary

Salesforce edition of the scratch org.
Salesforce edition of the scratch org. Overrides the value of the "edition" option in the definition file, if set.

# flags.async.summary

Expand Down Expand Up @@ -96,6 +110,32 @@ Create the scratch org with no namespace, even if the Dev Hub has a namespace.

Number of days before the org expires.

# flags.username.summary

Username of the scratch org admin user. Overrides the value of the "username" option in the definition file, if set.

# flags.username.description

The username must be unique within the entire scratch org and sandbox universe. You must add your own logic to ensure uniqueness.

Omit this flag to have Salesforce generate a unique username for your org.

# flags.description.summary

Description of the scratch org in the Dev Hub. Overrides the value of the "description" option in the definition file, if set.

# flags.name.summary

Name of the org, such as "Acme Company". Overrides the value of the "orgName" option in the definition file, if set.

# flags.release.summary

Release of the scratch org as compared to the Dev Hub release.

# flags.release.description

By default, scratch orgs are on the same release as the Dev Hub. During Salesforce release transition periods, you can override this default behavior and opt in or out of the new release.

# prompt.secret

OAuth client secret of your personal connected app
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -234,4 +234,4 @@
"output": []
}
}
}
}
30 changes: 25 additions & 5 deletions src/commands/org/create/scratch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ export default class EnvCreateScratch extends SfCommand<ScratchCreateResponse> {
char: 'f',
summary: messages.getMessage('flags.definition-file.summary'),
description: messages.getMessage('flags.definition-file.description'),
exactlyOne: ['definition-file', 'edition'],
}),
'target-dev-hub': Flags.requiredHub({
char: 'v',
Expand All @@ -78,7 +77,6 @@ export default class EnvCreateScratch extends SfCommand<ScratchCreateResponse> {
'partner-group',
'partner-professional',
],
exactlyOne: ['definition-file', 'edition'],
}),
'no-namespace': Flags.boolean({
char: 'm',
Expand Down Expand Up @@ -115,6 +113,21 @@ export default class EnvCreateScratch extends SfCommand<ScratchCreateResponse> {
description: messages.getMessage('flags.track-source.description'),
allowNo: true,
}),
username: Flags.string({
summary: messages.getMessage('flags.username.summary'),
description: messages.getMessage('flags.username.description'),
}),
description: Flags.string({
summary: messages.getMessage('flags.description.summary'),
}),
name: Flags.string({
summary: messages.getMessage('flags.name.summary'),
}),
release: Flags.string({
summary: messages.getMessage('flags.release.summary'),
description: messages.getMessage('flags.release.description'),
options: ['preview', 'previous'],
}),
};
public async run(): Promise<ScratchCreateResponse> {
const lifecycle = Lifecycle.getInstance();
Expand All @@ -123,9 +136,16 @@ export default class EnvCreateScratch extends SfCommand<ScratchCreateResponse> {
if (!baseUrl) {
throw new SfError('No instance URL found for the dev hub');
}
const orgConfig = flags['definition-file']
? (JSON.parse(await fs.promises.readFile(flags['definition-file'], 'utf-8')) as Record<string, unknown>)
: { edition: flags.edition };
const orgConfig = {
...(flags['definition-file']
? (JSON.parse(await fs.promises.readFile(flags['definition-file'], 'utf-8')) as Record<string, unknown>)
: {}),
...(flags.edition ? { edition: flags.edition } : {}),
...(flags.username ? { username: flags.username } : {}),
...(flags.description ? { description: flags.description } : {}),
...(flags.name ? { orgName: flags.name } : {}),
...(flags.release ? { release: flags.release } : {}),
};

const createCommandOptions: ScratchOrgCreateOptions = {
hubOrg: flags['target-dev-hub'],
Expand Down
16 changes: 12 additions & 4 deletions test/nut/scratchCreate.nut.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*/
import * as fs from 'fs';
import * as path from 'path';
import { execCmd, TestSession } from '@salesforce/cli-plugins-testkit';
import { execCmd, genUniqueString, TestSession } from '@salesforce/cli-plugins-testkit';
import { assert, expect } from 'chai';
import { AuthFields, Messages, Global, StateAggregator } from '@salesforce/core';
import { secretTimeout } from '../../src/commands/org/create/scratch';
Expand Down Expand Up @@ -42,9 +42,6 @@ describe('env create scratch NUTs', () => {
it('non-existent config file', () => {
execCmd('env:create:scratch -f badfile.json', { ensureExitCode: 1 });
});
it('config file AND edition', () => {
execCmd('env:create:scratch -f config/project-scratch-def.json --edition developer', { ensureExitCode: 1 });
});
it('wait zero', () => {
execCmd('env:create:scratch -f config/project-scratch-def.json --wait 0', { ensureExitCode: 1 });
});
Expand Down Expand Up @@ -85,6 +82,17 @@ describe('env create scratch NUTs', () => {
).jsonOutput?.result;
expect(resp).to.have.all.keys(keys);
});
it('creates an org from config file with "override" flags ', () => {
const expectedUsername = genUniqueString('%[email protected]');
const resp = execCmd<ScratchCreateResponse>(
`env:create:scratch -f config/project-scratch-def.json --json --username ${expectedUsername} --description "new one" --name TheOrg --wait 60`,
{
ensureExitCode: 0,
}
).jsonOutput?.result;
expect(resp).to.have.all.keys(keys);
expect(resp?.username).to.equal(expectedUsername);
});
it('creates an org with tracking disabled ', async () => {
const resp = execCmd<ScratchCreateResponse>(
'env:create:scratch --edition developer --no-track-source --json --wait 60',
Expand Down

0 comments on commit c09d229

Please sign in to comment.