Skip to content

Commit

Permalink
Deployment process polishing (#798)
Browse files Browse the repository at this point in the history
* git add stash troubleshooting

When git add / stash failure, display a message explaining to run `git config --system core.longpaths true` to solve the issue.

* countPackageXmlItems

* Count deployment items + fix test classes errors collection

* await

* cspell
  • Loading branch information
nvuillam authored Sep 24, 2024
1 parent cfbc275 commit dbdfc38
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 9 deletions.
1 change: 1 addition & 0 deletions .github/linters/.cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,7 @@
"localtest",
"loginasgrantedtopartnerbt",
"loglevel",
"longpaths",
"lors",
"lycheeignore",
"l\u2019acc\u00e8s",
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@

Note: Can be used with `sfdx plugins:install sfdx-hardis@beta` and docker image `hardisgroupcom/sfdx-hardis@beta`

## [5.0.5] 2024-09-24

- When git add / stash failure, display a message explaining to run `git config --system core.longpaths true` to solve the issue.
- Improve test classes errors collection during deployment check
- Display the number of elements deployed within a package.xml

## [5.0.4] 2024-09-24

- Fix errors collection during deployment check
Expand Down
37 changes: 34 additions & 3 deletions src/common/utils/deployTips.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,19 @@ export async function analyzeDeployErrorLogs(log: string, includeInLog = true, o
}

// Extract failed test classes
const failedTests: any[] = [];
const logRaw = stripAnsi(log);
const failedTests: any[] = [];
// sf project deploy output
extractFailedTestsInfoForSfCommand(logRaw, failedTests);
if (failedTests.length === 0) {
// Legacy sfdx force:source:deploy output
extractFailedTestsInfoForSfdxCommand(logRaw, failedTests);
}
await updatePullRequestResult(errorsAndTips, failedTests, options);
return { tips, errorsAndTips, failedTests, errLog: logResLines.join("\n") };
}

function extractFailedTestsInfoForSfdxCommand(logRaw: string, failedTests: any[]) {
const regexFailedTests = /Test Failures([\S\s]*?)Test Success/gm;
if (logRaw.match(regexFailedTests)) {
const failedTestsLines = (regexFailedTests
Expand Down Expand Up @@ -96,8 +107,28 @@ export async function analyzeDeployErrorLogs(log: string, includeInLog = true, o
}
}
}
updatePullRequestResult(errorsAndTips, failedTests, options);
return { tips, errorsAndTips, failedTests, errLog: logResLines.join("\n") };
}

function extractFailedTestsInfoForSfCommand(logRaw: string, failedTests: any[]) {
const regexFailedTests = /Test Failures([\S\s]*?)Test Success/gm;
if (logRaw.match(regexFailedTests)) {
const failedTestsString = (regexFailedTests.exec(logRaw) || [])[1].split(/\r?\n/).join("\n") + "\n•";
// Parse strings to extract main error line then stack
// eslint-disable-next-line no-regex-spaces, no-useless-escape
const regex = /^ (.*)\n message: (.*)\n stacktrace: ([\s\S]*?)(?=\n|\z)/gm;
const matches = [...failedTestsString.matchAll(regex)];
for (const match of matches || []) {
const failedTest: any = {
class: match[1].split(".")[0],
method: match[1].split(".")[1],
error: match[2].trim(),
};
if (match[3]) {
failedTest.stack = match[3];
}
failedTests.push(failedTest);
}
}
}

// Checks if the error string or regex is found in the log
Expand Down
5 changes: 3 additions & 2 deletions src/common/utils/deployUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import { callSfdxGitDelta } from './gitUtils.js';
import { createBlankSfdxProject, isSfdxProject } from './projectUtils.js';
import { prompts } from './prompts.js';
import { arrangeFilesBefore, restoreArrangedFiles } from './workaroundUtils.js';
import { isPackageXmlEmpty, parseXmlFile, removePackageXmlFilesContent, writeXmlFile } from './xmlUtils.js';
import { countPackageXmlItems, isPackageXmlEmpty, parseXmlFile, removePackageXmlFilesContent, writeXmlFile } from './xmlUtils.js';
import { ResetMode } from 'simple-git';
import { isProductionOrg } from './orgUtils.js';
import { soqlQuery } from './apiUtils.js';
Expand Down Expand Up @@ -221,11 +221,12 @@ export async function smartDeploy(
}
// Deployment of type package.xml file
if (deployment.packageXmlFile) {
const nbDeployedItems = await countPackageXmlItems(deployment.packageXmlFile);
uxLog(
commandThis,
c.cyan(
`${check ? 'Simulating deployment of' : 'Deploying'} ${c.bold(deployment.label)} package: ${deployment.packageXmlFile
} ...`
} (${nbDeployedItems} items)...`
)
);
// Try QuickDeploy
Expand Down
10 changes: 8 additions & 2 deletions src/common/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -371,8 +371,14 @@ export async function checkGitClean(options: any) {
})
.join('\n');
if (options.allowStash) {
await execCommand('git add --all', this, { output: true, fail: true });
await execCommand('git stash', this, { output: true, fail: true });
try {
await execCommand('git add --all', this, { output: true, fail: true });
await execCommand('git stash', this, { output: true, fail: true });
} catch (e) {
uxLog(this, c.yellow(c.bold("You might need to run the following command in Powershell launched as Administrator")));
uxLog(this, c.yellow(c.bold("git config --system core.longpaths true")));
throw e;
}
} else {
throw new SfError(
`[sfdx-hardis] Branch ${c.bold(gitStatus.current)} is not clean. You must ${c.bold(
Expand Down
13 changes: 11 additions & 2 deletions src/common/utils/xmlUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,15 @@ export async function parsePackageXmlFile(packageXmlFile: string) {
return targetOrgContent;
}

export async function countPackageXmlItems(packageXmlFile: string): Promise<number> {
const packageXmlParsed = await parsePackageXmlFile(packageXmlFile);
let counter = 0;
for (const type of Object.keys(packageXmlParsed)) {
counter += packageXmlParsed[type].length || 0;
}
return counter;
}

export async function writePackageXmlFile(packageXmlFile: string, packageXmlObject: any) {
let packageXmlContent: any = { Package: { types: [], version: [CONSTANTS.API_VERSION] } };
if (fs.existsSync(packageXmlFile)) {
Expand Down Expand Up @@ -334,8 +343,8 @@ export async function applyReplacementDefinition(
return replacementDefinition.type === 'code'
? '// ' + line + ' // Commented by sfdx-hardis purge-references'
: replacementDefinition.type === 'xml'
? '<!-- ' + line + ' Commented by sfdx-hardis purge-references --> '
: line;
? '<!-- ' + line + ' Commented by sfdx-hardis purge-references --> '
: line;
}
return line;
});
Expand Down

0 comments on commit dbdfc38

Please sign in to comment.