Skip to content

Commit

Permalink
Merge pull request #1351 from contentstack/development
Browse files Browse the repository at this point in the history
Release 54: Development-to-Staging
  • Loading branch information
cs-raj authored Mar 27, 2024
2 parents 3c9840b + 96f1242 commit 77f2b77
Show file tree
Hide file tree
Showing 36 changed files with 743 additions and 988 deletions.
993 changes: 314 additions & 679 deletions package-lock.json

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions packages/contentstack-audit/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@contentstack/cli-audit",
"version": "1.5.0",
"version": "1.5.1",
"description": "Contentstack audit plugin",
"author": "Contentstack CLI",
"homepage": "https://github.com/contentstack/cli",
Expand All @@ -21,7 +21,7 @@
"@contentstack/cli-command": "~1.2.16",
"@contentstack/cli-utilities": "~1.6.0",
"@oclif/plugin-help": "^5",
"@oclif/plugin-plugins": "^4.1.9",
"@oclif/plugin-plugins": "^5.0.0",
"chalk": "^4.1.2",
"fast-csv": "^4.3.6",
"fs-extra": "^11.1.1",
Expand Down Expand Up @@ -86,4 +86,4 @@
"keywords": [
"oclif"
]
}
}
28 changes: 21 additions & 7 deletions packages/contentstack-audit/src/audit-base-command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,13 @@ import { print } from './util/log';
import { auditMsg } from './messages';
import { BaseCommand } from './base-command';
import { Entries, GlobalField, ContentType, Extensions, Workflows } from './modules';
import { CommandNames, ContentTypeStruct, OutputColumn, RefErrorReturnType } from './types';
import {
CommandNames,
ContentTypeStruct,
OutputColumn,
RefErrorReturnType,
WorkflowExtensionsRefErrorReturnType,
} from './types';

export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseCommand> {
private currentCommand!: CommandNames;
Expand Down Expand Up @@ -113,7 +119,6 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
config: this.sharedConfig,
fix: this.currentCommand === 'cm:stacks:audit:fix',
};

switch (module) {
case 'content-types':
missingCtRefs = await new ContentType(cloneDeep(constructorParam)).run();
Expand Down Expand Up @@ -303,15 +308,15 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma

const tableKeys = Object.keys(missingRefs[0]);
const arrayOfObjects = tableKeys.map((key) => {
if (['title', 'name', 'uid', 'content_types', 'fixStatus'].includes(key)) {
if (['title', 'name', 'uid', 'content_types', 'branches', 'fixStatus'].includes(key)) {
return {
[key]: {
minWidth: 7,
header: key,
get: (row: Record<string, unknown>) => {
if (key === 'fixStatus') {
return chalk.green(typeof row[key] === 'object' ? JSON.stringify(row[key]) : row[key]);
} else if (key === 'content_types') {
} else if (key === 'content_types' || key === 'branches') {
return chalk.red(typeof row[key] === 'object' ? JSON.stringify(row[key]) : row[key]);
} else {
return chalk.white(typeof row[key] === 'object' ? JSON.stringify(row[key]) : row[key]);
Expand Down Expand Up @@ -371,14 +376,22 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
const ws = createWriteStream(csvPath).on('error', reject);
const defaultColumns = Object.keys(OutputColumn);
const userDefinedColumns = this.sharedConfig.flags.columns ? this.sharedConfig.flags.columns.split(',') : null;
let missingRefs: RefErrorReturnType[] = Object.values(listOfMissingRefs).flat();
let missingRefs: RefErrorReturnType[] | WorkflowExtensionsRefErrorReturnType[] =
Object.values(listOfMissingRefs).flat();
const columns: (keyof typeof OutputColumn)[] = userDefinedColumns
? [...userDefinedColumns, ...defaultColumns.filter((val: string) => !userDefinedColumns.includes(val))]
: defaultColumns;

if (this.sharedConfig.flags.filter) {
const [column, value]: [keyof typeof OutputColumn, string] = this.sharedConfig.flags.filter.split('=');
missingRefs = missingRefs.filter((row: RefErrorReturnType) => row[OutputColumn[column]] === value);
// Filter the missingRefs array
missingRefs = missingRefs.filter((row) => {
if (OutputColumn[column] in row) {
const rowKey = OutputColumn[column] as keyof (RefErrorReturnType | WorkflowExtensionsRefErrorReturnType);
return row[rowKey] === value;
}
return false;
});
}

const rowData: Record<string, string | string[]>[] = [];
Expand All @@ -387,7 +400,8 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma

for (const column of columns) {
if (Object.keys(issue).includes(OutputColumn[column])) {
row[column] = issue[OutputColumn[column]] as string;
const issueKey = OutputColumn[column] as keyof typeof issue;
row[column] = issue[issueKey] as string;
row[column] = typeof row[column] === 'object' ? JSON.stringify(row[column]) : row[column];
}
}
Expand Down
1 change: 1 addition & 0 deletions packages/contentstack-audit/src/messages/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const commonMsg = {
WORKFLOW_FIX_CONFIRMATION: 'Would you like to overwrite existing file?',
EXTENSION_FIX_WARN: `The extension associated with UID {uid} and title '{title}' will be removed.`,
EXTENSION_FIX_CONFIRMATION: `Would you like to overwrite existing file?`,
WF_BRANCH_REMOVAL: `Removing the branch '{branch} from workflow with UID {uid} and name {name} will be removed.'`,
};

const auditMsg = {
Expand Down
35 changes: 32 additions & 3 deletions packages/contentstack-audit/src/modules/workflows.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export default class Workflows {
public missingCtInWorkflows: Workflow[];
public missingCts: Set<string>;
public workflowPath: string;
public isBranchFixDone: boolean;

constructor({
log,
Expand All @@ -41,6 +42,7 @@ export default class Workflows {
this.missingCtInWorkflows = [];
this.missingCts = new Set();
this.workflowPath = '';
this.isBranchFixDone = false;
}
/**
* Check whether the given path for the workflow exists or not
Expand All @@ -55,6 +57,7 @@ export default class Workflows {
return {};
}


this.workflowPath = join(this.folderPath, this.fileName);
this.workflowSchema = existsSync(this.workflowPath)
? values(JSON.parse(readFileSync(this.workflowPath, 'utf8')) as Workflow[])
Expand All @@ -64,9 +67,20 @@ export default class Workflows {

for (const workflow of this.workflowSchema) {
const ctNotPresent = workflow.content_types.filter((ct) => !this.ctUidSet.has(ct));
if (ctNotPresent.length) {
const branch = workflow?.branches?.filter((branch) => branch !== this.config?.branch);

if (ctNotPresent.length || branch?.length) {
const tempwf = cloneDeep(workflow);
tempwf.content_types = ctNotPresent;
tempwf.content_types = ctNotPresent || [];

if (workflow?.branches) {
tempwf.branches = branch;
}

if (branch?.length) {
this.isBranchFixDone = true;
}

ctNotPresent.forEach((ct) => this.missingCts.add(ct));
this.missingCtInWorkflows.push(tempwf);
}
Expand All @@ -80,7 +94,7 @@ export default class Workflows {
);
}

if (this.fix && this.missingCtInWorkflows.length) {
if (this.fix && (this.missingCtInWorkflows.length || this.isBranchFixDone)) {
await this.fixWorkflowSchema();
this.missingCtInWorkflows.forEach((wf) => (wf.fixStatus = 'Fixed'));
}
Expand All @@ -96,6 +110,21 @@ export default class Workflows {
if (Object.keys(newWorkflowSchema).length !== 0) {
for (const workflow of this.workflowSchema) {
const fixedCts = workflow.content_types.filter((ct) => !this.missingCts.has(ct));
const fixedBranches: string[] = [];

workflow?.branches?.forEach((branch) => {
if (branch !== this.config?.branch) {
const { uid, name } = workflow;
this.log($t(commonMsg.WF_BRANCH_REMOVAL, { uid, name, branch }), { color: 'yellow' });
} else {
fixedBranches.push(branch);
}
});

if (fixedBranches.length > 0) {
newWorkflowSchema[workflow.uid].branches = fixedBranches;
}

if (fixedCts.length) {
newWorkflowSchema[workflow.uid].content_types = fixedCts;
} else {
Expand Down
4 changes: 4 additions & 0 deletions packages/contentstack-audit/src/types/content-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ type RefErrorReturnType = {
title?: string;
};

type WorkflowExtensionsRefErrorReturnType = RefErrorReturnType & { branches?: string[] };

// NOTE Type 1
type ReferenceFieldDataType = CommonDataTypeStruct & {
reference_to: string[];
Expand Down Expand Up @@ -119,6 +121,7 @@ enum OutputColumn {
title = 'title',
'uid' = 'uid',
'missingCts' = 'content_types',
'Missing Branches' = 'branches',
}

export {
Expand All @@ -137,4 +140,5 @@ export {
OutputColumn,
ContentTypeSchemaType,
GlobalFieldSchemaTypes,
WorkflowExtensionsRefErrorReturnType,
};
3 changes: 2 additions & 1 deletion packages/contentstack-audit/src/types/workflow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ export interface Workflow {
enabled?: boolean;
deleted_at?: any;
missingRefs?: any;
fixStatus?:string
fixStatus?: string;
branches?: string[];
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
"org_uid": "org1",
"api_key": "apiKey",
"content_types": [
"ct1"
"ct1",
"ct45",
"ct14"
],
"enabled": false,
"deleted_at": false
Expand All @@ -16,7 +18,8 @@
"org_uid": "org1",
"api_key": "apiKey",
"content_types": [
"ct2"
"ct2",
"ct6"
],
"enabled": false,
"deleted_at": false
Expand All @@ -43,5 +46,21 @@
],
"enabled": false,
"deleted_at": false
},
"wf5": {
"name": "wf5",
"uid": "wf5",
"org_uid": "org1",
"api_key": "apiKey",
"content_types": [
"ct4"
],
"branches": [
"main",
"development",
"stage"
],
"enabled": false,
"deleted_at": false
}
}
40 changes: 16 additions & 24 deletions packages/contentstack-audit/test/unit/modules/workflow.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ describe('Workflows', () => {
.it(
'should expect missingRefs equal to workflow which has missing refs, missingCts equal to missing Cts',
async () => {
wf.config.branch = 'development';
const missingRefs = await wf.run();
expect(wf.workflowSchema).eql(values(JSON.parse(fs.readFileSync(wf.workflowPath, 'utf8'))));
expect(missingRefs).eql([
Expand All @@ -67,33 +68,22 @@ describe('Workflows', () => {
enabled: false,
deleted_at: false,
},
{
api_key: 'apiKey',
branches: ['main', 'stage'],
content_types: [],
deleted_at: false,
enabled: false,
name: 'wf5',
org_uid: 'org1',
uid: 'wf5',
},
]);
expect(wf.missingCts).eql(new Set(['ct45', 'ct14', 'ct6']));
},
);
});

describe('run method with valid path and empty ctSchema to check the missing references', () => {
const wf = new Workflows({
log: () => {},
moduleName: 'workflows',
ctSchema: [],
config: Object.assign(config, {
basePath: resolve(`./test/unit/mock/contents/`),
flags: {},
}),
});

fancy
.stdout({ print: process.env.PRINT === 'true' || true })
.stub(ux, 'confirm', async () => true)
.it('should expect missingRefs equal to all workflows', async () => {
const missingRefs = await wf.run();
wf.workflowSchema.pop();
expect(missingRefs).eql(wf.workflowSchema);
});
});

describe('run method with audit fix for workflows with valid path and empty ctSchema', () => {
const wf = new Workflows({
log: () => {},
Expand All @@ -111,6 +101,7 @@ describe('Workflows', () => {
.stub(wf, 'log', async () => {})
.stub(ux, 'confirm', async () => true)
.stub(wf, 'WriteFileSync', () => {})
.stub(wf, 'writeFixContent', () => {})
.it('the run function should run and flow should go till fixWorkflowSchema', async () => {
const fixedReference = await wf.run();
expect(fixedReference).eql([
Expand All @@ -136,13 +127,14 @@ describe('Workflows', () => {
},
{
api_key: 'apiKey',
content_types: ['ct88'],
branches: ['main', 'stage'],
content_types: [],
deleted_at: false,
enabled: false,
fixStatus: 'Fixed',
name: 'wf6',
name: 'wf5',
org_uid: 'org1',
uid: 'wf6',
uid: 'wf5',
},
]);
});
Expand Down
6 changes: 3 additions & 3 deletions packages/contentstack-bootstrap/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@
"test:report": "nyc --reporter=lcov mocha \"test/**/*.test.js\""
},
"dependencies": {
"@contentstack/cli-cm-seed": "~1.7.0",
"@contentstack/cli-cm-seed": "~1.7.3",
"@contentstack/cli-command": "~1.2.16",
"@contentstack/cli-utilities": "~1.6.0",
"inquirer": "8.2.4",
"mkdirp": "^1.0.4",
"tar": "^6.1.13"
"tar": "^6.2.1 "
},
"devDependencies": {
"@oclif/test": "^2.5.6",
Expand Down Expand Up @@ -73,4 +73,4 @@
}
},
"repository": "contentstack/cli"
}
}
4 changes: 2 additions & 2 deletions packages/contentstack-branches/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@contentstack/cli-cm-branches",
"description": "Contentstack CLI plugin to do branches operations",
"version": "1.0.23",
"version": "1.0.24",
"author": "Contentstack",
"bugs": "https://github.com/contentstack/cli/issues",
"dependencies": {
Expand Down Expand Up @@ -95,4 +95,4 @@
}
},
"repository": "https://github.com/contentstack/cli"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,9 @@ export function assetFolderCreateScript(contentType) {
const createAssetTask = () => {
return {
title: 'Create Assets Folder',
title: 'Check and create asset folder in base branch',
successTitle: 'Assets folder Created Successfully',
failedTitle: 'Failed to create assets folder',
failedTitle: 'Failed to create assets folder in base branch',
task: async () => {
try {
const baseAssetsFolderCount = await getAssetCount(branch, true);
Expand Down
Loading

0 comments on commit 77f2b77

Please sign in to comment.