Skip to content

Commit 4b0762a

Browse files
Variants bulk publish and unpublish (#1664)
* Implemented variants entries bulk publish feature (#1515) * Implemented variants entries bulk publish feature * Fixed PR comments * Added variant entries pagination * Implemented error handling * Upgraded axios package version * Removed secrets-scan workflow file * Implemented variants entries bulk unpublish (#1521) * Implemented variants entries bulk unpublish * Upgraded axios package * Removed secrets-scan.yml workflow file * Fixed PR comments * Fixed PR comments * Implemented cross publish with variant entries (#1529) * Implemented cross publish variant entries * Fixed PR comments * Fixed cross publish issue and updated variant entry publish payload (#1569) * Fixed cross publish issue and updated variant entry publish payload * Fixed PR comments * Fixed PR comments * Reverted code changes * Removed api_version from header * Added new flag publish-without-base in entry variants publish (#1580) * Fixed variants cross publish issue (#1603) * Removed publish-without-base flag due to new variants publish rules * version bump * Removed un-necessary empty lines * version bump (#1639) * Fixed merge conflits (#1647) * Fixed merge conflits * Fixed variants publish issue when bulkPublishLimit is 1 * Merge branch 'development' into variants-bulk-publish-and-unpublish (#1657) * Fixed merge conflits (#1659) * Fix/merge conflits (#1662) * Fixed merge conflits * Fixed merge conflits * resolved conflits * Resolved merge conflits * updated readme file * Removed tsconfig file * version bump added
1 parent 21a8afa commit 4b0762a

File tree

18 files changed

+435
-103
lines changed

18 files changed

+435
-103
lines changed

package-lock.json

Lines changed: 7 additions & 36 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/contentstack-branches/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ $ npm install -g @contentstack/cli-cm-branches
3737
$ csdx COMMAND
3838
running command...
3939
$ csdx (--version)
40-
@contentstack/cli-cm-branches/1.2.0 darwin-arm64 node-v22.8.0
40+
@contentstack/cli-cm-branches/1.2.0 darwin-arm64 node-v22.2.0
4141
$ csdx --help [COMMAND]
4242
USAGE
4343
$ csdx COMMAND

packages/contentstack-bulk-publish/README.md

Lines changed: 53 additions & 11 deletions
Large diffs are not rendered by default.

packages/contentstack-bulk-publish/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@contentstack/cli-cm-bulk-publish",
33
"description": "Contentstack CLI plugin for bulk publish actions",
4-
"version": "1.6.0",
4+
"version": "1.7.0",
55
"author": "Contentstack",
66
"bugs": "https://github.com/contentstack/cli/issues",
77
"dependencies": {

packages/contentstack-bulk-publish/src/commands/cm/bulk-publish/cross-publish.js

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ class CrossPublishCommand extends Command {
4646
updatedFlags.deliveryToken = await cliux.prompt('Enter delivery token of your source environment');
4747
}
4848
updatedFlags.bulkPublish = updatedFlags.bulkPublish === 'false' ? false : true;
49-
49+
updatedFlags.includeVariants = updatedFlags.includeVariants === false ? false : true;
5050
stack = await getStack(config);
5151
}
5252

@@ -155,6 +155,10 @@ class CrossPublishCommand extends Command {
155155
_flags.deliveryToken = _flags['delivery-token'];
156156
delete _flags['delivery-token'];
157157
}
158+
if ('include-variants' in _flags) {
159+
_flags.includeVariants = _flags['include-variants'];
160+
delete _flags['include-variants'];
161+
}
158162
return _flags;
159163
}
160164
}
@@ -257,6 +261,10 @@ CrossPublishCommand.flags = {
257261
}),
258262
onlyAssets: flags.boolean({ description: 'Unpublish only assets', default: false }),
259263
onlyEntries: flags.boolean({ description: 'Unpublish only entries', default: false }),
264+
'include-variants': flags.boolean({
265+
description: 'Include Variants flag will publish all associated variant entries.',
266+
default: false,
267+
}),
260268
};
261269

262270
CrossPublishCommand.examples = [
@@ -278,8 +286,11 @@ CrossPublishCommand.examples = [
278286
'Using --stack-api-key flag',
279287
'csdx cm:bulk-publish:cross-publish --content-type [CONTENT TYPE] --source-env [SOURCE ENV] --environments [DESTINATION ENVIRONMENT] --locales [LOCALE] --stack-api-key [STACK API KEY] --delivery-token [DELIVERY TOKEN]',
280288
'',
289+
'Using --include-variants flag',
290+
'csdx cm:bulk-publish:cross-publish --content-type [CONTENT TYPE] --source-env [SOURCE ENV] --environments [DESTINATION ENVIRONMENT] --locales [LOCALE] --stack-api-key [STACK API KEY] --delivery-token [DELIVERY TOKEN] [--include-variants]',
291+
'',
281292
];
282293

283-
CrossPublishCommand.usage = `cm:bulk-publish:cross-publish [-a <value>] [--retry-failed <value>] [--bulk-publish <value>] [--content-type <value>] [--locales <value>] [--source-env <value>] [--environments <value>] [--delivery-token <value>] [-c <value>] [-y] [--branch <value>] [--onlyAssets] [--onlyEntries]`;
294+
CrossPublishCommand.usage = `cm:bulk-publish:cross-publish [-a <value>] [--retry-failed <value>] [--bulk-publish <value>] [--content-type <value>] [--locales <value>] [--source-env <value>] [--environments <value>] [--delivery-token <value>] [-c <value>] [-y] [--branch <value>] [--onlyAssets] [--onlyEntries] [--include-variants]`;
284295

285296
module.exports = CrossPublishCommand;

packages/contentstack-bulk-publish/src/commands/cm/entries/publish.js

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,19 @@ class PublishEntriesCommand extends Command {
2121
entriesFlags.publishAllContentTypes =
2222
entriesFlags['publish-all-content-types'] || entriesFlags.publishAllContentTypes || false;
2323
entriesFlags.apiVersion = entriesFlags['api-version'] || '3';
24+
entriesFlags.includeVariants = entriesFlags['include-variants'] || entriesFlags.includeVariants || false;
25+
entriesFlags.entryUid = entriesFlags['entry-uid'] || entriesFlags.entryUid;
26+
27+
if (entriesFlags.entryUid === undefined) {
28+
delete entriesFlags['entryUid'];
29+
}
2430
delete entriesFlags['api-version'];
2531
delete entriesFlags['retry-failed'];
2632
delete entriesFlags['content-types'];
2733
delete entriesFlags['bulk-publish'];
2834
delete entriesFlags['publish-all-content-types'];
35+
delete entriesFlags['include-variants'];
36+
delete entriesFlags['entry-uid'];
2937

3038
let updatedFlags;
3139
try {
@@ -243,6 +251,11 @@ PublishEntriesCommand.flags = {
243251
}),
244252
'delivery-token': flags.string({ description: 'The delivery token of the source environment.' }),
245253
'source-env': flags.string({ description: 'Source environment' }),
254+
'entry-uid': flags.string({ description: 'Entry Uid for publish all associated variant entries.' }),
255+
'include-variants': flags.boolean({
256+
default: false, // set the default value to false
257+
description: 'Include Variants flag will publish all associated variant entries with base entry.',
258+
}),
246259
};
247260

248261
PublishEntriesCommand.examples = [
@@ -266,11 +279,17 @@ PublishEntriesCommand.examples = [
266279
'',
267280
'Using --stack-api-key',
268281
'csdx cm:entries:publish -e [ENVIRONMENT 1] [ENVIRONMENT 2] --locales [LOCALE 1] [LOCALE 2] --stack-api-key [STACK API KEY] --source-env [SOURCE ENVIRONMENT] --delivery-token [DELIVERY TOKEN]',
282+
'',
283+
'Using --include-variants',
284+
'csdx cm:entries:publish --content-types [CONTENT TYPE 1] [CONTENT TYPE 2] -e [ENVIRONMENT 1] [ENVIRONMENT 2] --locales [LOCALE 1] [LOCALE 2] --stack-api-key [STACK API KEY] --source-env [SOURCE ENVIRONMENT] --delivery-token [DELIVERY TOKEN] [--include-variants]',
285+
'',
286+
'Using --entry-uid and --include-variants',
287+
'csdx cm:entries:publish --content-types [CONTENT TYPE 1] [CONTENT TYPE 2] -e [ENVIRONMENT 1] [ENVIRONMENT 2] --locales [LOCALE 1] [LOCALE 2] --stack-api-key [STACK API KEY] --source-env [SOURCE ENVIRONMENT] --delivery-token [DELIVERY TOKEN] --entry-uid [ENTRY UID] [--include-variants]',
269288
];
270289

271290
PublishEntriesCommand.aliases = ['cm:bulk-publish:entries'];
272291

273292
PublishEntriesCommand.usage =
274-
'cm:entries:publish [-a <value>] [--retry-failed <value>] [--bulk-publish <value>] [--publish-all-content-types] [--content-types <value>] [--locales <value>] [-e <value>] [-c <value>] [-y] [--branch <value>] [--delivery-token <value>] [--source-env <value>]';
293+
'cm:entries:publish [-a <value>] [--retry-failed <value>] [--bulk-publish <value>] [--publish-all-content-types] [--content-types <value>] [--locales <value>] [-e <value>] [-c <value>] [-y] [--branch <value>] [--delivery-token <value>] [--source-env <value>] [--entry-uid <value>] [--include-variants]';
275294

276295
module.exports = PublishEntriesCommand;

packages/contentstack-bulk-publish/src/commands/cm/entries/unpublish.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,13 @@ class UnpublishCommand extends Command {
1919
unpublishFlags.onlyAssets = false;
2020
unpublishFlags.onlyEntries = true;
2121
unpublishFlags.apiVersion = unpublishFlags['api-version'] || '3';
22+
unpublishFlags.includeVariants = unpublishFlags['include-variants'] || false;
2223
delete unpublishFlags['api-version'];
2324
delete unpublishFlags['retry-failed'];
2425
delete unpublishFlags['bulk-unpublish'];
2526
delete unpublishFlags['content-type'];
2627
delete unpublishFlags['delivery-token'];
28+
delete unpublishFlags['include-variants'];
2729

2830
let updatedFlags;
2931
try {
@@ -59,7 +61,6 @@ class UnpublishCommand extends Command {
5961
updatedFlags.deliveryToken = await cliux.prompt('Enter delivery token of your source environment');
6062
}
6163
updatedFlags.bulkUnpublish = updatedFlags.bulkUnpublish === 'false' ? false : true;
62-
6364
stack = await getStack(config);
6465
}
6566
if (!updatedFlags.deliveryToken && updatedFlags.deliveryToken.length === 0) {
@@ -136,6 +137,7 @@ UnpublishCommand.flags = {
136137
alias: flags.string({
137138
char: 'a',
138139
description: 'Alias (name) for the management token. You must use either the --alias flag or the --stack-api-key flag.',
140+
description: 'Alias (name) for the management token. You must use either the --alias flag or the --stack-api-key flag.',
139141
}),
140142
'stack-api-key': flags.string({
141143
char: 'k',
@@ -176,6 +178,10 @@ UnpublishCommand.flags = {
176178
'delivery-token': flags.string({
177179
description: 'The delivery token of the source environment.',
178180
}),
181+
'include-variants': flags.boolean({
182+
default: false, // set the default value to false
183+
description: 'Include Variants flag will unpublish all associated variant entries.'
184+
}),
179185
};
180186

181187
UnpublishCommand.examples = [
@@ -195,6 +201,9 @@ UnpublishCommand.examples = [
195201
'',
196202
'Using --stack-api-key flag',
197203
'csdx cm:stacks:unpublish --bulk-unpublish --content-type [CONTENT TYPE] --environment [SOURCE ENV] --locale [LOCALE] --stack-api-key [STACK API KEY] --delivery-token [DELIVERY TOKEN]',
204+
'',
205+
'Using --include-variants flag',
206+
'csdx cm:stacks:unpublish --bulk-unpublish --content-type [CONTENT TYPE] --environment [SOURCE ENV] --locale [LOCALE] --stack-api-key [STACK API KEY] --delivery-token [DELIVERY TOKEN] --include-variants',
198207
];
199208

200209
module.exports = UnpublishCommand;

packages/contentstack-bulk-publish/src/producer/cross-publish.js

Lines changed: 84 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ const { Command } = require('@contentstack/cli-command');
1616
const command = new Command();
1717
const { isEmpty } = require('../util');
1818
const { fetchBulkPublishLimit } = require('../util/common-utility');
19+
const VARIANTS_PUBLISH_API_VERSION = '3.2';
1920

2021
let bulkPublishSet = [];
2122
let bulkPublishAssetSet = [];
@@ -34,20 +35,30 @@ function getQueryParams(filter) {
3435
return queryString;
3536
}
3637

37-
async function bulkAction(stack, items, bulkPublish, filter, destEnv, apiVersion, bulkPublishLimit) {
38+
async function bulkAction(stack, items, bulkPublish, filter, destEnv, apiVersion, bulkPublishLimit, variantsFlag = false) {
3839
return new Promise(async (resolve) => {
3940
for (let index = 0; index < items.length; index++) {
4041
changedFlag = true;
4142

4243
if (bulkPublish) {
4344
if (bulkPublishSet.length < bulkPublishLimit && items[index].type === 'entry_published') {
44-
bulkPublishSet.push({
45+
const entry = {
4546
uid: items[index].data.uid,
4647
content_type: items[index].content_type_uid,
4748
locale: items[index].data.locale || 'en-us',
4849
version: items[index].data._version,
4950
publish_details: [items[index].data.publish_details] || [],
50-
});
51+
};
52+
53+
if (variantsFlag && Array.isArray(items[index].data.variants) && items[index].data.variants.length > 0) {
54+
entry.variants = items[index].data.variants || [];
55+
entry.variant_rules = {
56+
publish_latest_base: false,
57+
publish_latest_base_conditionally: true
58+
};
59+
}
60+
61+
bulkPublishSet.push(JSON.parse(JSON.stringify(entry)));
5162
}
5263

5364
if (bulkPublishAssetSet.length < bulkPublishLimit && items[index].type === 'asset_published') {
@@ -145,6 +156,7 @@ async function getSyncEntries(
145156
destEnv,
146157
apiVersion,
147158
bulkPublishLimit,
159+
variantsFlag = false,
148160
paginationToken = null,
149161
) {
150162
return new Promise(async (resolve, reject) => {
@@ -200,8 +212,19 @@ async function getSyncEntries(
200212
);
201213
}
202214

215+
if (variantsFlag) {
216+
for (let index = 0; index < entriesResponse?.items?.length; index++) {
217+
let variants = [];
218+
const entries = entriesResponse.items[index];
219+
variants = await getVariantEntries(stack, entries.content_type_uid, entriesResponse, index, queryParamsObj);
220+
if (variants.length > 0) {
221+
entriesResponse.items[index].data.variants = variants;
222+
}
223+
}
224+
}
225+
203226
if (entriesResponse.items.length > 0) {
204-
await bulkAction(stack, entriesResponse.items, bulkPublish, filter, destEnv, apiVersion, bulkPublishLimit);
227+
await bulkAction(stack, entriesResponse.items, bulkPublish, filter, destEnv, apiVersion, bulkPublishLimit, variantsFlag);
205228
}
206229
if (!entriesResponse.pagination_token) {
207230
if (!changedFlag) console.log('No Entries/Assets Found published on specified environment');
@@ -244,6 +267,48 @@ function setConfig(conf, bp) {
244267
filePath = initializeLogger(logFileName);
245268
}
246269

270+
async function getVariantEntries(stack, contentType, entries, index, queryParams, skip = 0) {
271+
try {
272+
let variantQueryParams = {
273+
locale: queryParams.locale || 'en-us',
274+
include_count: true,
275+
skip: skip, // Adding skip parameter for pagination
276+
limit: 100, // Set a limit to fetch up to 100 entries per request
277+
};
278+
const entryUid = entries.items[index].data.uid
279+
const variantsEntriesResponse = await stack
280+
.contentType(contentType)
281+
.entry(entryUid)
282+
.variants()
283+
.query(variantQueryParams)
284+
.find();
285+
286+
const variants = variantsEntriesResponse.items.map((entry) => ({
287+
uid: entry.variants._variant._uid,
288+
}));
289+
290+
if (variantsEntriesResponse.items.length === variantQueryParams.limit) {
291+
const nextVariants = await getVariantEntries(
292+
stack,
293+
contentType,
294+
entries,
295+
index,
296+
queryParams,
297+
skip + variantQueryParams.limit,
298+
);
299+
return Array.isArray(nextVariants) ? variants.concat(nextVariants) : variants;
300+
}
301+
return variants;
302+
} catch (error) {
303+
const errorMessage =
304+
error?.errorMessage ||
305+
error?.message ||
306+
error?.errors ||
307+
'Falied to fetch the variant entries, Please contact the admin for support.';
308+
throw new Error(`Error fetching variants: ${errorMessage}`);
309+
}
310+
}
311+
247312
async function start(
248313
{
249314
retryFailed,
@@ -258,6 +323,7 @@ async function start(
258323
destEnv,
259324
f_types,
260325
apiVersion,
326+
includeVariants,
261327
},
262328
stack,
263329
config,
@@ -310,7 +376,20 @@ async function start(
310376
// filter.type = (f_types) ? f_types : types // types mentioned in the config file (f_types) are given preference
311377
const queryParams = getQueryParams(filter);
312378
const bulkPublishLimit = fetchBulkPublishLimit(stack?.org_uid);
313-
await getSyncEntries(stack, config, queryParams, bulkPublish, filter, deliveryToken, destEnv, apiVersion, bulkPublishLimit);
379+
if (includeVariants) {
380+
apiVersion = VARIANTS_PUBLISH_API_VERSION;
381+
}
382+
await getSyncEntries(
383+
stack,
384+
config,
385+
queryParams,
386+
bulkPublish,
387+
filter,
388+
deliveryToken,
389+
destEnv,
390+
apiVersion, bulkPublishLimit,
391+
includeVariants,
392+
);
314393
}
315394
}
316395

0 commit comments

Comments
 (0)