[automation/dotnet] - Implement min version checking (#6590)

This commit is contained in:
Komal 2021-03-24 10:43:44 -07:00 committed by GitHub
parent 7f42d42b2b
commit 19c055315d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 82 additions and 2 deletions

1
.gitignore vendored
View file

@ -6,6 +6,7 @@
**/.vs/
**/.ionide/
**/.idea/
**/.DS_Store
coverage.cov
*.coverprofile

View file

@ -9,11 +9,12 @@
- [sdk/go] Cache loaded configuration files.
[#6576](https://github.com/pulumi/pulumi/pull/6576)
- [automation/go,nodejs,python] Implement minimum version checking and add:
- [automation/*] Implement minimum version checking and add:
- Go: `LocalWorkspace.PulumiVersion()` - [#6577](https://github.com/pulumi/pulumi/pull/6577)
- Nodejs: `LocalWorkspace.pulumiVersion` - [#6580](https://github.com/pulumi/pulumi/pull/6580)
- Python: `LocalWorkspace.pulumi_version` - [#6589](https://github.com/pulumi/pulumi/pull/6589)
- Dotnet: `LocalWorkspace.PulumiVersion` - [#6590](https://github.com/pulumi/pulumi/pull/6590)
### Bug Fixes
- [automation/python] Fix Settings file save

View file

@ -1,5 +1,6 @@
// Copyright 2016-2021, Pulumi Corporation
using Semver;
using System;
using System.Collections.Generic;
using System.IO;
@ -826,5 +827,36 @@ namespace Pulumi.Automation.Tests
Assert.True(expSecretValue.IsSecret);
}
}
[Fact]
public async Task PulumiVersionTest()
{
using var workspace = await LocalWorkspace.CreateAsync();
Assert.Matches("(\\d+\\.)(\\d+\\.)(\\d+)(-.*)?", workspace.PulumiVersion);
}
[Theory]
[InlineData("100.0.0", true)]
[InlineData("1.0.0", true)]
[InlineData("2.22.0", false)]
[InlineData("2.1.0", true)]
[InlineData("2.21.2", false)]
[InlineData("2.21.1", false)]
[InlineData("2.21.0", true)]
// Note that prerelease < release so this case should error
[InlineData("2.21.1-alpha.1234", true)]
public void ValidVersionTheory(string currentVersion, bool errorExpected)
{
var testMinVersion = SemVersion.Parse("2.21.1");
if (errorExpected)
{
Action act = () => LocalWorkspace.ValidatePulumiVersion(testMinVersion, currentVersion);
Assert.Throws<InvalidOperationException>(act);
}
else
{
LocalWorkspace.ValidatePulumiVersion(testMinVersion, currentVersion);
}
}
}
}

View file

@ -1,5 +1,6 @@
// Copyright 2016-2021, Pulumi Corporation
using Semver;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
@ -34,6 +35,7 @@ namespace Pulumi.Automation
private readonly LocalSerializer _serializer = new LocalSerializer();
private readonly bool _ownsWorkingDir;
private readonly Task _readyTask;
private static readonly SemVersion _minimumVersion = SemVersion.Parse("2.21.0");
/// <inheritdoc/>
public override string WorkDir { get; }
@ -41,6 +43,10 @@ namespace Pulumi.Automation
/// <inheritdoc/>
public override string? PulumiHome { get; }
private SemVersion? pulumiVersion;
/// <inheritdoc/>
public override string PulumiVersion => pulumiVersion?.ToString() ?? throw new InvalidOperationException("Failed to get Pulumi version.");
/// <inheritdoc/>
public override string? SecretsProvider { get; }
@ -320,6 +326,8 @@ namespace Pulumi.Automation
this.WorkDir = dir;
readyTasks.Add(this.PopulatePulumiVersionAsync(cancellationToken));
// these are after working dir is set because they start immediately
if (options?.ProjectSettings != null)
readyTasks.Add(this.SaveProjectSettingsAsync(options.ProjectSettings, cancellationToken));
@ -335,6 +343,29 @@ namespace Pulumi.Automation
private static readonly string[] SettingsExtensions = new string[] { ".yaml", ".yml", ".json" };
private async Task PopulatePulumiVersionAsync(CancellationToken cancellationToken)
{
var result = await this.RunCommandAsync(new[] { "version" }, cancellationToken).ConfigureAwait(false);
var versionString = result.StandardOutput.Trim();
versionString = versionString.TrimStart('v');
if (!SemVersion.TryParse(versionString, out var version))
{
throw new InvalidOperationException("Failed to get Pulumi version.");
}
LocalWorkspace.ValidatePulumiVersion(LocalWorkspace._minimumVersion, version);
this.pulumiVersion = version;
}
internal static void ValidatePulumiVersion(SemVersion minVersion, SemVersion currentVersion)
{
if (minVersion.Major < currentVersion.Major) {
throw new InvalidOperationException($"Major version mismatch. You are using Pulumi CLI version {currentVersion} with Automation SDK v{minVersion.Major}. Please update the SDK.");
}
if (minVersion > currentVersion) {
throw new InvalidOperationException($"Minimum version requirement failed. The minimum CLI version requirement is {minVersion}, your current CLI version is {currentVersion}. Please update the Pulumi CLI.");
}
}
/// <inheritdoc/>
public override async Task<ProjectSettings?> GetProjectSettingsAsync(CancellationToken cancellationToken = default)
{

View file

@ -269,6 +269,7 @@ abstract Pulumi.Automation.Workspace.PostCommandCallbackAsync(string stackName,
abstract Pulumi.Automation.Workspace.Program.get -> Pulumi.Automation.PulumiFn
abstract Pulumi.Automation.Workspace.Program.set -> void
abstract Pulumi.Automation.Workspace.PulumiHome.get -> string
abstract Pulumi.Automation.Workspace.PulumiVersion.get -> string
abstract Pulumi.Automation.Workspace.RefreshConfigAsync(string stackName, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<System.Collections.Immutable.ImmutableDictionary<string, Pulumi.Automation.ConfigValue>>
abstract Pulumi.Automation.Workspace.RemoveConfigAsync(string stackName, System.Collections.Generic.IEnumerable<string> keys, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
abstract Pulumi.Automation.Workspace.RemoveConfigValueAsync(string stackName, string key, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
@ -298,6 +299,7 @@ override Pulumi.Automation.LocalWorkspace.PostCommandCallbackAsync(string stackN
override Pulumi.Automation.LocalWorkspace.Program.get -> Pulumi.Automation.PulumiFn
override Pulumi.Automation.LocalWorkspace.Program.set -> void
override Pulumi.Automation.LocalWorkspace.PulumiHome.get -> string
override Pulumi.Automation.LocalWorkspace.PulumiVersion.get -> string
override Pulumi.Automation.LocalWorkspace.RefreshConfigAsync(string stackName, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<System.Collections.Immutable.ImmutableDictionary<string, Pulumi.Automation.ConfigValue>>
override Pulumi.Automation.LocalWorkspace.RemoveConfigAsync(string stackName, System.Collections.Generic.IEnumerable<string> keys, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
override Pulumi.Automation.LocalWorkspace.RemoveConfigValueAsync(string stackName, string key, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task

View file

@ -43,6 +43,9 @@
<member name="P:Pulumi.Automation.LocalWorkspace.PulumiHome">
<inheritdoc/>
</member>
<member name="P:Pulumi.Automation.LocalWorkspace.PulumiVersion">
<inheritdoc/>
</member>
<member name="P:Pulumi.Automation.LocalWorkspace.SecretsProvider">
<inheritdoc/>
</member>
@ -539,6 +542,11 @@
This customizes the location of $PULUMI_HOME where metadata is stored and plugins are installed.
</summary>
</member>
<member name="P:Pulumi.Automation.Workspace.PulumiVersion">
<summary>
The version of the underlying Pulumi CLI/Engine.
</summary>
</member>
<member name="P:Pulumi.Automation.Workspace.SecretsProvider">
<summary>
The secrets provider to use for encryption and decryption of stack secrets.

View file

@ -38,6 +38,11 @@ namespace Pulumi.Automation
/// </summary>
public abstract string? PulumiHome { get; }
/// <summary>
/// The version of the underlying Pulumi CLI/Engine.
/// </summary>
public abstract string PulumiVersion { get; }
/// <summary>
/// The secrets provider to use for encryption and decryption of stack secrets.
/// <para/>