Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions .github/workflows/_publish-cli-code.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: Publish CLI to NuGet

on:
workflow_call:
workflow_dispatch:

jobs:
publish:
name: Publish CLI release to NuGet
runs-on: ubuntu-latest

steps:
- name: Check out Git repository
uses: actions/checkout@v5

- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '10.0.x'

- name: Restore strong-name key from secret
run: |
echo "${{ secrets.MINDEE_SNK_B64 }}" | base64 -d > /tmp/Mindee.snk
chmod 600 /tmp/Mindee.snk

- name: Install dependencies
run: dotnet restore "src/Mindee.Cli" -p:TargetFrameworks=net8.0

- name: Build (strong-name signed)
run: dotnet build "src/Mindee.Cli" --configuration Release --no-restore -p:TargetFrameworks=net8.0 -p:MindeeStrongNameKeyFile=/tmp/Mindee.snk

- name: Pack
run: dotnet pack "src/Mindee.Cli" -c Release -p:PackAsTool=true -p:TargetFrameworks=net8.0 -p:IncludeSymbols=true -p:SymbolPackageFormat=snupkg --no-build --no-restore --output nuget

- name: Verify strong-name (PublicKeyToken)
run: |
sudo apt-get update
sudo apt-get install -y mono-devel unzip
DLL_PATH=$(unzip -Z -1 nuget/*.nupkg | grep -m1 '/Mindee.dll$')
if [ -z "$DLL_PATH" ]; then
echo "Mindee.dll not found in packaged CLI tool."
exit 1
fi
unzip -p nuget/*.nupkg "$DLL_PATH" > /tmp/Mindee.dll
sn -T /tmp/Mindee.dll
sn -vf /tmp/Mindee.dll

- name: Publish NuGet packages to NuGet
run: dotnet nuget push nuget/*.nupkg --api-key ${{ secrets.NUGET_KEY }} --source "nuget.org" --skip-duplicate
3 changes: 3 additions & 0 deletions .github/workflows/publish-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,6 @@ jobs:
publish_code:
uses: mindee/mindee-api-dotnet/.github/workflows/_publish-code.yml@main
secrets: inherit
publish_cli_code:
uses: mindee/mindee-api-dotnet/.github/workflows/_publish-cli-code.yml@main
secrets: inherit
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -370,3 +370,5 @@ _site
# StrongName files
*.snk
*.snk.b64
# Local CLI publish.
dotnet-tools.json
15 changes: 14 additions & 1 deletion src/Mindee.Cli/Commands/V1/PredictCommand.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.CommandLine;
using System.Text.Json;
using Microsoft.Extensions.Options;
using Mindee.Input;
using Mindee.V1;
using Mindee.V1.ClientOptions;
Expand Down Expand Up @@ -93,7 +94,7 @@ public PredictCommand(CommandOptions options)
Arguments.Add(_pathArgument);
}

public void ConfigureAction(V1Client mindeeClientV1)
public void ConfigureAction(Func<V1Client> clientFactory)
{
this.SetAction(parseResult =>
{
Expand All @@ -102,6 +103,18 @@ public void ConfigureAction(V1Client mindeeClientV1)
var fullText = _fullTextOption != null && parseResult.GetValue(_fullTextOption);
var output = parseResult.GetValue(_outputOption);
var isAsync = _asyncOption != null && parseResult.GetValue(_asyncOption);
V1Client mindeeClientV1;
try
{
mindeeClientV1 = clientFactory();
}
catch (OptionsValidationException)
{
Console.Error.WriteLine(
"The Mindee V1 API key is missing. " +
"Please provide it via the '--api-key' option or your configured environment variable.");
return 1;
}

var handler = new Handler(mindeeClientV1);
return handler.InvokeAsync(path, allWords, fullText, output, isAsync).GetAwaiter().GetResult();
Expand Down
45 changes: 42 additions & 3 deletions src/Mindee.Cli/Commands/V2/InferenceCommand.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System.CommandLine;
using System.Text.Json;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Mindee.Input;
using Mindee.V2.Parsing;
using Mindee.V2.Product.Classification;
Expand All @@ -12,6 +14,7 @@
using Mindee.V2.Product.Ocr.Params;
using Mindee.V2.Product.Split;
using Mindee.V2.Product.Split.Params;
using SettingsV2 = Mindee.V2.Http.Settings;
using V2Client = Mindee.V2.Client;

namespace Mindee.Cli.Commands.V2
Expand Down Expand Up @@ -71,15 +74,16 @@ class InferenceCommand : Command
private readonly Option<string?>? _textContextOption;
private readonly Option<string> _modelIdOption;
private readonly Argument<string> _pathArgument;
private readonly Option<string?> _apiKeyOption;

public InferenceCommand(InferenceCommandOptions options)
: base(options.Name, options.Description)
{
_modelIdOption =
new Option<string>("--model-id", "-m") { Description = "ID of the model to use", Required = true };
Options.Add(_modelIdOption);
var apiKeyOption = new Option<string>("--api-key", "-k") { Description = "Mindee V2 API key." };
Options.Add(apiKeyOption); // Will not be used at this step, only here for help display purposes.
_apiKeyOption = new Option<string?>("--api-key", "-k") { Description = "Mindee V2 API key." };
Options.Add(_apiKeyOption);

_productName = options.Name;
_aliasOption = new Option<string?>("--alias", "-a")
Expand Down Expand Up @@ -157,8 +161,28 @@ public InferenceCommand(InferenceCommandOptions options)
Arguments.Add(_pathArgument);
}

public void ConfigureAction(V2Client mindeeClientV2)
public void ConfigureAction(IServiceProvider services)
{
Validators.Add(commandResult =>
{
var apiKey = commandResult.GetValue(_apiKeyOption);
if (!string.IsNullOrWhiteSpace(apiKey))
{
return;
}

try
{
_ = services.GetRequiredService<IOptions<SettingsV2>>().Value;
}
catch (OptionsValidationException)
{
commandResult.AddError(
"The Mindee V2 API key is missing. " +
"Please provide it via the '--api-key' option or your configured environment variable.");
}
});

this.SetAction(parseResult =>
{
var path = parseResult.GetValue(_pathArgument)!;
Expand All @@ -180,6 +204,21 @@ public void ConfigureAction(V2Client mindeeClientV2)
}

var output = parseResult.GetValue(_outputOption);
var apiKey = parseResult.GetValue(_apiKeyOption);
V2Client mindeeClientV2;
try
{
mindeeClientV2 = !string.IsNullOrWhiteSpace(apiKey)
? new V2Client(apiKey)
: services.GetRequiredService<V2Client>();
}
catch (OptionsValidationException)
{
Console.Error.WriteLine(
"The Mindee V2 API key is missing. " +
"Please provide it via the '--api-key' option or your configured environment variable.");
return 1;
}

var handler = new Handler(mindeeClientV2);
return handler
Expand Down
46 changes: 44 additions & 2 deletions src/Mindee.Cli/Commands/V2/SearchModelsCommand.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
using System.CommandLine;
using System.Text.Json;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Mindee.V2.Parsing.Search;
using SettingsV2 = Mindee.V2.Http.Settings;
using V2Client = Mindee.V2.Client;

namespace Mindee.Cli.Commands.V2
Expand All @@ -10,6 +13,7 @@ namespace Mindee.Cli.Commands.V2
/// </summary>
public class SearchModelsCommand : Command
{
private readonly Option<string?> _apiKeyOption;
private readonly Option<string?>? _nameOption;
private readonly Option<string?>? _modelTypeOption;
private readonly Option<bool>? _rawOption;
Expand All @@ -19,6 +23,9 @@ public class SearchModelsCommand : Command
/// </summary>
public SearchModelsCommand() : base("search-models", "Search available models.")
{
_apiKeyOption = new Option<string?>("--api-key", "-k") { Description = "Mindee V2 API key." };
Options.Add(_apiKeyOption);

_nameOption = new Option<string?>("--name", "-n")
{
Description = "Filter by model name partial match (case insensitive).",
Expand Down Expand Up @@ -50,14 +57,49 @@ Filter by exact model type (case sensitive).
/// <summary>
///
/// </summary>
/// <param name="mindeeClientV2">V2 Client instance</param>
public void ConfigureAction(V2Client mindeeClientV2)
/// <param name="services">Service provider for dependency resolution</param>
public void ConfigureAction(IServiceProvider services)
{
Validators.Add(commandResult =>
{
var apiKey = commandResult.GetValue(_apiKeyOption);
if (!string.IsNullOrWhiteSpace(apiKey))
{
return;
}

try
{
_ = services.GetRequiredService<IOptions<SettingsV2>>().Value;
}
catch (OptionsValidationException)
{
commandResult.AddError(
"The Mindee V2 API key is missing. " +
"Please provide it via the '--api-key' option or your configured environment variable.");
}
});

this.SetAction(parseResult =>
{
var name = _nameOption != null ? parseResult.GetValue(_nameOption) : null;
var modelType = _modelTypeOption != null ? parseResult.GetValue(_modelTypeOption) : null;
var raw = _rawOption != null && parseResult.GetValue(_rawOption);
var apiKey = parseResult.GetValue(_apiKeyOption);
V2Client mindeeClientV2;
try
{
mindeeClientV2 = !string.IsNullOrWhiteSpace(apiKey)
? new V2Client(apiKey)
: services.GetRequiredService<V2Client>();
}
catch (OptionsValidationException)
{
Console.Error.WriteLine(
"The Mindee V2 API key is missing. " +
"Please provide it via the '--api-key' option or your configured environment variable.");
return 1;
}

var handler = new Handler(mindeeClientV2);
return handler
Expand Down
3 changes: 3 additions & 0 deletions src/Mindee.Cli/Mindee.Cli.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
<OutputType>Exe</OutputType>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PackAsTool>true</PackAsTool>
<ToolCommandName>mindee</ToolCommandName>
</PropertyGroup>

<ItemGroup>
Expand Down Expand Up @@ -43,6 +45,7 @@
<ItemGroup>
<None Include="..\..\LICENSE" Pack="true" PackagePath=""/>
<None Include="..\..\Logo.png" Pack="true" Visible="false" PackagePath=""/>
<None Include="README.md" Pack="true" Visible="false" PackagePath=""/>
<None Include="..\..\CHANGELOG.md" Pack="true" Visible="false" PackagePath=""/>
</ItemGroup>

Expand Down
Loading
Loading