Skip to content

Commit ba05d3a

Browse files
authored
Merge pull request #1117 from salesforcecli/t/2gp-readiness/w-20839284/is-dev-use-pkg-zip-requested-flag
@W-20839284 Expose --generate-dev-zip parameter to sf package version create CLI command
2 parents 0491ce0 + 039814e commit ba05d3a

5 files changed

Lines changed: 164 additions & 22 deletions

File tree

command-snapshot.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,8 @@
432432
"version-description",
433433
"version-name",
434434
"version-number",
435-
"wait"
435+
"wait",
436+
"generate-pkg-zip"
436437
],
437438
"plugin": "@salesforce/plugin-packaging"
438439
},

messages/package_version_create.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,9 +145,13 @@ Return a new package version before completing package validations.
145145

146146
Specifying async validation returns the package version earlier in the process, allowing you to install and test the new version right away. If your development team is using continuous integration (CI) scripts, async validation can reduce your overall CI run time.
147147

148+
# flags.generate-pkg-zip.summary
149+
150+
Generate a package ZIP file that you can use for debugging or to examine the package contents.
151+
148152
# flags.skip-ancestor-check.summary
149153

150-
Overrides ancestry requirements, which allows you to specify a package ancestor that isn’t the highest released package version.
154+
Override ancestry requirements, which allows you to specify a package ancestor that isn’t the highest released package version.
151155

152156
# flags.post-install-url.summary
153157

src/commands/package/version/create.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,10 @@ export class PackageVersionCreateCommand extends SfCommand<PackageVersionCommand
142142
default: false,
143143
exclusive: ['skip-validation'],
144144
}),
145+
'generate-pkg-zip': Flags.boolean({
146+
summary: messages.getMessage('flags.generate-pkg-zip.summary'),
147+
default: false,
148+
}),
145149
tag: Flags.string({
146150
char: 't',
147151
summary: messages.getMessage('flags.tag.summary'),
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
/*
2+
* Copyright 2026, Salesforce, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
import * as fs from 'node:fs';
17+
import * as path from 'node:path';
18+
import { expect } from 'chai';
19+
import { execCmd, TestSession } from '@salesforce/cli-plugins-testkit';
20+
import { Org, SfProject } from '@salesforce/core';
21+
import { Duration } from '@salesforce/kit';
22+
import { PackageVersionCreateRequestResult } from '@salesforce/packaging';
23+
import { FileDownloadEntry } from '../../../src/commands/package/version/retrieve.js';
24+
25+
let packageName: string;
26+
let devHubOrg: Org;
27+
28+
describe('package:version:create with managed package (--generate-pkg-zip)', () => {
29+
let session: TestSession;
30+
let managedPackageId: string;
31+
32+
before('setup managed package', async function () {
33+
// TODO: Remove once 260 is released to instance the CI dev hub is running on
34+
this.skip();
35+
this.timeout(Duration.minutes(5).milliseconds);
36+
37+
session = await TestSession.create({
38+
devhubAuthStrategy: 'AUTO',
39+
project: { name: 'managed-pkg-test' },
40+
});
41+
42+
devHubOrg = await Org.create({ aliasOrUsername: session.hubOrg.username });
43+
44+
// Query for existing managed package
45+
const existingPkgQuery = `
46+
SELECT Id, Name, NamespacePrefix
47+
FROM Package2
48+
WHERE ContainerOptions = 'Managed'
49+
AND IsDeprecated = false
50+
AND Name = 'pnhmanaged'
51+
LIMIT 1
52+
`;
53+
const existingPkgRecords = (
54+
await devHubOrg
55+
.getConnection()
56+
.tooling.query<{ Id: string; Name: string; NamespacePrefix: string }>(existingPkgQuery)
57+
).records;
58+
59+
managedPackageId = existingPkgRecords[0].Id;
60+
61+
// Create minimal source structure for a custom object
62+
const objectName = 'TestObject__c';
63+
const objectDir = path.join(session.project.dir, 'force-app', 'main', 'default', 'objects', objectName);
64+
fs.mkdirSync(objectDir, { recursive: true });
65+
66+
fs.writeFileSync(
67+
path.join(objectDir, `${objectName}.object-meta.xml`),
68+
`<?xml version="1.0" encoding="UTF-8"?>
69+
<CustomObject xmlns="http://soap.sforce.com/2006/04/metadata">
70+
<deploymentStatus>Deployed</deploymentStatus>
71+
<label>Test Object</label>
72+
<nameField>
73+
<label>Test Object Name</label>
74+
<type>Text</type>
75+
</nameField>
76+
<pluralLabel>Test Objects</pluralLabel>
77+
<sharingModel>ReadWrite</sharingModel>
78+
</CustomObject>`
79+
);
80+
81+
// Configure the project for the managed package
82+
const project = await SfProject.resolve(session.project.dir);
83+
const projectJson = project.getSfProjectJson();
84+
const namespacePrefix = existingPkgRecords[0].NamespacePrefix;
85+
packageName = existingPkgRecords[0].Name;
86+
87+
const packageDirectory = {
88+
path: 'force-app',
89+
package: existingPkgRecords[0].Name,
90+
versionNumber: '1.0.0.NEXT',
91+
ancestorVersion: 'NONE',
92+
versionName: 'v1',
93+
default: true,
94+
};
95+
96+
projectJson.set('packageDirectories', [packageDirectory]);
97+
projectJson.set('packageAliases', { [packageName]: managedPackageId });
98+
projectJson.set('namespace', namespacePrefix);
99+
projectJson.writeSync();
100+
});
101+
102+
after(async () => {
103+
await session?.clean();
104+
});
105+
106+
it('should create a managed package version with --generate-pkg-zip flag and retrieve the metadata', async function () {
107+
this.timeout(Duration.minutes(25).milliseconds);
108+
109+
const createResult = execCmd<PackageVersionCreateRequestResult>(
110+
`package:version:create --package ${packageName} --wait 20 -x --generate-pkg-zip --version-description "Test pkg zip" --json --skip-ancestor-check`,
111+
{ ensureExitCode: 0, timeout: Duration.minutes(20).milliseconds }
112+
).jsonOutput?.result;
113+
114+
// Debug: verify the flag was actually set
115+
const pvcRequestId = createResult?.Id;
116+
const verifyQuery = `SELECT Id, IsDevUsePkgZipRequested FROM Package2VersionCreateRequest WHERE Id = '${pvcRequestId}'`;
117+
const verifyResult = await devHubOrg
118+
.getConnection()
119+
.tooling.query<{ Id: string; IsDevUsePkgZipRequested: boolean }>(verifyQuery);
120+
// eslint-disable-next-line no-console
121+
console.log('IsDevUsePkgZipRequested:', verifyResult.records[0]?.IsDevUsePkgZipRequested);
122+
123+
expect(createResult?.Status).to.equal('Success');
124+
const subscriberPkgVersionId = createResult?.SubscriberPackageVersionId;
125+
expect(subscriberPkgVersionId).to.match(/04t.{15}/);
126+
127+
const retrieveOutputDir = 'pkg-zip-test-output';
128+
const retrieveResult = execCmd<FileDownloadEntry[]>(
129+
`package:version:retrieve --package ${subscriberPkgVersionId} --output-dir ${retrieveOutputDir} --json`,
130+
{ ensureExitCode: 0 }
131+
).jsonOutput?.result;
132+
133+
expect(retrieveResult).to.be.an('array');
134+
expect(retrieveResult?.length).to.be.greaterThan(0);
135+
});
136+
});

yarn.lock

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -879,15 +879,7 @@
879879
"@smithy/types" "^4.12.0"
880880
tslib "^2.6.2"
881881

882-
"@aws-sdk/types@^3.222.0":
883-
version "3.957.0"
884-
resolved "https://registry.yarnpkg.com/@aws-sdk/types/-/types-3.957.0.tgz#06e899503028bdb8c655aa11a9a01f562882f361"
885-
integrity sha512-wzWC2Nrt859ABk6UCAVY/WYEbAd7FjkdrQL6m24+tfmWYDNRByTJ9uOgU/kw9zqLCAwb//CPvrJdhqjTznWXAg==
886-
dependencies:
887-
"@smithy/types" "^4.11.0"
888-
tslib "^2.6.2"
889-
890-
"@aws-sdk/types@^3.973.0":
882+
"@aws-sdk/types@^3.222.0", "@aws-sdk/types@^3.973.0":
891883
version "3.973.0"
892884
resolved "https://registry.yarnpkg.com/@aws-sdk/types/-/types-3.973.0.tgz#4e7428dbaac37797a81339f646f40f41cc22a1fe"
893885
integrity sha512-jYIdB7a7jhRTvyb378nsjyvJh1Si+zVduJ6urMNGpz8RjkmHZ+9vM2H07XaIB2Cfq0GhJRZYOfUCH8uqQhqBkQ==
@@ -2031,16 +2023,16 @@
20312023
terminal-link "^3.0.0"
20322024

20332025
"@salesforce/source-deploy-retrieve@^12.31.9":
2034-
version "12.31.10"
2035-
resolved "https://registry.yarnpkg.com/@salesforce/source-deploy-retrieve/-/source-deploy-retrieve-12.31.10.tgz#612886356d81c87eb9053bbc9173546556fd5f36"
2036-
integrity sha512-kUdJicJUd3/lzNQOvDW1Sc5iBl8PVv2Tz7L59YA/Le0fzZCYM72oyKwdbl/f6kc+MzJpMVia2+AxrvVZir8oJw==
2026+
version "12.31.9"
2027+
resolved "https://registry.yarnpkg.com/@salesforce/source-deploy-retrieve/-/source-deploy-retrieve-12.31.9.tgz#69592e0b1564157fce8b7c66b33412460fa62b6e"
2028+
integrity sha512-UVRmLVl+Es1jLGnSx4G2xxTNHR7L6v5uzOpBFbg1ADMOQ4b1v8cDwZO9noJa9xAG+MLJJ7zDkcqywgFxU/3mmQ==
20372029
dependencies:
20382030
"@salesforce/core" "^8.24.0"
20392031
"@salesforce/kit" "^3.2.4"
20402032
"@salesforce/ts-types" "^2.0.12"
20412033
"@salesforce/types" "^1.6.0"
20422034
fast-levenshtein "^3.0.0"
2043-
fast-xml-parser "^5.3.4"
2035+
fast-xml-parser "^4.5.3"
20442036
got "^11.8.6"
20452037
graceful-fs "^4.2.11"
20462038
ignore "^5.3.2"
@@ -2568,13 +2560,6 @@
25682560
"@smithy/util-stream" "^4.5.10"
25692561
tslib "^2.6.2"
25702562

2571-
"@smithy/types@^4.11.0":
2572-
version "4.11.0"
2573-
resolved "https://registry.yarnpkg.com/@smithy/types/-/types-4.11.0.tgz#c02f6184dcb47c4f0b387a32a7eca47956cc09f1"
2574-
integrity sha512-mlrmL0DRDVe3mNrjTcVcZEgkFmufITfUAPBEA+AHYiIeYyJebso/He1qLbP3PssRe22KUzLRpQSdBPbXdgZ2VA==
2575-
dependencies:
2576-
tslib "^2.6.2"
2577-
25782563
"@smithy/types@^4.12.0":
25792564
version "4.12.0"
25802565
resolved "https://registry.yarnpkg.com/@smithy/types/-/types-4.12.0.tgz#55d2479080922bda516092dbf31916991d9c6fee"
@@ -4782,6 +4767,13 @@ fast-xml-parser@5.2.5:
47824767
dependencies:
47834768
strnum "^2.1.0"
47844769

4770+
fast-xml-parser@^4.5.3:
4771+
version "4.5.3"
4772+
resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-4.5.3.tgz#c54d6b35aa0f23dc1ea60b6c884340c006dc6efb"
4773+
integrity sha512-RKihhV+SHsIUGXObeVy9AXiBbFwkVk7Syp8XgwN5U3JV416+Gwp/GO9i0JYKmikykgz/UHRrrV4ROuZEo/T0ig==
4774+
dependencies:
4775+
strnum "^1.1.1"
4776+
47854777
fast-xml-parser@^5.3.4:
47864778
version "5.3.4"
47874779
resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-5.3.4.tgz#06f39aafffdbc97bef0321e626c7ddd06a043ecf"
@@ -8376,6 +8368,11 @@ strip-json-comments@^3.1.1:
83768368
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
83778369
integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==
83788370

8371+
strnum@^1.1.1:
8372+
version "1.1.2"
8373+
resolved "https://registry.yarnpkg.com/strnum/-/strnum-1.1.2.tgz#57bca4fbaa6f271081715dbc9ed7cee5493e28e4"
8374+
integrity sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA==
8375+
83798376
strnum@^2.1.0:
83808377
version "2.1.1"
83818378
resolved "https://registry.yarnpkg.com/strnum/-/strnum-2.1.1.tgz#cf2a6e0cf903728b8b2c4b971b7e36b4e82d46ab"

0 commit comments

Comments
 (0)