Compare commits
9 Commits
0.0.0-alpha
...
0.0.7
| Author | SHA1 | Date | |
|---|---|---|---|
| 213221e7d5 | |||
| f2cb5c30be | |||
| 4ec42cde84 | |||
| 86e4759531 | |||
| e3806f3fb4 | |||
| 591ff49340 | |||
| b1872be922 | |||
| aff5834508 | |||
| 2eccfafe45 |
@@ -21,7 +21,7 @@ jobs:
|
|||||||
run: dotnet restore
|
run: dotnet restore
|
||||||
- name: Extract functionInputSchema
|
- name: Extract functionInputSchema
|
||||||
id: extract_schema
|
id: extract_schema
|
||||||
working-directory: "SpeckleRegressionTester"
|
working-directory: "SpeckleAutomateDotnetExample"
|
||||||
run: |
|
run: |
|
||||||
dotnet build
|
dotnet build
|
||||||
dotnet run generate-schema ${HOME}/functionSchema.json
|
dotnet run generate-schema ${HOME}/functionSchema.json
|
||||||
@@ -29,7 +29,7 @@ jobs:
|
|||||||
- name: Speckle Automate Function - Build and Publish
|
- name: Speckle Automate Function - Build and Publish
|
||||||
uses: specklesystems/speckle-automate-github-composite-action@0.7.2
|
uses: specklesystems/speckle-automate-github-composite-action@0.7.2
|
||||||
with:
|
with:
|
||||||
speckle_function_command: "dotnet SpeckleRegressionTester.dll"
|
speckle_function_command: "dotnet SpeckleAutomateDotnetExample.dll"
|
||||||
speckle_automate_url: ${{ env.SPECKLE_AUTOMATE_URL }}
|
speckle_automate_url: ${{ env.SPECKLE_AUTOMATE_URL }}
|
||||||
speckle_token: ${{ secrets.SPECKLE_FUNCTION_TOKEN }}
|
speckle_token: ${{ secrets.SPECKLE_FUNCTION_TOKEN }}
|
||||||
speckle_function_id: ${{ secrets.SPECKLE_FUNCTION_ID }}
|
speckle_function_id: ${{ secrets.SPECKLE_FUNCTION_ID }}
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
FROM mcr.microsoft.com/dotnet/sdk:7.0 as build-env
|
FROM mcr.microsoft.com/dotnet/sdk:7.0 as build-env
|
||||||
|
|
||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
COPY SpeckleRegressionTester/ .
|
COPY SpeckleAutomateDotnetExample/ .
|
||||||
RUN dotnet restore --use-current-runtime
|
RUN dotnet restore --use-current-runtime
|
||||||
RUN dotnet publish --use-current-runtime --self-contained false --no-restore -o /publish
|
RUN dotnet publish --use-current-runtime --self-contained false --no-restore -o /publish
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
|||||||
# Visual Studio Version 17
|
# Visual Studio Version 17
|
||||||
VisualStudioVersion = 17.5.002.0
|
VisualStudioVersion = 17.5.002.0
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SpeckleRegressionTester", "SpeckleAutomateDotnetExample\SpeckleRegressionTester.csproj", "{E1DE5809-1111-4817-9B7D-7ADCA087FA1C}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SpeckleAutomateDotnetExample", "SpeckleAutomateDotnetExample\SpeckleAutomateDotnetExample.csproj", "{E1DE5809-1111-4817-9B7D-7ADCA087FA1C}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
@@ -2,6 +2,7 @@ using Objects;
|
|||||||
using Speckle.Automate.Sdk;
|
using Speckle.Automate.Sdk;
|
||||||
using Speckle.Automate.Sdk.Schema;
|
using Speckle.Automate.Sdk.Schema;
|
||||||
using Speckle.Core.Api;
|
using Speckle.Core.Api;
|
||||||
|
using Speckle.Core.Credentials;
|
||||||
using Speckle.Core.Models;
|
using Speckle.Core.Models;
|
||||||
using Speckle.Core.Models.Extensions;
|
using Speckle.Core.Models.Extensions;
|
||||||
using Speckle.Core.Transports;
|
using Speckle.Core.Transports;
|
||||||
@@ -37,6 +38,8 @@ static class AutomateFunction
|
|||||||
throw new Exception("Release branch has no commits");
|
throw new Exception("Release branch has no commits");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var tolerance = functionInputs.Tolerance;
|
||||||
|
|
||||||
Console.WriteLine($"Comparing {testBranchName} against {releaseBranchName}");
|
Console.WriteLine($"Comparing {testBranchName} against {releaseBranchName}");
|
||||||
|
|
||||||
// get the test and release commits
|
// get the test and release commits
|
||||||
@@ -44,19 +47,25 @@ static class AutomateFunction
|
|||||||
Base? testingCommitObject = await automationContext.ReceiveVersion();
|
Base? testingCommitObject = await automationContext.ReceiveVersion();
|
||||||
Console.WriteLine("Received test version: " + testingCommitObject);
|
Console.WriteLine("Received test version: " + testingCommitObject);
|
||||||
Console.WriteLine("Receiving release version");
|
Console.WriteLine("Receiving release version");
|
||||||
using ServerTransport transport =
|
ServerTransport serverTransport = new ServerTransport(
|
||||||
new(
|
automationContext.SpeckleClient.Account,
|
||||||
automationContext.SpeckleClient.Account,
|
automationContext.AutomationRunData.ProjectId
|
||||||
automationContext.AutomationRunData.ProjectId
|
);
|
||||||
);
|
|
||||||
Base? releaseCommitObject = await Operations
|
Base? releaseCommitObject = await Operations
|
||||||
.Receive(releaseCommit.referencedObject, transport)
|
.Receive(
|
||||||
|
(
|
||||||
|
await automationContext.SpeckleClient
|
||||||
|
.CommitGet(automationContext.AutomationRunData.ProjectId, releaseCommit.id)
|
||||||
|
.ConfigureAwait(continueOnCapturedContext: false)
|
||||||
|
).referencedObject,
|
||||||
|
serverTransport,
|
||||||
|
new MemoryTransport()
|
||||||
|
)
|
||||||
.ConfigureAwait(continueOnCapturedContext: false);
|
.ConfigureAwait(continueOnCapturedContext: false);
|
||||||
if (releaseCommitObject == null)
|
if (releaseCommitObject == null)
|
||||||
{
|
{
|
||||||
throw new Exception("Commit root object was null");
|
throw new Exception("Commit root object was null");
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine("Received release version: " + releaseCommitObject);
|
Console.WriteLine("Received release version: " + releaseCommitObject);
|
||||||
|
|
||||||
// flatten both commits
|
// flatten both commits
|
||||||
@@ -65,7 +74,10 @@ static class AutomateFunction
|
|||||||
var releaseCommitObjectsDict = new Dictionary<string, Base>();
|
var releaseCommitObjectsDict = new Dictionary<string, Base>();
|
||||||
foreach (var releaseObject in releaseCommitObjects)
|
foreach (var releaseObject in releaseCommitObjects)
|
||||||
{
|
{
|
||||||
if (!releaseCommitObjectsDict.ContainsKey(releaseObject.applicationId))
|
if (
|
||||||
|
releaseObject.applicationId != null
|
||||||
|
&& !releaseCommitObjectsDict.ContainsKey(releaseObject.applicationId)
|
||||||
|
)
|
||||||
{
|
{
|
||||||
releaseCommitObjectsDict.Add(releaseObject.applicationId, releaseObject);
|
releaseCommitObjectsDict.Add(releaseObject.applicationId, releaseObject);
|
||||||
}
|
}
|
||||||
@@ -77,12 +89,15 @@ static class AutomateFunction
|
|||||||
Console.WriteLine($"Found {testCommitObjects.Count()} objects in release version");
|
Console.WriteLine($"Found {testCommitObjects.Count()} objects in release version");
|
||||||
|
|
||||||
// compare objects
|
// compare objects
|
||||||
int addedCount = 0;
|
|
||||||
int modifiedCount = 0;
|
|
||||||
int unchangedCount = 0;
|
int unchangedCount = 0;
|
||||||
|
var addedList = new List<Tuple<string, string>>();
|
||||||
|
var modifiedList = new List<Tuple<string, string, string>>();
|
||||||
foreach (Base testObject in testCommitObjects)
|
foreach (Base testObject in testCommitObjects)
|
||||||
{
|
{
|
||||||
if (releaseCommitObjectsDict.ContainsKey(testObject.applicationId))
|
if (
|
||||||
|
testObject.applicationId != null
|
||||||
|
&& releaseCommitObjectsDict.ContainsKey(testObject.applicationId)
|
||||||
|
)
|
||||||
{
|
{
|
||||||
Base releaseObject = releaseCommitObjectsDict[testObject.applicationId];
|
Base releaseObject = releaseCommitObjectsDict[testObject.applicationId];
|
||||||
|
|
||||||
@@ -94,30 +109,28 @@ static class AutomateFunction
|
|||||||
// if ids are different, find property differences
|
// if ids are different, find property differences
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
modifiedCount++;
|
|
||||||
var diffDictionary = new Dictionary<string, string>();
|
var diffDictionary = new Dictionary<string, string>();
|
||||||
Dictionary<string, object> releaseObjectPropDict = releaseObject.GetMembers();
|
Dictionary<string, object?> releaseObjectPropDict =
|
||||||
Dictionary<string, object> testObjectPropDict = testObject.GetMembers();
|
releaseObject.GetMembers();
|
||||||
|
Dictionary<string, object?> testObjectPropDict = testObject.GetMembers();
|
||||||
foreach (var entry in testObjectPropDict)
|
foreach (var entry in testObjectPropDict)
|
||||||
{
|
{
|
||||||
if (releaseObjectPropDict.ContainsKey(entry.Key))
|
if (releaseObjectPropDict.ContainsKey(entry.Key))
|
||||||
{
|
{
|
||||||
bool changed = false;
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
changed = entry.Value != releaseObjectPropDict[entry.Key];
|
bool changed = !Equals(entry.Value, releaseObjectPropDict[entry.Key]);
|
||||||
}
|
if (changed)
|
||||||
catch { }
|
|
||||||
if (changed)
|
|
||||||
{
|
|
||||||
string diff =
|
|
||||||
$"Property ({entry.Key}) changed from ({releaseObjectPropDict[entry.Key]}) to ({entry.Value})";
|
|
||||||
if (!diffDictionary.ContainsKey(entry.Key))
|
|
||||||
{
|
{
|
||||||
diffDictionary.Add(entry.Key, diff);
|
string diff =
|
||||||
|
$"Property ({entry.Key}) changed from ({releaseObjectPropDict[entry.Key]}) to ({entry.Value})";
|
||||||
|
if (!diffDictionary.ContainsKey(entry.Key))
|
||||||
|
{
|
||||||
|
diffDictionary.Add(entry.Key, diff);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch { }
|
||||||
releaseObjectPropDict.Remove(entry.Key);
|
releaseObjectPropDict.Remove(entry.Key);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -144,14 +157,17 @@ static class AutomateFunction
|
|||||||
var sb = new System.Text.StringBuilder();
|
var sb = new System.Text.StringBuilder();
|
||||||
foreach (var entry in diffDictionary)
|
foreach (var entry in diffDictionary)
|
||||||
{
|
{
|
||||||
sb.AppendLine($"{entry.Key}: {entry.Value}");
|
sb.AppendLine($"{entry.Key}: {entry.Value}. ");
|
||||||
}
|
}
|
||||||
|
|
||||||
automationContext.AttachWarningToObjects(
|
modifiedList.Add(
|
||||||
MODIFIED,
|
new Tuple<string, string, string>(
|
||||||
new List<string>() { testObject.id },
|
testObject.id,
|
||||||
sb.ToString()
|
testObject.speckle_type,
|
||||||
|
sb.ToString()
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
//automationContext.AttachWarningToObjects( MODIFIED, new List<string>() { testObject.id }, sb.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,35 +175,88 @@ static class AutomateFunction
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
addedCount++;
|
//automationContext.AttachInfoToObjects(ADDED, new List<string>() { testObject.id });
|
||||||
automationContext.AttachInfoToObjects(
|
addedList.Add(
|
||||||
ADDED,
|
new Tuple<string, string>(testObject.id, testObject.speckle_type)
|
||||||
new List<string>() { testObject.id }
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if there are any remaining release commit objects, this indicates missing objects in the test run.
|
// if there are any remaining release commit objects, this indicates missing objects in the test run.
|
||||||
// mark run as failed and list missing object details.
|
var deletedList = new List<Tuple<string, string>>();
|
||||||
if (releaseCommitObjectsDict.Keys.Count > 0)
|
foreach (var entry in releaseCommitObjectsDict)
|
||||||
|
{
|
||||||
|
deletedList.Add(new Tuple<string, string>(entry.Key, entry.Value.speckle_type));
|
||||||
|
}
|
||||||
|
|
||||||
|
// mark run failed if there are any added, modified, or deleted objects and report
|
||||||
|
if (addedList.Count + deletedList.Count + modifiedList.Count > 0)
|
||||||
{
|
{
|
||||||
automationContext.MarkRunFailed(
|
automationContext.MarkRunFailed(
|
||||||
$"Missing {releaseCommitObjectsDict.Keys.Count} objects compared to the release commit."
|
$"Run failed due to {addedList.Count} ADDED, {modifiedList.Count} MODIFIED, and {deletedList.Count} DELETED objects compared to the release commit."
|
||||||
);
|
);
|
||||||
|
|
||||||
foreach (var missingObject in releaseCommitObjectsDict)
|
addedList.ForEach(
|
||||||
{
|
o => Console.WriteLine($"ADDED object: id( {o.Item1} ), type( {o.Item2} )")
|
||||||
Console.WriteLine(
|
);
|
||||||
$"Missing object info: id( {missingObject.Value.id} ), applicationId( {missingObject.Key} ), type( {missingObject.Value.speckle_type} )"
|
deletedList.ForEach(
|
||||||
);
|
o => Console.WriteLine($"DELETED object: id( {o.Item1} ), type( {o.Item2} )")
|
||||||
}
|
);
|
||||||
|
modifiedList.ForEach(
|
||||||
|
o =>
|
||||||
|
Console.WriteLine(
|
||||||
|
$"MODIFIED object: id( {o.Item1} ), type( {o.Item2} ), changed props:( {o.Item3} )"
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
// mark run as succeeded, noting any changed objects and added objects
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
automationContext.MarkRunSuccess(
|
automationContext.MarkRunSuccess(
|
||||||
$"Run passed with {addedCount} new objects, {modifiedCount} objects, and {unchangedCount} unchanged objects."
|
$"Run passed with {unchangedCount} unchanged objects."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool Equals<T>(T a, T b)
|
||||||
|
{
|
||||||
|
switch (a)
|
||||||
|
{
|
||||||
|
case Base o:
|
||||||
|
return b is Base bBase ? o.id == bBase.id : false;
|
||||||
|
case List<object> aList:
|
||||||
|
if (b is List<object> bList && aList.Count == bList.Count)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < aList.Count; i++)
|
||||||
|
{
|
||||||
|
if (!Equals(aList[i], bList[i]))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
case Dictionary<string, object> aDictionary:
|
||||||
|
if (
|
||||||
|
b is Dictionary<string, object> bDictionary
|
||||||
|
&& aDictionary.Count == bDictionary.Count
|
||||||
|
)
|
||||||
|
{
|
||||||
|
foreach (var entry in aDictionary)
|
||||||
|
{
|
||||||
|
if (
|
||||||
|
!bDictionary.ContainsKey(entry.Key)
|
||||||
|
|| !Equals(entry.Value, bDictionary[entry.Key])
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
default:
|
||||||
|
return EqualityComparer<T>.Default.Equals(a, b);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ using System.ComponentModel.DataAnnotations;
|
|||||||
/// are valid and match the required schema.
|
/// are valid and match the required schema.
|
||||||
struct FunctionInputs
|
struct FunctionInputs
|
||||||
{
|
{
|
||||||
//[Required]
|
[Required]
|
||||||
//public double Tolerance;
|
public double Tolerance;
|
||||||
|
|
||||||
//public string Exclusions;
|
//public string Exclusions;
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -8,7 +8,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Speckle.Automate.Sdk" Version="2.17.0-automate3" />
|
<PackageReference Include="Speckle.Automate.Sdk" Version="2.18.0-fileInput" />
|
||||||
<PackageReference Include="Speckle.Objects" Version="2.17.0-automate3" />
|
<PackageReference Include="Speckle.Objects" Version="2.18.0-fileInput" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
Reference in New Issue
Block a user