Skip to content

Commit

Permalink
fix: add package:beta:version:promote and NUT
Browse files Browse the repository at this point in the history
  • Loading branch information
WillieRuemmele committed Aug 18, 2022
1 parent f9d3c9d commit 8db94c2
Show file tree
Hide file tree
Showing 5 changed files with 193 additions and 74 deletions.
5 changes: 3 additions & 2 deletions messages/package_version_promote.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ Promotes a package version to released status.

Supply the ID or alias of the package version you want to promote. Promotes the package version to released status.

Examples:
# examples

$ sfdx force:package:version:promote -p 04t...
$ sfdx force:package:version:promote -p awesome_package_alias
$ sfdx force:package:version:promote -p "Awesome Package Alias"
Expand All @@ -23,7 +24,7 @@ ID (starts with 04t) or alias of the package version to promote

The ID (starts with 04t) or alias of the package version to promote.

# packageVersionPromoteSetAsReleasedYesNo
# packageVersionPromoteConfirm

Are you sure you want to release package version %s? You can't undo this action. Release package (y/n)?

Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
"@oclif/core": "^1.13.10",
"@oclif/plugin-version": "^1.1.1",
"@salesforce/command": "^5.2.4",
"@salesforce/core": "^3.26.1",
"@salesforce/kit": "^1.5.45",
"@salesforce/core": "^3.26.2",
"@salesforce/kit": "^1.6.0",
"@salesforce/packaging": "^0.0.17",
"tslib": "^2"
},
Expand Down
62 changes: 57 additions & 5 deletions src/commands/force/package/beta/version/promote.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,29 @@
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/

import * as os from 'os';
import { flags, FlagsConfig, SfdxCommand } from '@salesforce/command';
import { Messages, SfdxPropertyKeys } from '@salesforce/core';
import { Messages, SfError } from '@salesforce/core';
import { SaveResult } from 'jsforce';
import {
BY_LABEL,
getHasMetadataRemoved,
getPackageIdFromAlias,
getPackageVersionId,
Package,
validateId,
} from '@salesforce/packaging';

Messages.importMessagesDirectory(__dirname);
const messages = Messages.loadMessages('@salesforce/plugin-packaging', 'package_version_promote');

export type PackageVersionPromoteResponse = { id: string; success: boolean; errors: Error[] };

export class PackageVersionPromoteCommand extends SfdxCommand {
public static readonly description = messages.getMessage('cliDescription');
public static readonly longDescription = messages.getMessage('cliDescriptionLong');
public static readonly help = messages.getMessage('help');
public static readonly orgType = SfdxPropertyKeys.DEFAULT_DEV_HUB_USERNAME;
public static readonly examples = messages.getMessage('examples').split(os.EOL);
public static readonly requiresDevhubUsername = true;
public static readonly requiresProject = true;
public static readonly flagsConfig: FlagsConfig = {
Expand All @@ -32,8 +44,48 @@ export class PackageVersionPromoteCommand extends SfdxCommand {
}),
};

public async run(): Promise<unknown> {
process.exitCode = 1;
return Promise.resolve('Not yet implemented');
public async run(): Promise<PackageVersionPromoteResponse> {
const conn = this.hubOrg.getConnection();
let packageId = getPackageIdFromAlias(this.flags.package, this.project) ?? (this.flags.package as string);

// ID can be 04t or 05i at this point
validateId([BY_LABEL.SUBSCRIBER_PACKAGE_VERSION_ID, BY_LABEL.PACKAGE_VERSION_ID], packageId);

// lookup the 05i ID, if needed
if (!packageId.startsWith('05i')) {
packageId = await getPackageVersionId(packageId, conn);
}

if (!this.flags.noprompt) {
// Warn when a Managed package has removed metadata
if (await getHasMetadataRemoved(packageId, conn)) {
this.ux.warn(messages.getMessage('hasMetadataRemovedWarning'));
}

// Prompt for confirmation
if (!(await this.ux.confirm(messages.getMessage('packageVersionPromoteConfirm', [this.flags.package])))) {
return;
}
}

const pkg = new Package({ connection: conn });
let result: SaveResult;

try {
result = await pkg.promote(packageId);
if (!result.success) {
throw SfError.wrap(result.errors.join(os.EOL));
}
} catch (e) {
const err = SfError.wrap(e);
if (err.name === 'DUPLICATE_VALUE' && err.message.includes('previously released')) {
err.message = messages.getMessage('previouslyReleasedMessage');
err.actions = [messages.getMessage('previouslyReleasedAction')];
}
throw err;
}
result.id = packageId;
this.ux.log(messages.getMessage('humanSuccess', [result.id]));
return result;
}
}
61 changes: 61 additions & 0 deletions test/commands/force/package/versionPromote.nut.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright (c) 2022, salesforce.com, inc.
* All rights reserved.
* 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 { execCmd, genUniqueString, TestSession } from '@salesforce/cli-plugins-testkit';
import { expect } from 'chai';
import { getPackageIdFromAlias } from '@salesforce/packaging';
import { SfProject } from '@salesforce/core';
import { PackageVersionPromoteResponse } from '../../../../src/commands/force/package/beta/version/promote';
// TODO: enable once `package:beta:version:create` is released
describe.skip('package:version:promote', () => {
let session: TestSession;
let packageId: string;
const pkgName = genUniqueString('dancingbears-');

before(async () => {
session = await TestSession.create({
setupCommands: ['sfdx force:org:create -d 1 -s -f config/project-scratch-def.json'],
project: { gitClone: 'https://github.com/trailheadapps/dreamhouse-lwc' },
});
execCmd(
`force:package:beta:create --name ${pkgName} --packagetype Unlocked --path force-app --description "Don't ease, don't ease, don't ease me in."`,
{ ensureExitCode: 0 }
);
// TODO: requires this command
execCmd(
`force:package:beta:version:create --package ${pkgName} --version 1.0.0 --codecoverage --description "Initial version"`,
{ ensureExitCode: 0 }
);
packageId = getPackageIdFromAlias(pkgName, SfProject.getInstance());
});

after(async () => {
await session?.clean();
});

it('should promote a package (human readable)', () => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
const result = execCmd(`force:package:beta:version:promote --package ${pkgName} --noprompt`, { ensureExitCode: 0 })
.shellOutput.stdout as string;
expect(result).to.contain(
`Successfully promoted the package version, ID: ${packageId}, to released. Starting in Winter ‘21, only unlocked package versions that have met the minimum 75% code coverage requirement can be promoted. Code coverage minimums aren’t enforced on org-dependent unlocked packages.`
);
});

it('should promote a package (--json)', () => {
const result = execCmd<PackageVersionPromoteResponse>(
`force:package:beta:version:promote --package ${pkgName} --noprompt --json`,
{
ensureExitCode: 0,
}
).jsonOutput.result;
expect(result).to.have.all.keys('id', 'success', 'errors');
expect(result.id).to.equal(packageId);
expect(result.success).to.equal(true);
expect(result.errors).to.equal([]);
});
});
Loading

0 comments on commit 8db94c2

Please sign in to comment.