1 Commits

Author SHA1 Message Date
Gergő Jedlicska efd36971dc Update nuget versions 2024-01-31 13:05:36 +01:00
15 changed files with 29 additions and 207 deletions
@@ -3,19 +3,20 @@ on:
workflow_dispatch:
push:
tags:
- "*"
- '*'
jobs:
publish-automate-function-version: # make sure the action works on a clean machine without building
env:
FUNCTION_SCHEMA_FILE_NAME: functionSchema.json
SPECKLE_AUTOMATE_URL: https://automate.speckle.dev
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v4.1.1
- name: Setup .NET Core SDK
uses: actions/setup-dotnet@v5
uses: actions/setup-dotnet@v3.2.0
with:
dotnet-version: 8.x.x
dotnet-version: 7.x
- name: Restore dependencies
run: dotnet restore
- name: Extract functionInputSchema
@@ -26,10 +27,10 @@ jobs:
dotnet run generate-schema ${HOME}/functionSchema.json
cat ${HOME}/functionSchema.json
- name: Speckle Automate Function - Build and Publish
uses: specklesystems/speckle-automate-github-composite-action@0.9.0
uses: specklesystems/speckle-automate-github-composite-action@0.7.2
with:
speckle_function_command: "dotnet SpeckleAutomateDotnetExample.dll"
speckle_automate_url: ${{ env.SPECKLE_AUTOMATE_URL || vars.SPECKLE_AUTOMATE_URL || 'https://automate.speckle.dev' }}
speckle_automate_url: ${{ env.SPECKLE_AUTOMATE_URL }}
speckle_token: ${{ secrets.SPECKLE_FUNCTION_TOKEN }}
speckle_function_id: ${{ secrets.SPECKLE_FUNCTION_ID }}
speckle_function_input_schema_file_path: ${{ env.FUNCTION_SCHEMA_FILE_NAME }}
-19
View File
@@ -1,19 +0,0 @@
name: "Test Building"
on:
pull_request:
jobs:
build-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Setup .NET Core SDK
uses: actions/setup-dotnet@v5
with:
dotnet-version: 8.x.x
- name: Restore dependencies
run: dotnet restore
- name: Build
working-directory: "SpeckleAutomateDotnetExample"
run: |
dotnet build -warnaserror
-2
View File
@@ -576,5 +576,3 @@ FodyWeavers.xsd
# Additional files built by Visual Studio
# End of https://www.toptal.com/developers/gitignore/api/dotnetcore,linux,visualstudiocode,rider,visualstudio,windows,macos
appsettings.json
+2 -2
View File
@@ -1,10 +1,10 @@
FROM mcr.microsoft.com/dotnet/sdk:8.0 as build-env
FROM mcr.microsoft.com/dotnet/sdk:7.0 as build-env
WORKDIR /src
COPY SpeckleAutomateDotnetExample/ .
RUN dotnet restore --use-current-runtime
RUN dotnet publish --use-current-runtime --self-contained false --no-restore -o /publish
FROM mcr.microsoft.com/dotnet/runtime:8.0 as runtime
FROM mcr.microsoft.com/dotnet/runtime:7.0 as runtime
WORKDIR /publish
COPY --from=build-env /publish .
+3 -4
View File
@@ -33,7 +33,7 @@ This repository contains an example function that is compatible with Speckle Aut
## Getting started
This is essentially a template function, designed to serve as a starting point for creating your own function. The function targets dotnet 8.0 and uses the Speckle.Automate.SDK NuGet package.
This is essentially a template function, designed to serve as a starting point for creating your own function. The function targets dotnet 7.0 and uses the Speckle.Automate.SDK NuGet package, as well as the Objects Kit.
At its core every Speckle Automate function is a CLI application with a specific, standardized set of available commands and arguments ([see below](#anatomy-of-a-function)). Each automate function is then built into a Docker image and published onto Speckle Automate.
@@ -62,14 +62,13 @@ These arguments are automatically provided by the automate platform every time a
### Function Boilerplate (`Program.cs`)
This Program.cs file is the entry point to your CLI app.
It contains boilerplate to setup the Automate SDK services, Resolve your function, and run it via the call to `IAutomationRunner.Main<TInput>`. This method handles argument parsing and accepts:
In this file, you'll find a call to `AutomationRunner.Main<TInput>`, which serves as your function's SDK entry point. This method handles argument parsing and accepts:
- `args` -> the arguments provided by Speckle Automate, and
- `Func<AutomationContext, TInput>` -> Your custom function that gets executed when the automation is triggered.
> [!NOTE]
> If your function requires no inputs, there is also `IAutomationRunner.Main` (non-generic) which takes in a `Func<AutomationContext>` instead.
> If your function requires no inputs, there is also `AutomationRunner.Main` (non-generic) which takes in a `Func<AutomationContext>` instead.
This sets up a CLI application with two commands:
-6
View File
@@ -5,8 +5,6 @@ VisualStudioVersion = 17.5.002.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SpeckleAutomateDotnetExample", "SpeckleAutomateDotnetExample/SpeckleAutomateDotnetExample.csproj", "{E1DE5809-1111-4817-9B7D-7ADCA087FA1C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestAutomateFunction", "TestAutomateFunction\TestAutomateFunction.csproj", "{8107A920-A5E2-459C-9756-04B91FB63F3F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -17,10 +15,6 @@ Global
{E1DE5809-1111-4817-9B7D-7ADCA087FA1C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E1DE5809-1111-4817-9B7D-7ADCA087FA1C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E1DE5809-1111-4817-9B7D-7ADCA087FA1C}.Release|Any CPU.Build.0 = Release|Any CPU
{8107A920-A5E2-459C-9756-04B91FB63F3F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8107A920-A5E2-459C-9756-04B91FB63F3F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8107A920-A5E2-459C-9756-04B91FB63F3F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8107A920-A5E2-459C-9756-04B91FB63F3F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -1,14 +1,18 @@
using Objects;
using Objects.Geometry;
using Speckle.Automate.Sdk;
using Speckle.Sdk.Models.Extensions;
using Speckle.Core.Logging;
using Speckle.Core.Models.Extensions;
public class AutomateFunction
static class AutomateFunction
{
public async Task Run(
IAutomationContext automationContext,
public static async Task Run(
AutomationContext automationContext,
FunctionInputs functionInputs
)
{
Console.WriteLine("Starting execution");
_ = typeof(ObjectsKit).Assembly; // INFO: Force objects kit to initialize
Console.WriteLine("Receiving version");
var commitObject = await automationContext.ReceiveVersion();
@@ -20,15 +24,6 @@ public class AutomateFunction
.Count(b => b.speckle_type == functionInputs.SpeckleTypeToCount);
Console.WriteLine($"Counted {count} objects");
if (count < functionInputs.SpeckleTypeTargetCount)
{
automationContext.MarkRunFailed(
$"Counted {count} objects where {functionInputs.SpeckleTypeTargetCount} were expected"
);
return;
}
automationContext.MarkRunSuccess($"Counted {count} objects");
}
}
+2 -22
View File
@@ -1,32 +1,12 @@
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using Speckle.Automate.Sdk.DataAnnotations;
/// <summary>
/// This class describes the user specified variables that the function wants to work with.
/// </summary>
/// This class is used to generate a JSON Schema to ensure that the user provided values
/// are valid and match the required schema.
public readonly struct FunctionInputs
struct FunctionInputs
{
/// <summary>
/// The object type to count instances of in the given model version.
/// </summary>
[Required]
public string SpeckleTypeToCount { get; init; }
/// <summary>
/// The total number of the specified type expected.
/// </summary>
[DefaultValue(10)]
[Range(1, 100)]
[Required]
public int SpeckleTypeTargetCount { get; init; }
/// <summary>
/// An arbitrary example of using a secret input value.
/// </summary>
[Required]
[Secret]
public string ExternalServiceKey { get; init; }
public string SpeckleTypeToCount;
}
+4 -12
View File
@@ -1,14 +1,6 @@
using Microsoft.Extensions.DependencyInjection;
using Speckle.Automate.Sdk;
//Boilerplate to setup Automate SDK
var serviceCollection = new ServiceCollection();
serviceCollection.AddAutomateSdk();
serviceCollection.AddSingleton<AutomateFunction>();
await using var container = serviceCollection.BuildServiceProvider();
var runner = container.GetRequiredService<IAutomationRunner>();
var function = container.GetRequiredService<AutomateFunction>();
using Speckle.Automate.Sdk;
// WARNING do not delete this call, this is the actual execution of your function
return await runner.Main<FunctionInputs>(args, function.Run);
return await AutomationRunner
.Main<FunctionInputs>(args, AutomateFunction.Run)
.ConfigureAwait(false);
@@ -2,15 +2,13 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<NoWarn>$(NoWarn);NETSDK1206</NoWarn>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.1" />
<PackageReference Include="Speckle.Automate.Sdk" Version="3.4.0-alpha.20" />
<PackageReference Include="Speckle.Automate.Sdk" Version="2.18.0-fileInput" />
<PackageReference Include="Speckle.Objects" Version="2.18.0-fileInput" />
</ItemGroup>
</Project>
@@ -1,60 +0,0 @@
using Microsoft.Extensions.DependencyInjection;
using Speckle.Automate.Sdk;
using Speckle.Automate.Sdk.Test;
using Speckle.Sdk.Api;
using Speckle.Sdk.Api.GraphQL.Models;
using Speckle.Sdk.Credentials;
namespace TestAutomateFunction;
[TestFixture]
public sealed class AutomationContextTest : IDisposable
{
private IClient _client;
private Account _account;
private IAutomationRunner _runner;
private AutomateFunction _function;
[OneTimeSetUp]
public void Setup()
{
var serviceProvider = ServiceRegistration.GetServiceProvider();
_account = new Account
{
token = TestAutomateEnvironment.GetSpeckleToken(),
serverInfo = new ServerInfo
{
url = TestAutomateEnvironment.GetSpeckleServerUrl().ToString()
}
};
_client = serviceProvider.GetRequiredService<IClientFactory>().Create(_account);
_runner = serviceProvider.GetRequiredService<IAutomationRunner>();
_function = serviceProvider.GetRequiredService<AutomateFunction>();
}
[Test]
public async Task TestFunctionRun()
{
var inputs = new FunctionInputs
{
SpeckleTypeToCount = "Base",
SpeckleTypeTargetCount = 1
};
var automationRunData = await TestAutomateUtils.CreateTestRun(_client);
var automationContext = await _runner.RunFunction(
_function.Run,
automationRunData,
_account.token,
inputs
);
Assert.That(automationContext.RunStatus, Is.EqualTo("SUCCEEDED"));
}
public void Dispose()
{
_client.Dispose();
TestAutomateEnvironment.Clear();
}
}
@@ -1,15 +0,0 @@
using Microsoft.Extensions.DependencyInjection;
using Speckle.Automate.Sdk;
namespace TestAutomateFunction;
public static class ServiceRegistration
{
public static IServiceProvider GetServiceProvider()
{
var serviceCollection = new ServiceCollection();
serviceCollection.AddAutomateSdk();
serviceCollection.AddSingleton<AutomateFunction>();
return serviceCollection.BuildServiceProvider();
}
}
@@ -1,34 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.0" />
<PackageReference Include="NUnit" Version="4.3.2" />
<PackageReference Include="NUnit3TestAdapter" Version="5.0.0"/>
<PackageReference Include="NUnit.Analyzers" Version="4.7.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="6.0.4">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SpeckleAutomateDotnetExample\SpeckleAutomateDotnetExample.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
-1
View File
@@ -1 +0,0 @@
global using NUnit.Framework;
@@ -1,6 +0,0 @@
{
"SpeckleToken": "YOUR-TOKEN-HERE",
"SpeckleServerUrl": "http://127.0.0.1:3000",
"SpeckleProjectId": "YOUR-PROJECT-ID-HERE",
"SpeckleAutomationId": "YOUR-AUTOMATION-ID-HERE"
}