First attempt to use the automation api and I get ...
# dotnet
w
First attempt to use the automation api and I get the following exception:
Copy code
System.MissingMethodException: Method not found: 'Void YamlDotNet.Core.Events.MappingStart..ctor(System.String, System.String, Boolean, YamlDotNet.Core.Events.MappingStyle)'.
  at Pulumi.Automation.Serialization.Yaml.ProjectRuntimeYamlConverter.WriteYaml(IEmitter emitter, Object value, Type type)
  at YamlDotNet.Serialization.ObjectGraphVisitors.CustomSerializationObjectGraphVisitor.Enter(IObjectDescriptor value, IEmitter context)
  at YamlDotNet.Serialization.ObjectGraphTraversalStrategies.FullObjectGraphTraversalStrategy.Traverse[[TContext]](Object name, IObjectDescriptor value, IObjectGraphVisitor`1 visitor, TContext context, Stack`1 path)
  at YamlDotNet.Serialization.ObjectGraphTraversalStrategies.FullObjectGraphTraversalStrategy.TraverseProperties[[TContext]](IObjectDescriptor value, IObjectGraphVisitor`1 visitor, TContext context, Stack`1 path)
  at YamlDotNet.Serialization.ObjectGraphTraversalStrategies.FullObjectGraphTraversalStrategy.TraverseObject[[TContext]](IObjectDescriptor value, IObjectGraphVisitor`1 visitor, TContext context, Stack`1 path)
  at YamlDotNet.Serialization.ObjectGraphTraversalStrategies.FullObjectGraphTraversalStrategy.Traverse[[TContext]](Object name, IObjectDescriptor value, IObjectGraphVisitor`1 visitor, TContext context, Stack`1 path)
  at YamlDotNet.Serialization.ObjectGraphTraversalStrategies.FullObjectGraphTraversalStrategy.YamlDotNet.Serialization.IObjectGraphTraversalStrategy.Traverse[[TContext]](IObjectDescriptor graph, IObjectGraphVisitor`1 visitor, TContext context)
  at YamlDotNet.Serialization.SerializerBuilder.ValueSerializer.SerializeValue(IEmitter emitter, Object value, Type type)
  at YamlDotNet.Serialization.Serializer.EmitDocument(IEmitter emitter, Object graph, Type type)
  at YamlDotNet.Serialization.Serializer.Serialize(IEmitter emitter, Object graph)
  at YamlDotNet.Serialization.Serializer.Serialize(TextWriter writer, Object graph)
  at YamlDotNet.Serialization.Serializer.Serialize(Object graph)
  at Pulumi.Automation.Serialization.LocalSerializer.SerializeYaml[[T]](T object) in LocalSerializer.cs:41
  at Pulumi.Automation.LocalWorkspace.SaveProjectSettingsAsync(ProjectSettings settings, CancellationToken cancellationToken) in LocalWorkspace.cs:419
  at Pulumi.Automation.LocalWorkspace.InitializeProjectSettingsAsync(ProjectSettings projectSettings, CancellationToken cancellationToken) in LocalWorkspace.cs:355
  at Pulumi.Automation.LocalWorkspace.CreateStackHelperAsync(InlineProgramArgs args, Func`4 initFunc, CancellationToken cancellationToken) in LocalWorkspace.cs:275
  at Pharos.Gemini.DeployCommand.ExecuteAsync(CommandContext context, Settings settings)
This is the core code:
Copy code
public override async Task<int> ExecuteAsync(CommandContext context, Settings settings)
{
    try
    {
        var deployedResources = OrderedResources.Where(resource => settings.Resources.HasFlag(resource));
        foreach (var resource in deployedResources)
        {
            var info = ResourceInfoMap[resource];
            Logger.LogDebug($"Deploying {info.ProjectName}...");
            var stackName = $"{settings.Organization.ToLower()}/{settings.Environment.ToString().ToLower()}";
            var stackArgs = new InlineProgramArgs(info.ProjectName, stackName, info.Program);
            var stack = await LocalWorkspace.CreateOrSelectStackAsync(stackArgs);
            foreach (var plugin in info.Plugins)
            {
                var pluginArgs = plugin.Split(" ");
                await stack.Workspace.InstallPluginAsync(pluginArgs[0], pluginArgs[1]);
            }
            //await stack.SetConfigAsync("aws:region", new ConfigValue("us-east-1")); //TODO
            await stack.RefreshAsync(new RefreshOptions { OnStandardOutput = AnsiConsole.WriteLine });
            var result = await stack.UpAsync(new UpOptions { OnStandardOutput = AnsiConsole.WriteLine });
            if (result.Summary.ResourceChanges != null)
            {
                AnsiConsole.WriteLine("Summary:");
                foreach (var (key, value) in result.Summary.ResourceChanges)
                {
                    AnsiConsole.WriteLine($"    {key}: {value}");
                }
            }
            Logger.LogDebug($"Deployed {info.ProjectName}");
        }
        return 0;
    }
    catch (Exception ex)
    {
        AnsiConsole.WriteException(ex, ExceptionFormats.ShortenPaths);
        return -1;
    }
}
Project file:
Copy code
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net5.0</TargetFramework>

    <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
    <AssemblyName>gemini</AssemblyName>
  </PropertyGroup>

  <PropertyGroup Condition="'$(Configuration)' == 'Release'">
    <DebuggerSupport>false</DebuggerSupport>
    <EnableUnsafeBinaryFormatterSerialization>false</EnableUnsafeBinaryFormatterSerialization>
    <EnableUnsafeUTF7Encoding>false</EnableUnsafeUTF7Encoding>
    <EventSourceSupport>false</EventSourceSupport>
    <HttpActivityPropagationSupport>false</HttpActivityPropagationSupport>
    <IncludeNativeLibrariesForSelfExtract>false</IncludeNativeLibrariesForSelfExtract>
    <InvariantGlobalization>true</InvariantGlobalization>
    <PublishSingleFile>true</PublishSingleFile>
    <PublishTrimmed>true</PublishTrimmed>
    <RuntimeIdentifier>linux-x64</RuntimeIdentifier>
    <TrimMode>Link</TrimMode>
  </PropertyGroup>

  <ItemGroup>
    <ProjectReference Include="..\Aws\Aws.csproj" />
    <ProjectReference Include="..\Kubernetes\Kubernetes.csproj" />
    <ProjectReference Include="..\Library\Library.csproj" />
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Extensions.Hosting" Version="5.0.0" />
    <PackageReference Include="NetEscapades.Configuration.Yaml" Version="2.1.0" />
    <PackageReference Include="Pulumi.Automation" Version="3.1.0" />
    <PackageReference Include="Serilog" Version="2.10.0" />
    <PackageReference Include="Serilog.Extensions.Hosting" Version="4.1.2" />
    <PackageReference Include="Serilog.Settings.Configuration" Version="3.1.0" />
    <PackageReference Include="Serilog.Sinks.Seq" Version="5.0.1" />
    <PackageReference Include="Spectre.Console" Version="0.39.1-preview.0.7" />
  </ItemGroup>

  <ItemGroup>
    <None Update="config.Development.yml">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </None>
    <None Update="config.yml">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </None>
  </ItemGroup>
</Project>
p
I recall similar error occurring when I had different versions of YamlDotNet in use, do you use YamlDotNet in your own code?
w
Yeah, my library depends on
YamlDotNet
11.1.1
. I changed it to
9.1.0
and it worked.
9.1.4
and
10.0.0
work.
10.1.0
does not work.
I can't see any relevant breaking change so it must be due to different type identities. Directly depending on a later version so it gets loaded first doesn't work either.
Basically previously the anchor & tags were plain strings, but now they are custom types
w
Ah.
Pulumi.Automation
passes null for both anchor and tags. Updating it to
YamlDotNet
11.1.1
compiles without any issues.
@prehistoric-coat-10166 would you accept a PR to bump
YamlDotNet
to latest?
p
I'm actually not part of Pulumi, just a contributor, but I don't see why the package could not be updated
w
@tall-librarian-49374?
t
I’m not up-to-date on that one… Does it manifest in any observable behavior changes? cc @bored-oyster-3147 too
b
I think we have the YAML serialization pretty well unit tested so we could just bump and see?
at least for the types we are internally serializing.
@worried-city-86458 do you have an issue open for this? I could get it together quick
w
@bored-oyster-3147 cool, I'll send a PR later this morning.
I'm still having trouble building everything but haven't spent any more time on it - relying on CI to flush out issues. @bored-oyster-3147 what does your environment look like? How do you build and test everything?
b
In order for me to run tests locally I need to make sure that I have a pulumi api account set up and that I am currently logged into it. Because the tests are actually creating & manipulating projects/stacks I don't really have any issues building though, so if you are having issues there we can look at it
w
@bored-oyster-3147 I've now got a full build to work via vs code dev container (tests aside) Do you build everything or just focus on the dotnet sdk (which is ultimately what I would do)? Do you use vs code, visual studio or jetbrains rider? I'm still curious what your dev inner loop looks like... live in ide and just build from cli before pushing?
b
I’m not using a dev container though I could probably benefit from it. I primarily use VS and the dev container loop is a bit easier in VS Code. So I only build the .NET SDK, personally. I use VS for all the dotnet stuff. I use VS Code for everything else if I need to touch anything else. Powershell for git manipulation, with posh-git. I build and test from within VS. But first I just make sure that I am logged into Pulumi API by opening up the credentials.json file in my pulumi user folder and making sure “current” is the pulumi api domain. I’m sure there’s an easier way to verify that but I’ve always found any CLI auth to be finicky so that’s my sanity check.
w
How do you build the dotnet sdk? Directly in windows, outside of wsl2, with all source files in windows? i.e. from inside vs only, without using the build tools required by pulumi build? (I'm much happier living in vs [2019] rather than in vs code)
b
I just open the dotnet sdk in VS and build it in VS. I don’t even have
make
installed.. I’m pretty strictly dotnet at the moment 😅
🍺 1