Skip to content

Commit

Permalink
Merge pull request #16 from forcedotcom/phale/W-11489082
Browse files Browse the repository at this point in the history
fix: package version. now stored in packdir in sfdx project
  • Loading branch information
peternhale authored Aug 18, 2022
2 parents bd36d28 + d2a9ed5 commit 7c6cfdf
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 59 deletions.
5 changes: 5 additions & 0 deletions src/package/package.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,11 @@ export class Package extends AsyncCreatable<PackageOptions> implements IPackage
return Promise.resolve(undefined);
}

public async getPackage(packageId: string): Promise<PackagingSObjects.Package2> {
const package2 = await this.options.connection.tooling.sobject('Package2').retrieve(packageId);
return package2 as unknown as PackagingSObjects.Package2;
}

public async getExternalSites(
subscriberPackageVersionId: string,
installationKey?: string
Expand Down
88 changes: 85 additions & 3 deletions src/package/packageVersion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,34 @@
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/

import { Connection, Messages, SfProject, PollingClient, Lifecycle, StatusResult } from '@salesforce/core';
import {
Connection,
Messages,
SfProject,
PollingClient,
Lifecycle,
StatusResult,
NamedPackageDir,
} from '@salesforce/core';
import { Duration } from '@salesforce/kit';
import {
PackageVersionCreateRequestResult,
PackageSaveResult,
PackageVersionCreateOptions,
PackageVersionOptions,
PackageVersionReportResult,
PackagingSObjects,
} from '../interfaces';
import * as pkgUtils from '../utils/packageUtils';
import { combineSaveErrors } from '../utils';
import { generatePackageAliasEntry, getConfigPackageDirectory } from '../utils/packageUtils';
import { PackageVersionCreate } from './packageVersionCreate';
import { getPackageVersionReport } from './packageVersionReport';
import { getCreatePackageVersionCreateRequestReport } from './packageVersionCreateRequestReport';
import { Package } from './package';

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

// const logger = Logger.childFromRoot('packageVersionCreate');
export class PackageVersion {
// @ts-ignore
Expand All @@ -44,6 +54,7 @@ export class PackageVersion {
const pvc = new PackageVersionCreate({ ...options, ...this.options });
const createResult = await pvc.createPackageVersion();
const waitResult = await this.waitForCreateVersion(
createResult.Package2Id,
createResult.Id,
options.wait ?? Duration.milliseconds(0),
options.pollInterval ? options.pollInterval : Duration.seconds(30)
Expand Down Expand Up @@ -120,6 +131,7 @@ export class PackageVersion {
* @param interval - frequency of checking for the package version to be created
*/
public async waitForCreateVersion(
packageId: string,
createPackageVersionRequestId: string,
wait: Duration = Duration.milliseconds(0),
interval: Duration = Duration.milliseconds(0)
Expand All @@ -128,6 +140,7 @@ export class PackageVersion {
const result = await this.getCreateVersionReport(createPackageVersionRequestId);
return result;
}
const resolvedWait = await this.resolveOrgDependentPollingTime(packageId, wait, interval);
let remainingWaitTime: Duration = wait;
let report: PackageVersionCreateRequestResult;
const pollingClient = await PollingClient.create({
Expand All @@ -154,6 +167,7 @@ export class PackageVersion {
payload: report,
};
case 'Success':
await this.updateProjectWithPackageVersion(this.project, report);
await Lifecycle.getInstance().emit('success', report);
return { completed: true, payload: report };
case 'Error':
Expand All @@ -162,7 +176,7 @@ export class PackageVersion {
}
},
frequency: interval,
timeout: wait,
timeout: resolvedWait,
});
try {
return pollingClient.subscribe<PackageVersionCreateRequestResult>();
Expand Down Expand Up @@ -217,4 +231,72 @@ export class PackageVersion {
updateResult.id = await pkgUtils.getSubscriberPackageVersionId(packageVersionId, this.connection);
return updateResult;
}

/**
* Increase the wait time for a package version that is org dependent.
*
* @param resolvedPackageId
* @param pollInterval
* @param wait
* @private
*/
private async resolveOrgDependentPollingTime(
resolvedPackageId: string,
wait: Duration,
pollInterval: Duration
): Promise<Duration> {
// If we are polling check to see if the package is Org-Dependent, if so, update the poll time
if (wait.milliseconds > 0) {
const query = `SELECT IsOrgDependent FROM Package2 WHERE Id = '${resolvedPackageId}'`;
try {
const pkgQueryResult = await this.connection.singleRecordQuery<PackagingSObjects.Package2>(query, {
tooling: true,
});
if (pkgQueryResult.IsOrgDependent) {
return Duration.seconds((60 / pollInterval.seconds) * wait.seconds);
}
} catch {
// do nothing
}
}
return wait;
}

private async updateProjectWithPackageVersion(
withProject: SfProject,
results: PackageVersionCreateRequestResult
): Promise<void> {
if (withProject && !process.env.SFDX_PROJECT_AUTOUPDATE_DISABLE_FOR_PACKAGE_VERSION_CREATE) {
const query = `SELECT Name, Package2Id, MajorVersion, MinorVersion, PatchVersion, BuildNumber, Description, Branch FROM Package2Version WHERE Id = '${results.Package2VersionId}'`;
const packageVersion = await this.connection.singleRecordQuery<PackagingSObjects.Package2Version>(query, {
tooling: true,
});
const packageVersionVersionString = `${packageVersion.MajorVersion}.${packageVersion.MinorVersion}.${packageVersion.PatchVersion}.${packageVersion.BuildNumber}`;
await this.generatePackageDirectory(packageVersion, withProject, packageVersionVersionString);
const newConfig = await generatePackageAliasEntry(
this.connection,
withProject,
packageVersion.SubscriberPackageVersionId,
packageVersionVersionString,
packageVersion.Branch,
packageVersion.Package2Id
);
withProject.getSfProjectJson().set('packageAliases', newConfig);
await withProject.getSfProjectJson().write();
}
}

private async generatePackageDirectory(
packageVersion: PackagingSObjects.Package2Version,
withProject: SfProject,
packageVersionVersionString: string
) {
const pkg = await (await Package.create({ connection: this.connection })).getPackage(packageVersion.Package2Id);
const pkgDir =
getConfigPackageDirectory(withProject.getPackageDirectories(), 'id', pkg.Id) ?? ({} as NamedPackageDir);
pkgDir.versionNumber = packageVersionVersionString;
pkgDir.versionDescription = packageVersion.Description;
const packageDirs = withProject.getPackageDirectories().map((pd) => (pkgDir['id'] === pd['id'] ? pkgDir : pd));
withProject.getSfProjectJson().set('packageDirectories', packageDirs);
}
}
44 changes: 0 additions & 44 deletions src/package/packageVersionCreate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import { ComponentSetBuilder, ConvertResult, MetadataConverter } from '@salesfor
import { uniqid } from '@salesforce/core/lib/testSetup';
import SettingsGenerator from '@salesforce/core/lib/org/scratchOrgSettingsGenerator';
import * as xml2js from 'xml2js';
import { Duration } from '@salesforce/kit';
import { PackageDirDependency } from '@salesforce/core/lib/sfProject';
import * as pkgUtils from '../utils/packageUtils';
import { consts } from '../constants';
Expand All @@ -44,8 +43,6 @@ const logger = Logger.childFromRoot('packageVersionCreate');

const DESCRIPTOR_FILE = 'package2-descriptor.json';

const POLL_INTERVAL_WITHOUT_VALIDATION_SECONDS = 5;

type PackageDescriptorJson = Partial<NamedPackageDir> &
Partial<{
id: string;
Expand Down Expand Up @@ -811,21 +808,6 @@ export class PackageVersionCreate {
errStr.toString(),
]);
}
let pollInterval = Duration.seconds(pkgUtils.POLL_INTERVAL_SECONDS);
let maxRetries = 0;

if (options.wait?.milliseconds > 0) {
if (options.skipvalidation === true) {
pollInterval = Duration.seconds(POLL_INTERVAL_WITHOUT_VALIDATION_SECONDS);
}
maxRetries = (60 / pollInterval.seconds) * options.wait.seconds;
}
[pollInterval, maxRetries] = await this.resolveOrgDependentPollingTime(
resolvedPackageId,
options,
pollInterval,
maxRetries
);

return (await this.listRequestById(createResult.id, this.connection))[0];
}
Expand Down Expand Up @@ -938,32 +920,6 @@ export class PackageVersionCreate {
});
}

private async resolveOrgDependentPollingTime(
resolvedPackageId: string,
options: PackageVersionCreateOptions,
pollInterval: Duration,
maxRetries: number
): Promise<[Duration, number]> {
let pi = pollInterval;
let mr = maxRetries;
// If we are polling check to see if the package is Org-Dependent, if so, update the poll time
if (options.wait) {
const query = `SELECT IsOrgDependent FROM Package2 WHERE Id = '${resolvedPackageId}'`;
try {
const pkgQueryResult = await this.connection.singleRecordQuery<PackagingSObjects.Package2>(query, {
tooling: true,
});
if (pkgQueryResult.IsOrgDependent) {
pi = Duration.seconds(POLL_INTERVAL_WITHOUT_VALIDATION_SECONDS);
mr = (60 / pollInterval.seconds) * options.wait.seconds;
}
} catch {
// do nothing
}
}
return [pi, mr];
}

private async validateFlagsForPackageType(packageId: string, options: PackageVersionCreateOptions): Promise<void> {
const packageType = await pkgUtils.getPackageType(packageId, this.connection);

Expand Down
15 changes: 7 additions & 8 deletions src/utils/packageUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -859,7 +859,7 @@ export async function pollForStatusWithInterval(
const record = pkgQueryResult.records[0];
return `${record.MajorVersion}.${record.MinorVersion}.${record.PatchVersion}-${record.BuildNumber}`;
});
const newConfig = await _generatePackageAliasEntry(
const newConfig = await generatePackageAliasEntry(
connection,
withProject,
results[0].SubscriberPackageVersionId,
Expand All @@ -870,7 +870,7 @@ export async function pollForStatusWithInterval(
withProject.getSfProjectJson().set('packageAliases', newConfig);
await withProject.getSfProjectJson().write();
}
Lifecycle.getInstance().emit(Package2VersionStatus.success, {
await Lifecycle.getInstance().emit(Package2VersionStatus.success, {
id,
packageVersionCreateRequestResult: results[0],
projectUpdated,
Expand All @@ -889,12 +889,12 @@ export async function pollForStatusWithInterval(
}
status = errors.length !== 0 ? errors.join('\n') : results[0].Error.join('\n');
}
Lifecycle.getInstance().emit(Package2VersionStatus.error, { id, status });
await Lifecycle.getInstance().emit(Package2VersionStatus.error, { id, status });
throw new SfError(status);
}
} else {
const remainingTime = Duration.milliseconds(interval.milliseconds * remainingRetries);
Lifecycle.getInstance().emit(Package2VersionStatus.inProgress, {
await Lifecycle.getInstance().emit(Package2VersionStatus.inProgress, {
id,
packageVersionCreateRequestResult: results[0],
message: '',
Expand Down Expand Up @@ -927,7 +927,7 @@ export async function pollForStatusWithInterval(
* @param packageId the 0Ho id
* @private
*/
async function _generatePackageAliasEntry(
export async function generatePackageAliasEntry(
connection: Connection,
project: SfProject,
packageVersionId: string,
Expand All @@ -942,9 +942,8 @@ async function _generatePackageAliasEntry(
let packageName;
if (!aliasForPackageId || aliasForPackageId.length === 0) {
const query = `SELECT Name FROM Package2 WHERE Id = '${packageId}'`;
packageName = await connection.tooling
.query<PackagingSObjects.Package2>(query)
.then((pkgQueryResult) => pkgQueryResult.records[0]?.Name);
const package2 = await connection.singleRecordQuery<PackagingSObjects.Package2>(query, { tooling: true });
packageName = package2.Name;
} else {
packageName = aliasForPackageId[0];
}
Expand Down
10 changes: 6 additions & 4 deletions test/package/packageTest.nut.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ describe('Integration tests for #salesforce/packaging library', function () {
`\n${JSON.stringify(result, undefined, 2)}`
);
pkgCreateVersionRequestId = result.Id;
pkgId = result.Package2Id;
});

it('get package version create report', async () => {
Expand Down Expand Up @@ -165,6 +166,7 @@ describe('Integration tests for #salesforce/packaging library', function () {
expect(results.Status).to.equal(PackagingSObjects.Package2VersionStatus.success);
});
const result = await pv.waitForCreateVersion(
pkgId,
pkgCreateVersionRequestId,
Duration.minutes(10),
Duration.seconds(30)
Expand Down Expand Up @@ -210,10 +212,10 @@ describe('Integration tests for #salesforce/packaging library', function () {
// eslint-disable-next-line no-console
console.log(`projectFile: ${JSON.stringify(projectFile, undefined, 2)}`);

// expect(result.Description).to.equal(
// projectFile.packageDirectories[0].versionDescription,
// `'force:package:version:report' Description mismatch: expected '${projectFile.packageDirectories[0].versionDescription}', got '${result.Description}'`
// );
expect(result.Description).to.equal(
projectFile.packageDirectories[0].versionDescription,
`'force:package:version:report' Description mismatch: expected '${projectFile.packageDirectories[0].versionDescription}', got '${result.Description}'`
);

expect(result.Name).to.equal(
projectFile.packageDirectories[0].versionName,
Expand Down

0 comments on commit 7c6cfdf

Please sign in to comment.