diff --git a/packages/core/src/PackageMetadata.ts b/packages/core/src/PackageMetadata.ts index 0308c3ad6..4989043ad 100644 --- a/packages/core/src/PackageMetadata.ts +++ b/packages/core/src/PackageMetadata.ts @@ -30,4 +30,5 @@ export default interface PackageMetadata { reconcileProfiles?: boolean; creation_details?: { creation_time?: number; timestamp?: number }; deployments?: { target_org: string; sub_directory?: string; installation_time?: number; timestamp?: number }[]; + apiVersion?: string; } diff --git a/packages/core/src/package/packageCreators/CreatePackage.ts b/packages/core/src/package/packageCreators/CreatePackage.ts index 6a598b0f9..bc7dc824c 100644 --- a/packages/core/src/package/packageCreators/CreatePackage.ts +++ b/packages/core/src/package/packageCreators/CreatePackage.ts @@ -7,6 +7,9 @@ import SourcePackageGenerator from '../../generators/SourcePackageGenerator'; export abstract class CreatePackage { private startTime: number; + + // Child classes parse the project config again, to avoid mutation + private packageManifest; private packageDescriptor; private packageDirectory; @@ -18,18 +21,22 @@ export abstract class CreatePackage { protected logger?: Logger, protected pathToReplacementForceIgnore?: string, protected configFilePath?: string - ) {} + ) { + this.packageManifest = ProjectConfig.getSFDXPackageManifest(this.projectDirectory); + //Get Package Descriptor + this.packageDescriptor = ProjectConfig.getPackageDescriptorFromConfig(this.sfdx_package, this.packageManifest); + this.packageDirectory = this.packageDescriptor['path']; + } public async exec(): Promise { //Get Type of Package this.packageArtifactMetadata.package_type = this.getTypeOfPackage(); + + this.packageArtifactMetadata.apiVersion = this.packageManifest.sourceApiVersion; + //Capture Start Time this.startTime = Date.now(); - //Get Package Descriptor - this.packageDescriptor = ProjectConfig.getSFDXPackageDescriptor(this.projectDirectory, this.sfdx_package); - this.packageDirectory = this.packageDescriptor['path']; - //Print Header this.printHeader(); diff --git a/packages/core/src/package/packageInstallers/InstallSourcePackageImpl.ts b/packages/core/src/package/packageInstallers/InstallSourcePackageImpl.ts index 96dd7769a..dcd2d6dae 100644 --- a/packages/core/src/package/packageInstallers/InstallSourcePackageImpl.ts +++ b/packages/core/src/package/packageInstallers/InstallSourcePackageImpl.ts @@ -94,7 +94,8 @@ export default class InstallSourcePackageImpl extends InstallPackage { this.options.waitTime, this.options.optimizeDeployment, this.options.skipTesting, - this.targetusername + this.targetusername, + this.options.apiVersion ); let deploySourceToOrgImpl: DeploymentExecutor = new DeploySourceToOrgImpl( @@ -299,12 +300,14 @@ export default class InstallSourcePackageImpl extends InstallPackage { waitTime: string, optimizeDeployment: boolean, skipTest: boolean, - target_org: string + target_org: string, + apiVersion: string ): Promise { let mdapi_options = {}; mdapi_options['ignore_warnings'] = true; mdapi_options['wait_time'] = waitTime; mdapi_options['checkonly'] = false; + mdapi_options['apiVersion'] = apiVersion; if (skipTest) { let orgDetails: OrgDetails; diff --git a/packages/core/src/package/packageInstallers/InstallUnlockedPackageImpl.ts b/packages/core/src/package/packageInstallers/InstallUnlockedPackageImpl.ts index 1a5d98ad6..d521f9581 100644 --- a/packages/core/src/package/packageInstallers/InstallUnlockedPackageImpl.ts +++ b/packages/core/src/package/packageInstallers/InstallUnlockedPackageImpl.ts @@ -37,7 +37,8 @@ export default class InstallUnlockedPackageImpl extends InstallPackage { this.options['publishWaitTime'], this.options['installationkey'], this.options['securitytype'], - this.options['upgradetype'] + this.options['upgradetype'], + this.options.apiVersion ); SFPLogger.log( `Executing installation command: ${installUnlockedPackageWrapper.getGeneratedSFDXCommandWithParams()}` @@ -45,6 +46,12 @@ export default class InstallUnlockedPackageImpl extends InstallPackage { await installUnlockedPackageWrapper.exec(false); } + /** + * Checks whether unlocked package version is installed in org. + * Overrides base class method. + * @param skipIfPackageInstalled + * @returns + */ protected async isPackageToBeInstalled(skipIfPackageInstalled: boolean): Promise { try { if (skipIfPackageInstalled) { diff --git a/packages/core/src/sfdxwrappers/InstallUnlockedPackageImpl.ts b/packages/core/src/sfdxwrappers/InstallUnlockedPackageImpl.ts index 62a3ab14e..2de6d0eea 100644 --- a/packages/core/src/sfdxwrappers/InstallUnlockedPackageImpl.ts +++ b/packages/core/src/sfdxwrappers/InstallUnlockedPackageImpl.ts @@ -12,7 +12,8 @@ export default class InstallUnlockedPackageImpl extends SFDXCommand { private publishWaitTime?: string, private installationkey?: string, private securityType?: string, - private upgradeType?: string + private upgradeType?: string, + private apiVersion?: string ) { super(targetUserName, working_directory, logger, logLevel); } @@ -36,6 +37,7 @@ export default class InstallUnlockedPackageImpl extends SFDXCommand { if (this.publishWaitTime) command += ` --publishwait=${this.publishWaitTime}`; if (this.securityType) command += ` --securitytype=${this.securityType}`; if (this.upgradeType) command += ` --upgradetype=${this.upgradeType}`; + if (this.apiVersion) command += ` --apiversion=${this.apiVersion}`; return command; } diff --git a/packages/core/src/sfpcommands/source/DeploySourceToOrgImpl.ts b/packages/core/src/sfpcommands/source/DeploySourceToOrgImpl.ts index faa11f296..b34d06408 100644 --- a/packages/core/src/sfpcommands/source/DeploySourceToOrgImpl.ts +++ b/packages/core/src/sfpcommands/source/DeploySourceToOrgImpl.ts @@ -49,7 +49,7 @@ export default class DeploySourceToOrgImpl implements DeploymentExecutor { let sourceToMdapiConvertor = new SourceToMDAPIConvertor( this.project_directory, this.source_directory, - this.deployment_options['apiVersion'], + this.deployment_options.apiVersion, this.packageLogger ); @@ -262,6 +262,10 @@ export default class DeploySourceToOrgImpl implements DeploymentExecutor { command += ` --ignoreerrors`; } + if (this.deployment_options.apiVersion) { + command += ` --apiversion ${this.deployment_options.apiVersion}`; + } + return command; } diff --git a/packages/sfpowerscripts-cli/src/commands/sfpowerscripts/package/source/install.ts b/packages/sfpowerscripts-cli/src/commands/sfpowerscripts/package/source/install.ts index 6f89ac791..b1b34a1ec 100644 --- a/packages/sfpowerscripts-cli/src/commands/sfpowerscripts/package/source/install.ts +++ b/packages/sfpowerscripts-cli/src/commands/sfpowerscripts/package/source/install.ts @@ -7,7 +7,7 @@ import * as fs from 'fs-extra'; import { PackageInstallationStatus } from '@dxatscale/sfpowerscripts.core/lib/package/packageInstallers/PackageInstallationResult'; import { ConsoleLogger } from '@dxatscale/sfpowerscripts.core/lib/logger/SFPLogger'; import { DeploymentType } from '@dxatscale/sfpowerscripts.core/lib/sfpcommands/source/DeploymentExecutor'; - +import PackageMetadata from '@dxatscale/sfpowerscripts.core/lib/PackageMetadata'; // Initialize Messages with the current plugin directory Messages.importMessagesDirectory(__dirname); @@ -95,7 +95,7 @@ export default class InstallSourcePackage extends InstallPackageCommand { try { let artifactMetadataFilepath = this.artifactFilePaths.packageMetadataFilePath; - let packageMetadata = JSON.parse(fs.readFileSync(artifactMetadataFilepath).toString()); + let packageMetadata: PackageMetadata = JSON.parse(fs.readFileSync(artifactMetadataFilepath).toString()); console.log('Package Metadata:'); console.log(packageMetadata); @@ -106,6 +106,7 @@ export default class InstallSourcePackage extends InstallPackageCommand { optimizeDeployment: optimizeDeployment, skipTesting: skipTesting, waitTime: wait_time, + apiVersion: packageMetadata.apiVersion || packageMetadata.payload.Package.version, // Use package.xml version for backwards compat with old artifacts }; let installSourcePackageImpl: InstallSourcePackageImpl = new InstallSourcePackageImpl( diff --git a/packages/sfpowerscripts-cli/src/commands/sfpowerscripts/package/unlocked/install.ts b/packages/sfpowerscripts-cli/src/commands/sfpowerscripts/package/unlocked/install.ts index d835e594b..f6fb57a0c 100644 --- a/packages/sfpowerscripts-cli/src/commands/sfpowerscripts/package/unlocked/install.ts +++ b/packages/sfpowerscripts-cli/src/commands/sfpowerscripts/package/unlocked/install.ts @@ -3,6 +3,7 @@ import { Messages } from '@salesforce/core'; import InstallPackageCommand from '../../../../InstallPackageCommand'; import InstallUnlockedPackageImpl from '@dxatscale/sfpowerscripts.core/lib/package/packageInstallers/InstallUnlockedPackageImpl'; import { PackageInstallationStatus } from '@dxatscale/sfpowerscripts.core/lib/package/packageInstallers/PackageInstallationResult'; +import PackageMetadata from '@dxatscale/sfpowerscripts.core/lib/PackageMetadata'; import { ConsoleLogger } from '@dxatscale/sfpowerscripts.core/lib/logger/SFPLogger'; const fs = require('fs'); @@ -119,7 +120,7 @@ export default class InstallUnlockedPackage extends InstallPackageCommand { const waitTime = this.flags.waittime; const publishWaitTime = this.flags.publishwaittime; const skipIfAlreadyInstalled = this.flags.skipifalreadyinstalled; - let packageMetadata; + let packageMetadata: PackageMetadata; let sourceDirectory; // Figure out the package version id from the artifact @@ -138,6 +139,7 @@ export default class InstallUnlockedPackage extends InstallPackageCommand { upgradetype: upgrade_type, waitTime: waitTime, publishWaitTime: publishWaitTime, + apiVersion: packageMetadata.apiVersion || packageMetadata.payload.Package.version, // Use package.xml version for backwards compat with old artifacts }; let installUnlockedPackageImpl: InstallUnlockedPackageImpl = new InstallUnlockedPackageImpl( diff --git a/packages/sfpowerscripts-cli/src/impl/deploy/DeployImpl.ts b/packages/sfpowerscripts-cli/src/impl/deploy/DeployImpl.ts index 0937c77ca..32a56adaf 100644 --- a/packages/sfpowerscripts-cli/src/impl/deploy/DeployImpl.ts +++ b/packages/sfpowerscripts-cli/src/impl/deploy/DeployImpl.ts @@ -134,8 +134,9 @@ export default class DeployImpl { queue[i].skipTesting, this.props.waitTime.toString(), pkgDescriptor, - false //Queue already filtered by deploy, there is no further need for individual + false, //Queue already filtered by deploy, there is no further need for individual //commands to decide the skip logic. TODO: fix this incorrect pattern + packageMetadata.apiVersion || packageMetadata.payload.Package.version // Use package.xml version for backwards compat with old artifacts ); if ( @@ -516,24 +517,35 @@ export default class DeployImpl { skipTesting: boolean, waitTime: string, pkgDescriptor: any, - skipIfPackageInstalled: boolean + skipIfPackageInstalled: boolean, + apiVersion: string ): Promise { let packageInstallationResult: PackageInstallationResult; if (this.props.deploymentMode == DeploymentMode.NORMAL) { if (packageType === 'unlocked') { + let options = { + installationkey: null, + apexcompile: 'package', + securitytype: 'AdminsOnly', + upgradetype: 'Mixed', + waitTime: waitTime, + apiVersion: apiVersion, + }; + packageInstallationResult = await this.installUnlockedPackage( targetUsername, + sourceDirectoryPath, packageMetadata, - skipIfPackageInstalled, - waitTime, - sourceDirectoryPath + options, + skipIfPackageInstalled ); } else if (packageType === 'source') { let options = { optimizeDeployment: this.isOptimizedDeploymentForSourcePackage(pkgDescriptor), skipTesting: skipTesting, waitTime: waitTime, + apiVersion: apiVersion, }; packageInstallationResult = await this.installSourcePackage( @@ -549,8 +561,8 @@ export default class DeployImpl { sfdx_package, targetUsername, sourceDirectoryPath, - skipIfPackageInstalled, - packageMetadata + packageMetadata, + skipIfPackageInstalled ); } else { throw new Error(`Unhandled package type ${packageType}`); @@ -579,8 +591,8 @@ export default class DeployImpl { sfdx_package, targetUsername, sourceDirectoryPath, - skipIfPackageInstalled, - packageMetadata + packageMetadata, + skipIfPackageInstalled ); } else { throw new Error(`Unhandled package type ${packageType}`); @@ -591,19 +603,11 @@ export default class DeployImpl { private installUnlockedPackage( targetUsername: string, + sourceDirectoryPath: string, packageMetadata: PackageMetadata, - skip_if_package_installed: boolean, - waitTime: string, - sourceDirectoryPath: string + options: any, + skip_if_package_installed: boolean ): Promise { - let options = { - installationkey: null, - apexcompile: 'package', - securitytype: 'AdminsOnly', - upgradetype: 'Mixed', - waitTime: waitTime, - }; - let installUnlockedPackageImpl: InstallUnlockedPackageImpl = new InstallUnlockedPackageImpl( packageMetadata.package_name, targetUsername, @@ -650,8 +654,8 @@ export default class DeployImpl { sfdx_package: string, targetUsername: string, sourceDirectoryPath: string, - skip_if_package_installed: boolean, - packageMetadata: PackageMetadata + packageMetadata: PackageMetadata, + skip_if_package_installed: boolean ): Promise { let installDataPackageImpl: InstallDataPackageImpl = new InstallDataPackageImpl( sfdx_package, diff --git a/packages/sfpowerscripts-cli/src/impl/prepare/PrepareOrgJob.ts b/packages/sfpowerscripts-cli/src/impl/prepare/PrepareOrgJob.ts index ecb030357..1e6d070ce 100644 --- a/packages/sfpowerscripts-cli/src/impl/prepare/PrepareOrgJob.ts +++ b/packages/sfpowerscripts-cli/src/impl/prepare/PrepareOrgJob.ts @@ -9,7 +9,7 @@ import SFPLogger, { } from '@dxatscale/sfpowerscripts.core/lib/logger/SFPLogger'; import { Stage } from '../Stage'; import SFPStatsSender from '@dxatscale/sfpowerscripts.core/lib/stats/SFPStatsSender'; -import InstallUnlockedPackageImpl from '@dxatscale/sfpowerscripts.core/lib/sfdxwrappers/InstallUnlockedPackageImpl'; +import InstallUnlockedPackageWrapper from '@dxatscale/sfpowerscripts.core/lib/sfdxwrappers/InstallUnlockedPackageImpl'; import ScratchOrg from '@dxatscale/sfpowerscripts.core/lib/scratchorg/ScratchOrg'; import PoolJobExecutor, { JobError, ScriptExecutionResult } from '../pool/PoolJobExecutor'; import { Connection, Org } from '@salesforce/core'; @@ -54,7 +54,7 @@ export default class PrepareOrgJob extends PoolJobExecutor { SFPLogger.log(`Installing sfpowerscripts_artifact package to the ${scratchOrg.alias}`, null, packageLogger); - let installUnlockedPackageImpl: InstallUnlockedPackageImpl = new InstallUnlockedPackageImpl( + let installUnlockedPackageWrapper: InstallUnlockedPackageWrapper = new InstallUnlockedPackageWrapper( packageLogger, logLevel, null, @@ -65,7 +65,7 @@ export default class PrepareOrgJob extends PoolJobExecutor { '60' ); - await installUnlockedPackageImpl.exec(true); + await installUnlockedPackageWrapper.exec(true); SFPLogger.log(`Installing package depedencies to the ${scratchOrg.alias}`, LoggerLevel.INFO, packageLogger); SFPLogger.log(`Installing Package Dependencies of this repo in ${scratchOrg.alias}`);