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

Wr/pdr feat requests #675

Merged
merged 6 commits into from
Jul 5, 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
816 changes: 202 additions & 614 deletions CHANGELOG.md

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions command-snapshot.json
Original file line number Diff line number Diff line change
Expand Up @@ -164,10 +164,16 @@
"api-version",
"async",
"concise",
"coverage-formatters",
"json",
"junit",
"manifest",
"metadata",
"metadata-dir",
"post-destructive-changes",
"pre-destructive-changes",
"purge-on-delete",
"results-dir",
"single-package",
"source-dir",
"target-org",
Expand Down
20 changes: 20 additions & 0 deletions messages/deploy.metadata.validate.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,3 +132,23 @@ Failed to validate the deployment (%s). Due To:
# error.NoTestsSpecified

You must specify tests using the --tests flag if the --test-level flag is set to RunSpecifiedTests.

# flags.pre-destructive-changes.summary

File path for a manifest (destructiveChangesPre.xml) of components to delete before the deploy

# flags.post-destructive-changes.summary

File path for a manifest (destructiveChangesPost.xml) of components to delete after the deploy.

# flags.purge-on-delete.summary

Specify that deleted components in the destructive changes manifest file are immediately eligible for deletion rather than being stored in the Recycle Bin.

# flags.junit.summary

Output JUnit test results.

# flags.results-dir.summary

Output directory for code coverage and JUnit results; defaults to the deploy ID.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"tslib": "^2"
},
"devDependencies": {
"@oclif/plugin-command-snapshot": "^4.0.2",
"@oclif/plugin-command-snapshot": "^4.0.5",
"@salesforce/cli-plugins-testkit": "^4.1.1",
"@salesforce/dev-config": "^4.0.1",
"@salesforce/dev-scripts": "^5.4.2",
Expand Down Expand Up @@ -268,4 +268,4 @@
"output": []
}
}
}
}
12 changes: 9 additions & 3 deletions src/commands/project/deploy/report.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { coverageFormattersFlag } from '../../../utils/flags';

Messages.importMessagesDirectory(__dirname);
const messages = Messages.loadMessages('@salesforce/plugin-deploy-retrieve', 'deploy.metadata.report');
const testFlags = 'Test';

export default class DeployMetadataReport extends SfCommand<DeployResultJson> {
public static readonly description = messages.getMessage('description');
Expand All @@ -41,11 +42,15 @@ export default class DeployMetadataReport extends SfCommand<DeployResultJson> {
summary: messages.getMessage('flags.use-most-recent.summary'),
exactlyOne: ['use-most-recent', 'job-id'],
}),
'coverage-formatters': coverageFormattersFlag,
junit: Flags.boolean({ summary: messages.getMessage('flags.junit.summary') }),
'coverage-formatters': { ...coverageFormattersFlag, helpGroup: testFlags },
junit: Flags.boolean({
summary: messages.getMessage('flags.junit.summary'),
helpGroup: testFlags,
}),
'results-dir': Flags.directory({
dependsOn: ['junit', 'coverage-formatters'],
relationships: [{ type: 'some', flags: ['coverage-formatters', 'junit'] }],
summary: messages.getMessage('flags.results-dir.summary'),
helpGroup: testFlags,
}),
};

Expand All @@ -67,6 +72,7 @@ export default class DeployMetadataReport extends SfCommand<DeployResultJson> {

const formatter = new DeployReportResultFormatter(result, {
...deployOpts,
...flags,
...{ 'target-org': org },
});

Expand Down
12 changes: 9 additions & 3 deletions src/commands/project/deploy/resume.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import { coverageFormattersFlag } from '../../../utils/flags';
Messages.importMessagesDirectory(__dirname);
const messages = Messages.loadMessages('@salesforce/plugin-deploy-retrieve', 'deploy.metadata.resume');

const testFlags = 'Test';

export default class DeployMetadataResume extends SfCommand<DeployResultJson> {
public static readonly description = messages.getMessage('description');
public static readonly summary = messages.getMessage('summary');
Expand Down Expand Up @@ -61,11 +63,15 @@ export default class DeployMetadataResume extends SfCommand<DeployResultJson> {
helpValue: '<minutes>',
min: 1,
}),
'coverage-formatters': coverageFormattersFlag,
junit: Flags.boolean({ summary: messages.getMessage('flags.junit.summary') }),
'coverage-formatters': { ...coverageFormattersFlag, helpGroup: testFlags },
junit: Flags.boolean({
summary: messages.getMessage('flags.junit.summary'),
helpGroup: testFlags,
}),
'results-dir': Flags.directory({
dependsOn: ['junit', 'coverage-formatters'],
relationships: [{ type: 'some', flags: ['coverage-formatters', 'junit'] }],
summary: messages.getMessage('flags.results-dir.summary'),
helpGroup: testFlags,
}),
};

Expand Down
3 changes: 1 addition & 2 deletions src/commands/project/deploy/start.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,11 +154,10 @@ export default class DeployMetadata extends SfCommand<DeployResultJson> {
'coverage-formatters': { ...coverageFormattersFlag, helpGroup: testFlags },
junit: Flags.boolean({
summary: messages.getMessage('flags.junit.summary'),
dependsOn: ['coverage-formatters'],
helpGroup: testFlags,
}),
'results-dir': Flags.directory({
dependsOn: ['coverage-formatters'],
relationships: [{ type: 'some', flags: ['coverage-formatters', 'junit'] }],
summary: messages.getMessage('flags.results-dir.summary'),
helpGroup: testFlags,
}),
Expand Down
30 changes: 29 additions & 1 deletion src/commands/project/deploy/validate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@ import { DeployResultJson, TestLevel } from '../../../utils/types';
import { executeDeploy, resolveApi, determineExitCode, validateTests } from '../../../utils/deploy';
import { DEPLOY_STATUS_CODES_DESCRIPTIONS } from '../../../utils/errorCodes';
import { ConfigVars } from '../../../configMeta';
import { fileOrDirFlag, testLevelFlag, testsFlag } from '../../../utils/flags';
import { coverageFormattersFlag, fileOrDirFlag, testLevelFlag, testsFlag } from '../../../utils/flags';

Messages.importMessagesDirectory(__dirname);
const messages = Messages.loadMessages('@salesforce/plugin-deploy-retrieve', 'deploy.metadata.validate');
const deployMessages = Messages.loadMessages('@salesforce/plugin-deploy-retrieve', 'deploy.metadata');

const EXACTLY_ONE_FLAGS = ['manifest', 'source-dir', 'metadata', 'metadata-dir'];
const destructiveFlags = 'Delete';
const testFlags = 'Test';

export default class DeployMetadataValidate extends SfCommand<DeployResultJson> {
public static readonly description = messages.getMessage('description');
Expand Down Expand Up @@ -101,6 +103,32 @@ export default class DeployMetadataValidate extends SfCommand<DeployResultJson>
helpValue: '<minutes>',
min: 1,
}),
'coverage-formatters': { ...coverageFormattersFlag, helpGroup: testFlags },
junit: Flags.boolean({
summary: messages.getMessage('flags.junit.summary'),
helpGroup: testFlags,
}),
'results-dir': Flags.directory({
relationships: [{ type: 'some', flags: ['coverage-formatters', 'junit'] }],
summary: messages.getMessage('flags.results-dir.summary'),
helpGroup: testFlags,
}),
'purge-on-delete': Flags.boolean({
summary: messages.getMessage('flags.purge-on-delete.summary'),
dependsOn: ['manifest'],
relationships: [{ type: 'some', flags: ['pre-destructive-changes', 'post-destructive-changes'] }],
helpGroup: destructiveFlags,
}),
'pre-destructive-changes': Flags.file({
summary: messages.getMessage('flags.pre-destructive-changes.summary'),
dependsOn: ['manifest'],
helpGroup: destructiveFlags,
}),
'post-destructive-changes': Flags.file({
summary: messages.getMessage('flags.post-destructive-changes.summary'),
dependsOn: ['manifest'],
helpGroup: destructiveFlags,
}),
};

public static configurationVariablesSection = toHelpSection(
Expand Down
25 changes: 25 additions & 0 deletions test/commands/deploy/metadata/cancel.nut.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,31 @@ describe('deploy metadata cancel NUTs', () => {
expect(cancel.jsonOutput.name).to.equal('CannotCancelDeployError');
}
});

it.skip('should cancel most recently started deployment without specifying the flag', () => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there are a few of the new NUTs in this PR being skipped.

const first = execCmd<DeployResultJson>(
'deploy:metadata --source-dir force-app --async --ignore-conflicts --json',
{
ensureExitCode: 0,
}
).jsonOutput?.result;
assert(first);
assert(first.id);

const cacheBefore = readDeployCache(session.dir);
expect(cacheBefore).to.have.property(first.id);

const cancel = execCmd<DeployResultJson>('deploy:metadata:cancel --json');
assert(cancel.jsonOutput);
if (cancel.jsonOutput.status === 0) {
assert(cancel.jsonOutput.result);
assertSuccessfulCancel(session.dir, first, cancel.jsonOutput.result);
} else {
// the deploy likely already finished
expect(cancel.jsonOutput.exitCode).to.equal(1);
expect(cancel.jsonOutput.name).to.equal('CannotCancelDeployError');
}
});
});

describe('--job-id', () => {
Expand Down
17 changes: 17 additions & 0 deletions test/commands/deploy/metadata/quick.nut.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,23 @@ describe('deploy metadata quick NUTs', () => {
assert(deploy);
await testkit.expect.filesToBeDeployed(['force-app/**/*'], ['force-app/test/**/*']);
});

it.skip('should deploy previously validated deployment without specifying the flag', async () => {
const validation = await testkit.execute<DeployResultJson>('project:deploy:validate', {
args: '--source-dir force-app',
json: true,
exitCode: 0,
});
assert(validation);
await testkit.expect.filesToBeDeployed(['force-app/**/*'], ['force-app/test/**/*']);

const deploy = await testkit.execute<DeployResultJson>('project:deploy:quick', {
json: true,
exitCode: 0,
});
assert(deploy);
await testkit.expect.filesToBeDeployed(['force-app/**/*'], ['force-app/test/**/*']);
});
it('should deploy previously validated deployment with metadata format', async () => {
execCmd('project:convert:source --source-dir force-app --output-dir metadata');
const validation = await testkit.execute<DeployResultJson>('project:deploy:validate', {
Expand Down
15 changes: 15 additions & 0 deletions test/commands/deploy/metadata/report-mdapi.nut.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,21 @@ describe('deploy metadata report NUTs with source-dir', () => {
assert(deploy?.result);
expect(deploy.result.success).to.equal(true);
});

it.skip('should report most recently started deployment without specifying the flag', async () => {
await testkit.execute<DeployResultJson>('project deploy start', {
args: '--metadata-dir mdapiOut --async',
json: true,
exitCode: 0,
});

const deploy = await testkit.execute<DeployResultJson>('project deploy report', {
json: true,
exitCode: 0,
});
assert(deploy?.result);
expect(deploy.result.success).to.equal(true);
});
});

describe('--job-id', () => {
Expand Down
42 changes: 42 additions & 0 deletions test/commands/deploy/metadata/report.nut.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/

import * as fs from 'fs';
import * as path from 'path';
import { SourceTestkit } from '@salesforce/source-testkit';
import { assert, isObject } from '@salesforce/ts-types';
import { expect } from 'chai';
import { DeployResultJson } from '../../../../src/utils/types';

describe('deploy metadata report NUTs with source-dir', () => {
Expand Down Expand Up @@ -39,6 +42,21 @@ describe('deploy metadata report NUTs with source-dir', () => {
assert(isObject(deploy));
await testkit.expect.filesToBeDeployedViaResult(['force-app/**/*'], ['force-app/test/**/*'], deploy.result.files);
});

it.skip('should report most recently started deployment without specifying the flag', async () => {
await testkit.execute<DeployResultJson>('deploy:metadata', {
args: '--source-dir force-app --async',
json: true,
exitCode: 0,
});

const deploy = await testkit.execute<DeployResultJson>('deploy:metadata:report', {
json: true,
exitCode: 0,
});
assert(isObject(deploy));
await testkit.expect.filesToBeDeployedViaResult(['force-app/**/*'], ['force-app/test/**/*'], deploy.result.files);
});
});

describe('--job-id', () => {
Expand All @@ -57,4 +75,28 @@ describe('deploy metadata report NUTs with source-dir', () => {
await testkit.expect.filesToBeDeployedViaResult(['force-app/**/*'], ['force-app/test/**/*'], deploy.result.files);
});
});

describe('test flags', () => {
it('should override the --output-dir', async () => {
const first = await testkit.execute<DeployResultJson>('deploy:metadata', {
args: '--source-dir force-app --async --ignore-conflicts --test-level RunAllTestsInOrg --coverage-formatters html --junit --results-dir test-output',
json: true,
exitCode: 0,
});
const deploy = await testkit.execute<DeployResultJson>('deploy:metadata:report', {
args: `--job-id ${first?.result.id} --coverage-formatters html --coverage-formatters text --junit --results-dir test-output-override`,
json: true,
exitCode: 0,
});
expect(fs.existsSync(path.join(testkit.projectDir, 'test-output-override'))).to.be.true;
expect(fs.existsSync(path.join(testkit.projectDir, 'test-output-override', 'coverage'))).to.be.true;
expect(fs.existsSync(path.join(testkit.projectDir, 'test-output-override', 'coverage', 'html'))).to.be.true;
expect(fs.existsSync(path.join(testkit.projectDir, 'test-output-override', 'coverage', 'text.txt'))).to.be.true;
expect(fs.existsSync(path.join(testkit.projectDir, 'test-output-override', 'junit'))).to.be.true;
expect(fs.existsSync(path.join(testkit.projectDir, 'test-output-override', 'junit', 'junit.xml'))).to.be.true;
expect(fs.existsSync(path.join(testkit.projectDir, 'test-output'))).to.be.false;
assert(isObject(deploy));
await testkit.expect.filesToBeDeployedViaResult(['force-app/**/*'], ['force-app/test/**/*'], deploy.result.files);
});
});
});
25 changes: 25 additions & 0 deletions test/commands/deploy/metadata/resume.nut.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,31 @@ describe('deploy metadata resume NUTs', () => {

const cacheAfter = readDeployCache(testkit.projectDir);

expect(cacheAfter).to.have.property(first.result.id);
expect(cacheAfter[first.result.id]).have.property('status');
expect(cacheAfter[first.result.id].status).to.equal(RequestStatus.Succeeded);
});
it.skip('should resume most recently started deployment without specifying the flag', async () => {
const first = await testkit.execute<DeployResultJson>('deploy:metadata', {
args: '--source-dir force-app --async',
json: true,
exitCode: 0,
});
assert(first);
assert(first.result.id);

const cacheBefore = readDeployCache(testkit.projectDir);
expect(cacheBefore).to.have.property(first.result.id);

const deploy = await testkit.execute<DeployResultJson>('deploy:metadata:resume', {
json: true,
exitCode: 0,
});
assert(deploy);
await testkit.expect.filesToBeDeployedViaResult(['force-app/**/*'], ['force-app/test/**/*'], deploy.result.files);

const cacheAfter = readDeployCache(testkit.projectDir);

expect(cacheAfter).to.have.property(first.result.id);
expect(cacheAfter[first.result.id]).have.property('status');
expect(cacheAfter[first.result.id].status).to.equal(RequestStatus.Succeeded);
Expand Down
Loading