Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fdc0842b03 | |||
| 23d5dd44bc |
@@ -2,20 +2,15 @@ name: .NET Build and Publish
|
||||
|
||||
on:
|
||||
push:
|
||||
tags: ["3.*.*"]
|
||||
tags: ["3.*"]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
environment:
|
||||
name: 'nuget.org'
|
||||
permissions:
|
||||
id-token: write # enable GitHub OIDC token issuance for this job
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v5
|
||||
|
||||
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v5
|
||||
with:
|
||||
@@ -25,7 +20,7 @@ jobs:
|
||||
with:
|
||||
path: ~/.nuget/packages
|
||||
key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }}
|
||||
|
||||
|
||||
- id: set-version
|
||||
name: Set version to output
|
||||
run: |
|
||||
@@ -42,24 +37,18 @@ jobs:
|
||||
|
||||
echo $SEMVER
|
||||
echo $FILE_VERSION
|
||||
|
||||
|
||||
- name: 🔫 Build and Pack
|
||||
run: ./build.sh pack
|
||||
env:
|
||||
SEMVER: ${{ steps.set-version.outputs.SEMVER }}
|
||||
FILE_VERSION: ${{ steps.set-version.outputs.FILE_VERSION }}
|
||||
|
||||
|
||||
- name: Upload coverage reports to Codecov with GitHub Action
|
||||
uses: codecov/codecov-action@v5
|
||||
with:
|
||||
files: tests/**/coverage.xml
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
||||
- name: NuGet login (OIDC → temp API key)
|
||||
uses: NuGet/login@v1
|
||||
id: login
|
||||
with:
|
||||
user: ${{ secrets.NUGET_USER }}
|
||||
|
||||
- name: Push to nuget.org
|
||||
run: dotnet nuget push output/*.nupkg --source "https://api.nuget.org/v3/index.json" --api-key ${{steps.login.outputs.NUGET_API_KEY}}
|
||||
run: dotnet nuget push output/*.nupkg --source "https://api.nuget.org/v3/index.json" --api-key ${{secrets.CONNECTORS_NUGET_TOKEN }} --skip-duplicate
|
||||
|
||||
@@ -35,6 +35,6 @@ public class RenderMaterial : Base
|
||||
public Color emissiveColor
|
||||
{
|
||||
get => Color.FromArgb(emissive);
|
||||
set => emissive = value.ToArgb();
|
||||
set => diffuse = value.ToArgb();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ using Microsoft.Extensions.Logging;
|
||||
using Speckle.Sdk.Logging;
|
||||
using Speckle.Sdk.Models;
|
||||
using Speckle.Sdk.Serialisation;
|
||||
using Speckle.Sdk.Serialisation.V2.Receive;
|
||||
using Speckle.Sdk.Transports;
|
||||
|
||||
namespace Speckle.Sdk.Api;
|
||||
@@ -23,8 +22,7 @@ public partial class Operations
|
||||
string objectId,
|
||||
string? authorizationToken,
|
||||
IProgress<ProgressArgs>? onProgressAction,
|
||||
CancellationToken cancellationToken,
|
||||
DeserializeProcessOptions? options = null
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
using var receiveActivity = activityFactory.Start("Operations.Receive");
|
||||
@@ -38,8 +36,7 @@ public partial class Operations
|
||||
streamId,
|
||||
authorizationToken,
|
||||
onProgressAction,
|
||||
cancellationToken,
|
||||
options
|
||||
cancellationToken
|
||||
);
|
||||
try
|
||||
{
|
||||
@@ -47,11 +44,6 @@ public partial class Operations
|
||||
receiveActivity?.SetStatus(SdkActivityStatusCode.Ok);
|
||||
return result;
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
//this is handled by the caller
|
||||
throw;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
receiveActivity?.SetStatus(SdkActivityStatusCode.Error);
|
||||
|
||||
@@ -25,8 +25,7 @@ public partial class Operations
|
||||
string? authorizationToken,
|
||||
Base value,
|
||||
IProgress<ProgressArgs>? onProgressAction,
|
||||
CancellationToken cancellationToken,
|
||||
SerializeProcessOptions? options = null
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
using var receiveActivity = activityFactory.Start("Operations.Send");
|
||||
@@ -39,8 +38,7 @@ public partial class Operations
|
||||
streamId,
|
||||
authorizationToken,
|
||||
onProgressAction,
|
||||
cancellationToken,
|
||||
options
|
||||
cancellationToken
|
||||
);
|
||||
try
|
||||
{
|
||||
|
||||
@@ -9,8 +9,6 @@ public static class SpecklePathProvider
|
||||
{
|
||||
private const string APPLICATION_NAME = "Speckle";
|
||||
|
||||
private const string LOG_FOLDER_NAME = "Logs";
|
||||
|
||||
private const string BLOB_FOLDER_NAME = "Blobs";
|
||||
|
||||
private const string ACCOUNTS_FOLDER_NAME = "Accounts";
|
||||
@@ -45,7 +43,7 @@ public static class SpecklePathProvider
|
||||
/// <see cref="Environment.SpecialFolder.ApplicationData"/> path usually maps to
|
||||
/// <ul>
|
||||
/// <li>win: <c>%appdata%/</c></li>
|
||||
/// <li>MacOS: <c>~/Library/Application Support</c></li>
|
||||
/// <li>MacOS: <c>~/.config/</c></li>
|
||||
/// <li>Linux: <c>~/.config/</c></li>
|
||||
/// </ul>
|
||||
/// </remarks>
|
||||
@@ -59,18 +57,29 @@ public static class SpecklePathProvider
|
||||
return pathOverride;
|
||||
}
|
||||
|
||||
// on desktop linux and macos we use the appdata.
|
||||
// but we might not have write access to the disk
|
||||
// so the catch falls back to the user profile
|
||||
try
|
||||
{
|
||||
return Environment.GetFolderPath(
|
||||
Environment.SpecialFolder.ApplicationData,
|
||||
// It's not a given that the folder is already there on all OS-es, so we'll create it
|
||||
// if the folder doesn't exist, we get back an empty string on OSX,
|
||||
// which in turn, breaks other stuff down the line.
|
||||
// passing in the Create option ensures that this directory exists,
|
||||
// which is not a given on all OS-es.
|
||||
Environment.SpecialFolderOption.Create
|
||||
);
|
||||
}
|
||||
catch (PlatformNotSupportedException)
|
||||
catch (SystemException ex) when (ex is PlatformNotSupportedException or ArgumentException)
|
||||
{
|
||||
// We might not have write access to the disk to create the folder,
|
||||
// so we'll fall back to the user profile
|
||||
//Adding this log just so we confidently know which Exception type to catch here.
|
||||
// TODO: Must re-add log call when (and if) this get's made as a service
|
||||
//SpeckleLog.Logger.Warning(ex, "Falling back to user profile path");
|
||||
|
||||
// on server linux, there might not be a user setup, things can run under root
|
||||
// in that case, the appdata variable is most probably not set up
|
||||
// we fall back to the value of the home folder
|
||||
return Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
|
||||
}
|
||||
}
|
||||
@@ -87,7 +96,4 @@ public static class SpecklePathProvider
|
||||
Directory.CreateDirectory(path);
|
||||
return path;
|
||||
}
|
||||
|
||||
public static string LogFolderPath(string applicationAndVersion) =>
|
||||
EnsureFolderExists(UserSpeckleFolderPath, LOG_FOLDER_NAME, applicationAndVersion);
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ public class MemoryServerObjectManager(ConcurrentDictionary<string, string> obje
|
||||
{
|
||||
public virtual async IAsyncEnumerable<(string, string)> DownloadObjects(
|
||||
IReadOnlyCollection<string> objectIds,
|
||||
string? attributeMask,
|
||||
IProgress<ProgressArgs>? progress,
|
||||
[EnumeratorCancellation] CancellationToken cancellationToken
|
||||
)
|
||||
|
||||
@@ -14,8 +14,7 @@ public record DeserializeProcessOptions(
|
||||
bool ThrowOnMissingReferences = true,
|
||||
bool SkipInvalidConverts = false,
|
||||
int? MaxParallelism = null,
|
||||
bool SkipServer = false,
|
||||
string? AttributeMask = null
|
||||
bool SkipServer = false
|
||||
);
|
||||
|
||||
public partial interface IDeserializeProcess : IAsyncDisposable;
|
||||
@@ -45,7 +44,6 @@ public sealed class DeserializeProcess(
|
||||
new ObjectLoader(
|
||||
sqLiteJsonCacheManager,
|
||||
serverObjectManager,
|
||||
options?.AttributeMask,
|
||||
progress,
|
||||
loggerFactory.CreateLogger<ObjectLoader>(),
|
||||
cancellationToken
|
||||
|
||||
@@ -16,7 +16,6 @@ public partial interface IObjectLoader : IDisposable;
|
||||
public sealed class ObjectLoader(
|
||||
ISqLiteJsonCacheManager sqLiteJsonCacheManager,
|
||||
IServerObjectManager serverObjectManager,
|
||||
string? attributeMask,
|
||||
IProgress<ProgressArgs>? progress,
|
||||
ILogger<ObjectLoader> logger,
|
||||
CancellationToken cancellationToken
|
||||
@@ -112,7 +111,6 @@ public sealed class ObjectLoader(
|
||||
await foreach (
|
||||
var (id, json) in serverObjectManager.DownloadObjects(
|
||||
ids.Select(x => x.NotNull()).ToList(),
|
||||
attributeMask,
|
||||
progress,
|
||||
cancellationToken
|
||||
)
|
||||
|
||||
@@ -51,7 +51,6 @@ public class ServerObjectManager : IServerObjectManager
|
||||
|
||||
public async IAsyncEnumerable<(string, string)> DownloadObjects(
|
||||
IReadOnlyCollection<string> objectIds,
|
||||
string? attributeMask,
|
||||
IProgress<ProgressArgs>? progress,
|
||||
[EnumeratorCancellation] CancellationToken cancellationToken
|
||||
)
|
||||
@@ -60,14 +59,10 @@ public class ServerObjectManager : IServerObjectManager
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
using var childrenHttpMessage = new HttpRequestMessage();
|
||||
childrenHttpMessage.RequestUri = new Uri($"/api/v2/projects/{_streamId}/object-stream/", UriKind.Relative);
|
||||
childrenHttpMessage.RequestUri = new Uri($"/api/getobjects/{_streamId}", UriKind.Relative);
|
||||
childrenHttpMessage.Method = HttpMethod.Post;
|
||||
|
||||
Dictionary<string, object> postParameters = new() { { "objectIds", objectIds } };
|
||||
if (!string.IsNullOrWhiteSpace(attributeMask))
|
||||
{
|
||||
postParameters.Add("attributeMask", attributeMask.NotNull());
|
||||
}
|
||||
Dictionary<string, string> postParameters = new() { { "objects", JsonConvert.SerializeObject(objectIds) } };
|
||||
string serializedPayload = JsonConvert.SerializeObject(postParameters);
|
||||
childrenHttpMessage.Content = new StringContent(serializedPayload, Encoding.UTF8, "application/json");
|
||||
childrenHttpMessage.Headers.Add("Accept", "text/plain");
|
||||
|
||||
@@ -338,7 +338,6 @@ public class DummyServerObjectManager : IServerObjectManager
|
||||
{
|
||||
public IAsyncEnumerable<(string, string)> DownloadObjects(
|
||||
IReadOnlyCollection<string> objectIds,
|
||||
string? attributeMask,
|
||||
IProgress<ProgressArgs>? progress,
|
||||
CancellationToken cancellationToken
|
||||
) => throw new NotImplementedException();
|
||||
|
||||
@@ -112,7 +112,6 @@ public class ExceptionTests
|
||||
new DummySqLiteReceiveManager(new Dictionary<string, string>()),
|
||||
new ExceptionServerObjectManager(),
|
||||
null,
|
||||
null,
|
||||
new NullLogger<ObjectLoader>(),
|
||||
default
|
||||
);
|
||||
|
||||
@@ -8,7 +8,6 @@ public class ExceptionServerObjectManager : IServerObjectManager
|
||||
{
|
||||
public IAsyncEnumerable<(string, string)> DownloadObjects(
|
||||
IReadOnlyCollection<string> objectIds,
|
||||
string? attributeMask,
|
||||
IProgress<ProgressArgs>? progress,
|
||||
CancellationToken cancellationToken
|
||||
) => throw new NotImplementedException();
|
||||
|
||||
@@ -150,7 +150,7 @@ public class SerializationTests
|
||||
id.Should().Be(newId.Value);
|
||||
}
|
||||
|
||||
[Theory(Skip = "Takes too long")]
|
||||
[Theory]
|
||||
[InlineData("RevitObject.json.gz", "3416d3fe01c9196115514c4a2f41617b", 7818)]
|
||||
public async Task Roundtrip_Test_Old(string fileName, string _, int count)
|
||||
{
|
||||
@@ -186,6 +186,8 @@ public class SerializationTests
|
||||
|
||||
[Theory]
|
||||
[InlineData(1)]
|
||||
[InlineData(2)]
|
||||
[InlineData(3)]
|
||||
[InlineData(4)]
|
||||
public async Task Roundtrip_Test_New(int concurrency)
|
||||
{
|
||||
@@ -202,7 +204,6 @@ public class SerializationTests
|
||||
new DummySqLiteReceiveManager(closures),
|
||||
new DummyReceiveServerObjectManager(closures),
|
||||
null,
|
||||
null,
|
||||
new NullLogger<ObjectLoader>(),
|
||||
default
|
||||
)
|
||||
|
||||
@@ -31,17 +31,14 @@ public class ServerObjectManagerTests : MoqTest
|
||||
var jObject = new JObject { { "id", id }, { "value", true } };
|
||||
var jObject2 = new JObject { { "id", id2 }, { "value", true } };
|
||||
var mockHttp = new MockHttpMessageHandler();
|
||||
Dictionary<string, object> postParameters = new()
|
||||
Dictionary<string, string> postParameters = new()
|
||||
{
|
||||
{
|
||||
"objectIds",
|
||||
new List<string> { id, id2 }
|
||||
},
|
||||
{ "objects", JsonConvert.SerializeObject(new List<string> { id, id2 }) },
|
||||
};
|
||||
|
||||
string serializedPayload = JsonConvert.SerializeObject(postParameters);
|
||||
mockHttp
|
||||
.When(HttpMethod.Post, $"http://localhost/api/v2/projects/{streamId}/object-stream/")
|
||||
.When(HttpMethod.Post, $"http://localhost/api/getobjects/{streamId}")
|
||||
.WithContent(serializedPayload)
|
||||
.Respond(
|
||||
"application/json",
|
||||
@@ -62,7 +59,7 @@ public class ServerObjectManagerTests : MoqTest
|
||||
token,
|
||||
new(timeout: TimeSpan.FromSeconds(timeout))
|
||||
);
|
||||
var results = serverObjectManager.DownloadObjects(new List<string> { id, id2 }, null, null, ct);
|
||||
var results = serverObjectManager.DownloadObjects(new List<string> { id, id2 }, null, ct);
|
||||
var objects = new JObject();
|
||||
await foreach (var (x, json) in results)
|
||||
{
|
||||
|
||||
@@ -10,7 +10,6 @@ public class DummyReceiveServerObjectManager(IReadOnlyDictionary<string, string>
|
||||
{
|
||||
public async IAsyncEnumerable<(string, string)> DownloadObjects(
|
||||
IReadOnlyCollection<string> objectIds,
|
||||
string? attributeMask,
|
||||
IProgress<ProgressArgs>? progress,
|
||||
[EnumeratorCancellation] CancellationToken cancellationToken
|
||||
)
|
||||
|
||||
@@ -9,7 +9,6 @@ public class DummySendServerObjectManager(ConcurrentDictionary<string, string> s
|
||||
{
|
||||
public IAsyncEnumerable<(string, string)> DownloadObjects(
|
||||
IReadOnlyCollection<string> objectIds,
|
||||
string? attributeMask,
|
||||
IProgress<ProgressArgs>? progress,
|
||||
CancellationToken cancellationToken
|
||||
) => throw new NotImplementedException();
|
||||
|
||||
Reference in New Issue
Block a user