Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: more scratch org creation flags #641

Merged
merged 6 commits into from
Apr 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
4 changes: 1 addition & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,10 @@
"@salesforce/prettier-config": "^0.0.2",
"@salesforce/ts-sinon": "1.4.6",
"@swc/core": "1.3.39",
"@types/chai-as-promised": "^7.1.5",
"@types/shelljs": "^0.8.10",
"@typescript-eslint/eslint-plugin": "^5.57.0",
"@typescript-eslint/parser": "^5.57.1",
"chai": "^4.3.7",
"chai-as-promised": "^7.1.1",
"eslint": "^8.38.0",
"eslint-config-prettier": "^8.6.0",
"eslint-config-salesforce": "^1.1.1",
Expand Down Expand Up @@ -236,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({
peternhale marked this conversation as resolved.
Show resolved Hide resolved
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
5 changes: 1 addition & 4 deletions test/unit/org/list.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
* Licensed under the BSD 3-Clause license.
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/
import { expect, use as ChaiUse } from 'chai';
import * as chaiAsPromised from 'chai-as-promised';
import { expect } from 'chai';
import { TestContext } from '@salesforce/core/lib/testSetup';
import { AuthInfo, Connection, Org } from '@salesforce/core';
import { stubMethod } from '@salesforce/ts-sinon';
Expand All @@ -14,8 +13,6 @@ import OrgListMock = require('../../shared/orgListMock');
import { OrgListCommand } from '../../../src/commands/org/list';
import { OrgListUtil } from '../../../src/shared/orgListUtil';

ChaiUse(chaiAsPromised);

describe('org:list', () => {
// Create new TestContext, which automatically creates and restores stubs
// pertaining to authorization, orgs, config files, etc...
Expand Down
14 changes: 0 additions & 14 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1332,13 +1332,6 @@
"@types/node" "*"
"@types/responselike" "^1.0.0"

"@types/chai-as-promised@^7.1.5":
version "7.1.5"
resolved "https://registry.yarnpkg.com/@types/chai-as-promised/-/chai-as-promised-7.1.5.tgz#6e016811f6c7a64f2eed823191c3a6955094e255"
integrity sha512-jStwss93SITGBwt/niYrkf2C+/1KTeZCZl1LaeezTlqppAKeoQC7jxyqYuP72sxBGKCIbw7oHgbYssIRzT5FCQ==
dependencies:
"@types/chai" "*"

"@types/chai@*", "@types/chai@^4.2.11":
version "4.3.4"
resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.4.tgz#e913e8175db8307d78b4e8fa690408ba6b65dee4"
Expand Down Expand Up @@ -2269,13 +2262,6 @@ cardinal@^2.1.1:
ansicolors "~0.3.2"
redeyed "~2.1.0"

chai-as-promised@^7.1.1:
version "7.1.1"
resolved "https://registry.yarnpkg.com/chai-as-promised/-/chai-as-promised-7.1.1.tgz#08645d825deb8696ee61725dbf590c012eb00ca0"
integrity sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA==
dependencies:
check-error "^1.0.2"

chai@^4.2.0, chai@^4.3.7:
version "4.3.7"
resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.7.tgz#ec63f6df01829088e8bf55fca839bcd464a8ec51"
Expand Down