-
Notifications
You must be signed in to change notification settings - Fork 60
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix- ALM Run set level save #4040
Conversation
WalkthroughThe pull request modifies the Changes
Possibly related PRs
Suggested reviewers
Poem
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🧹 Nitpick comments (3)
Ginger/GingerCoreNET/Run/RunSetActions/RunSetActionPublishToQCOperations.cs (3)
236-241
: Enhance XML documentation completenessWhile the documentation explains the method's purpose, consider adding:
- Parameter requirements/constraints
- Return value documentation (void)
- Possible exceptions that might be thrown
/// <summary> /// Updates the ALM ID in the Runset after exporting the RunSet to ALM when ALMTestSet Level is Runset /// </summary> -/// <param name="runsetConvertedbusinessFlow"></param> -/// <param name="reportInfo"></param> +/// <param name="runsetConvertedbusinessFlow">The business flow converted from runset. Must not be null when containing ExternalID/ExternalID2.</param> +/// <param name="reportInfo">Report information for the execution. Must not be null.</param> +/// <returns>void</returns> +/// <exception cref="Exception">Thrown when update operation fails</exception>
246-249
: Improve null parameter handlingConsider logging which parameter is null for better debugging.
-if (reportInfo == null || runsetConvertedbusinessFlow == null) +if (reportInfo == null) { + Reporter.ToLog(eLogLevel.WARN, "UpdateAlmIdtoRunset: reportInfo parameter is null"); return; } +if (runsetConvertedbusinessFlow == null) +{ + Reporter.ToLog(eLogLevel.WARN, "UpdateAlmIdtoRunset: runsetConvertedbusinessFlow parameter is null"); + return; +}
314-314
: Enhance error handling for repository save operationConsider adding specific error handling for the repository save operation.
-WorkSpace.Instance.SolutionRepository.SaveRepositoryItem(runSetExec.RunSetConfig); +try +{ + WorkSpace.Instance.SolutionRepository.SaveRepositoryItem(runSetExec.RunSetConfig); +} +catch (Exception saveEx) +{ + Reporter.ToLog(eLogLevel.ERROR, $"Failed to save RunSetConfig to repository. ExternalID: {runSetExec.RunSetConfig.ExternalID}", saveEx); + throw; +}
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
Ginger/GingerCoreNET/Run/RunSetActions/RunSetActionPublishToQCOperations.cs
(2 hunks)
if (runsetConvertedbusinessFlow != null && !string.IsNullOrEmpty(runsetConvertedbusinessFlow.ExternalID)) | ||
{ | ||
if (!string.IsNullOrEmpty(runSetExec.RunSetConfig.ExternalID)) | ||
{ | ||
if (!General.isVariableUsed(runSetExec.RunSetConfig.ExternalID)) | ||
{ | ||
runSetExec.RunSetConfig.ExternalID = businessFlow.ExternalID; | ||
runSetExec.RunSetConfig.ExternalID = runsetConvertedbusinessFlow.ExternalID; | ||
} | ||
} | ||
else | ||
{ | ||
runSetExec.RunSetConfig.ExternalID = businessFlow.ExternalID; | ||
runSetExec.RunSetConfig.ExternalID = runsetConvertedbusinessFlow.ExternalID; | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Simplify ExternalID update logic
The code contains:
- Redundant null check after parameter validation
- Nested conditions that can be flattened
-if (runsetConvertedbusinessFlow != null && !string.IsNullOrEmpty(runsetConvertedbusinessFlow.ExternalID))
+if (!string.IsNullOrEmpty(runsetConvertedbusinessFlow.ExternalID))
{
- if (!string.IsNullOrEmpty(runSetExec.RunSetConfig.ExternalID))
- {
- if (!General.isVariableUsed(runSetExec.RunSetConfig.ExternalID))
- {
- runSetExec.RunSetConfig.ExternalID = runsetConvertedbusinessFlow.ExternalID;
- }
- }
- else
+ if (string.IsNullOrEmpty(runSetExec.RunSetConfig.ExternalID) ||
+ !General.isVariableUsed(runSetExec.RunSetConfig.ExternalID))
{
runSetExec.RunSetConfig.ExternalID = runsetConvertedbusinessFlow.ExternalID;
}
}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
if (runsetConvertedbusinessFlow != null && !string.IsNullOrEmpty(runsetConvertedbusinessFlow.ExternalID)) | |
{ | |
if (!string.IsNullOrEmpty(runSetExec.RunSetConfig.ExternalID)) | |
{ | |
if (!General.isVariableUsed(runSetExec.RunSetConfig.ExternalID)) | |
{ | |
runSetExec.RunSetConfig.ExternalID = businessFlow.ExternalID; | |
runSetExec.RunSetConfig.ExternalID = runsetConvertedbusinessFlow.ExternalID; | |
} | |
} | |
else | |
{ | |
runSetExec.RunSetConfig.ExternalID = businessFlow.ExternalID; | |
runSetExec.RunSetConfig.ExternalID = runsetConvertedbusinessFlow.ExternalID; | |
} | |
} | |
if (!string.IsNullOrEmpty(runsetConvertedbusinessFlow.ExternalID)) | |
{ | |
if (string.IsNullOrEmpty(runSetExec.RunSetConfig.ExternalID) || | |
!General.isVariableUsed(runSetExec.RunSetConfig.ExternalID)) | |
{ | |
runSetExec.RunSetConfig.ExternalID = runsetConvertedbusinessFlow.ExternalID; | |
} | |
} |
if (runsetConvertedbusinessFlow != null && !string.IsNullOrEmpty(runsetConvertedbusinessFlow.ExternalID2)) | ||
{ | ||
if (!string.IsNullOrEmpty(runSetExec.RunSetConfig.ExternalID2)) | ||
{ | ||
if (!General.isVariableUsed(runSetExec.RunSetConfig.ExternalID2)) | ||
{ | ||
runSetExec.RunSetConfig.ExternalID2 = businessFlow.ExternalID2; | ||
runSetExec.RunSetConfig.ExternalID2 = runsetConvertedbusinessFlow.ExternalID2; | ||
} | ||
} | ||
else | ||
{ | ||
runSetExec.RunSetConfig.ExternalID2 = businessFlow.ExternalID2; | ||
runSetExec.RunSetConfig.ExternalID2 = runsetConvertedbusinessFlow.ExternalID2; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Extract duplicate logic into helper method
The ExternalID and ExternalID2 update logic is identical. Consider extracting this into a helper method.
+private void UpdateExternalId(string sourceId, ref string targetId)
+{
+ if (!string.IsNullOrEmpty(sourceId))
+ {
+ if (string.IsNullOrEmpty(targetId) || !General.isVariableUsed(targetId))
+ {
+ targetId = sourceId;
+ }
+ }
+}
private void UpdateAlmIdtoRunset(BusinessFlow runsetConvertedbusinessFlow, IReportInfo reportInfo)
{
// ... existing code ...
- if (runsetConvertedbusinessFlow != null && !string.IsNullOrEmpty(runsetConvertedbusinessFlow.ExternalID2))
- {
- if (!string.IsNullOrEmpty(runSetExec.RunSetConfig.ExternalID2))
- {
- if (!General.isVariableUsed(runSetExec.RunSetConfig.ExternalID2))
- {
- runSetExec.RunSetConfig.ExternalID2 = runsetConvertedbusinessFlow.ExternalID2;
- }
- }
- else
- {
- runSetExec.RunSetConfig.ExternalID2 = runsetConvertedbusinessFlow.ExternalID2;
- }
- }
+ UpdateExternalId(runsetConvertedbusinessFlow.ExternalID, ref runSetExec.RunSetConfig.ExternalID);
+ UpdateExternalId(runsetConvertedbusinessFlow.ExternalID2, ref runSetExec.RunSetConfig.ExternalID2);
Committable suggestion skipped: line range outside the PR's diff.
foreach (BusinessFlow bFlowToUpdate in Bflist.Where(x => BFGuidlist.Contains(x.Guid))) | ||
{ | ||
ActivitiesGroup activitiesGroup = businessFlow.ActivitiesGroups.FirstOrDefault(x => x.ParentGuid == bFlow.Guid); | ||
ActivitiesGroup activitiesGroup = runsetConvertedbusinessFlow.ActivitiesGroups.FirstOrDefault(x => x.ParentGuid == bFlowToUpdate.Guid); | ||
if (activitiesGroup != null) | ||
{ | ||
if (!string.IsNullOrEmpty(bFlow.ExternalID)) | ||
if (!string.IsNullOrEmpty(bFlowToUpdate.ExternalID)) | ||
{ | ||
if (!General.isVariableUsed(bFlow.ExternalID)) | ||
if (!General.isVariableUsed(bFlowToUpdate.ExternalID)) | ||
{ | ||
bFlow.ExternalID = !string.IsNullOrEmpty(activitiesGroup.ExternalID) ? activitiesGroup.ExternalID : bFlow.ExternalID; | ||
bFlowToUpdate.ExternalID = !string.IsNullOrEmpty(activitiesGroup.ExternalID) ? activitiesGroup.ExternalID : bFlowToUpdate.ExternalID; | ||
} | ||
} | ||
else | ||
{ | ||
bFlow.ExternalID = activitiesGroup.ExternalID; | ||
bFlowToUpdate.ExternalID = activitiesGroup.ExternalID; | ||
} | ||
|
||
if (!string.IsNullOrEmpty(bFlowToUpdate.ExternalID)) | ||
{ | ||
WorkSpace.Instance.SolutionRepository.SaveRepositoryItem(bFlowToUpdate); | ||
} | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Optimize LINQ query and simplify business flow updates
The current implementation has:
- Complex LINQ operations that could be optimized
- Nested conditions that can be simplified
- Potential performance impact with multiple repository queries
-foreach (BusinessFlow bFlowToUpdate in Bflist.Where(x => BFGuidlist.Contains(x.Guid)))
+var bFlowsToUpdate = Bflist
+ .Join(BFGuidlist,
+ bf => bf.Guid,
+ guid => guid,
+ (bf, guid) => bf)
+ .ToList();
+
+foreach (var bFlowToUpdate in bFlowsToUpdate)
{
ActivitiesGroup activitiesGroup = runsetConvertedbusinessFlow.ActivitiesGroups.FirstOrDefault(x => x.ParentGuid == bFlowToUpdate.Guid);
if (activitiesGroup != null)
{
- if (!string.IsNullOrEmpty(bFlowToUpdate.ExternalID))
- {
- if (!General.isVariableUsed(bFlowToUpdate.ExternalID))
- {
- bFlowToUpdate.ExternalID = !string.IsNullOrEmpty(activitiesGroup.ExternalID) ? activitiesGroup.ExternalID : bFlowToUpdate.ExternalID;
- }
- }
- else
+ if (!string.IsNullOrEmpty(activitiesGroup.ExternalID) &&
+ (string.IsNullOrEmpty(bFlowToUpdate.ExternalID) || !General.isVariableUsed(bFlowToUpdate.ExternalID)))
{
bFlowToUpdate.ExternalID = activitiesGroup.ExternalID;
+ WorkSpace.Instance.SolutionRepository.SaveRepositoryItem(bFlowToUpdate);
}
-
- if (!string.IsNullOrEmpty(bFlowToUpdate.ExternalID))
- {
- WorkSpace.Instance.SolutionRepository.SaveRepositoryItem(bFlowToUpdate);
- }
}
}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
foreach (BusinessFlow bFlowToUpdate in Bflist.Where(x => BFGuidlist.Contains(x.Guid))) | |
{ | |
ActivitiesGroup activitiesGroup = businessFlow.ActivitiesGroups.FirstOrDefault(x => x.ParentGuid == bFlow.Guid); | |
ActivitiesGroup activitiesGroup = runsetConvertedbusinessFlow.ActivitiesGroups.FirstOrDefault(x => x.ParentGuid == bFlowToUpdate.Guid); | |
if (activitiesGroup != null) | |
{ | |
if (!string.IsNullOrEmpty(bFlow.ExternalID)) | |
if (!string.IsNullOrEmpty(bFlowToUpdate.ExternalID)) | |
{ | |
if (!General.isVariableUsed(bFlow.ExternalID)) | |
if (!General.isVariableUsed(bFlowToUpdate.ExternalID)) | |
{ | |
bFlow.ExternalID = !string.IsNullOrEmpty(activitiesGroup.ExternalID) ? activitiesGroup.ExternalID : bFlow.ExternalID; | |
bFlowToUpdate.ExternalID = !string.IsNullOrEmpty(activitiesGroup.ExternalID) ? activitiesGroup.ExternalID : bFlowToUpdate.ExternalID; | |
} | |
} | |
else | |
{ | |
bFlow.ExternalID = activitiesGroup.ExternalID; | |
bFlowToUpdate.ExternalID = activitiesGroup.ExternalID; | |
} | |
if (!string.IsNullOrEmpty(bFlowToUpdate.ExternalID)) | |
{ | |
WorkSpace.Instance.SolutionRepository.SaveRepositoryItem(bFlowToUpdate); | |
} | |
} | |
} | |
} | |
var bFlowsToUpdate = Bflist | |
.Join(BFGuidlist, | |
bf => bf.Guid, | |
guid => guid, | |
(bf, guid) => bf) | |
.ToList(); | |
foreach (var bFlowToUpdate in bFlowsToUpdate) | |
{ | |
ActivitiesGroup activitiesGroup = runsetConvertedbusinessFlow.ActivitiesGroups.FirstOrDefault(x => x.ParentGuid == bFlowToUpdate.Guid); | |
if (activitiesGroup != null) | |
{ | |
if (!string.IsNullOrEmpty(activitiesGroup.ExternalID) && | |
(string.IsNullOrEmpty(bFlowToUpdate.ExternalID) || !General.isVariableUsed(bFlowToUpdate.ExternalID))) | |
{ | |
bFlowToUpdate.ExternalID = activitiesGroup.ExternalID; | |
WorkSpace.Instance.SolutionRepository.SaveRepositoryItem(bFlowToUpdate); | |
} | |
} | |
} | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (3)
Ginger/GingerCoreNET/Run/RunSetActions/RunSetActionPublishToQCOperations.cs (3)
250-263
: 🛠️ Refactor suggestionSimplify ExternalID update logic
The nested conditions can be flattened to improve readability.
265-278
: 🛠️ Refactor suggestionExtract duplicate ExternalID update logic
The ExternalID and ExternalID2 update logic is identical and should be extracted into a helper method.
290-313
: 🛠️ Refactor suggestionOptimize LINQ query and simplify business flow updates
The LINQ operations and nested conditions can be optimized for better performance and readability.
🧹 Nitpick comments (3)
Ginger/GingerCoreNET/Run/RunSetActions/RunSetActionPublishToQCOperations.cs (3)
236-241
: Enhance XML documentation completenessThe XML documentation should be expanded to include:
- Parameter descriptions using
<param>
tags- Return value using
<returns>
tag- Exception documentation using
<exception>
tags/// <summary> /// Updates the ALM ID in the Runset after exporting the RunSet to ALM when ALMTestSet Level is Runset /// </summary> -/// <param name="runsetConvertedbusinessFlow"></param> -/// <param name="reportInfo"></param> +/// <param name="runsetConvertedbusinessFlow">The business flow converted from the runset</param> +/// <param name="reportInfo">The report information containing execution details</param> +/// <returns>void</returns> +/// <exception cref="Exception">Thrown when ALM ID update fails</exception>
246-249
: Improve parameter validation with guard clausesConsider using guard clauses and adding specific logging for null parameters.
-if (reportInfo == null || runsetConvertedbusinessFlow == null) -{ - return; -} +if (reportInfo == null) +{ + Reporter.ToLog(eLogLevel.WARN, "UpdateAlmIdtoRunset: reportInfo parameter is null"); + return; +} +if (runsetConvertedbusinessFlow == null) +{ + Reporter.ToLog(eLogLevel.WARN, "UpdateAlmIdtoRunset: runsetConvertedbusinessFlow parameter is null"); + return; +}
314-314
: Add validation for RunSetConfig save operationThe save operation could fail silently. Consider adding validation and error handling.
-WorkSpace.Instance.SolutionRepository.SaveRepositoryItem(runSetExec.RunSetConfig); +bool saveSuccess = WorkSpace.Instance.SolutionRepository.SaveRepositoryItem(runSetExec.RunSetConfig); +if (!saveSuccess) +{ + Reporter.ToLog(eLogLevel.ERROR, "Failed to save RunSetConfig"); +}
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
Ginger/GingerCoreNET/Run/RunSetActions/RunSetActionPublishToQCOperations.cs
(2 hunks)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (2)
Ginger/GingerCoreNET/Run/RunSetActions/RunSetActionPublishToQCOperations.cs (2)
250-264
: 🛠️ Refactor suggestionSimplify ExternalID update logic
The nested conditions make the code harder to maintain and understand.
Please refer to the previous review comment for the suggested refactoring approach.
265-278
: 🛠️ Refactor suggestionExtract duplicate ExternalID update logic
The ExternalID and ExternalID2 update logic is identical, causing code duplication.
Please refer to the previous review comment for the suggested helper method approach.
🧹 Nitpick comments (4)
Ginger/GingerCoreNET/Run/RunSetActions/RunSetActionPublishToQCOperations.cs (4)
236-241
: Enhance XML documentationWhile the documentation provides a good overview, consider adding:
<returns>
tag to document void return type<exception>
tags to document potential exceptions- Parameter requirements (e.g., non-null constraints) in the param tags
/// <summary> /// Updates the ALM ID in the Runset after exporting the RunSet to ALM when ALMTestSet Level is Runset /// </summary> -/// <param name="runsetConvertedbusinessFlow"></param> -/// <param name="reportInfo"></param> +/// <param name="runsetConvertedbusinessFlow">The business flow converted from runset. Must not be null.</param> +/// <param name="reportInfo">The report information. Must not be null.</param> +/// <returns>void</returns> +/// <exception cref="Exception">Thrown when ALM ID update fails</exception>
246-249
: Add logging for parameter validation failuresConsider logging a warning when null parameters are detected to help with debugging.
if (reportInfo == null || runsetConvertedbusinessFlow == null) { + Reporter.ToLog(eLogLevel.WARN, $"UpdateAlmIdtoRunset skipped due to null parameters. reportInfo: {reportInfo == null}, runsetConvertedbusinessFlow: {runsetConvertedbusinessFlow == null}"); return; }
290-303
: Improve null checks and loggingGood addition of null checks and logging. However, consider using more descriptive log messages.
-Reporter.ToLog(eLogLevel.INFO, $"No ActivitiesGroup found for BusinessFlow with Guid: {bFlowToUpdate.Guid}"); +Reporter.ToLog(eLogLevel.INFO, $"No ActivitiesGroup found for BusinessFlow '{bFlowToUpdate.Name}' (Guid: {bFlowToUpdate.Guid})");
317-320
: Consider batching save operationsMultiple individual save operations could impact performance. Consider collecting all items to save and performing a batch operation if supported by the repository.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
Ginger/GingerCoreNET/Run/RunSetActions/RunSetActionPublishToQCOperations.cs
(2 hunks)
🔇 Additional comments (1)
Ginger/GingerCoreNET/Run/RunSetActions/RunSetActionPublishToQCOperations.cs (1)
Line range hint 236-320
: Verify ALM integration impact
Please verify that these changes don't break existing ALM integrations, especially:
- The handling of existing ALM IDs
- The behavior when ALM is unavailable
- The impact on different ALM types (QC, etc.)
✅ Verification successful
Based on the shell script results, I can now provide a final response:
ALM integration changes are safe
The code changes in RunSetActionPublishToQCOperations.cs
follow the established ALM integration patterns across the codebase:
- The ExternalID update logic matches the patterns used in other ALM integrations (JIRA, Zephyr)
- The code properly handles null/empty ID cases and variable usage checks
- The changes maintain backward compatibility with existing ALM types
The key evidence from the codebase:
- ALM integration tests exist across multiple test files
- ExternalID handling patterns are consistent across ALM implementations
- Proper null checks and variable validation are in place
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for ALM integration tests and usage patterns
echo "Searching for ALM integration tests..."
rg -l "ALMTestSetLevel" --type cs
echo "Checking ALM type handling..."
ast-grep --pattern 'PublishALMType.Equals($_, $_)'
echo "Checking ExternalID usage patterns..."
rg -A 5 "ExternalID.*=.*" --type cs
Length of output: 84849
Thank you for your contribution.
Before submitting this PR, please make sure:
Summary by CodeRabbit
New Features
Bug Fixes
Documentation