Skip to content

Commit

Permalink
[auto] Add new API to install the Pulumi CLI from the Automation API
Browse files Browse the repository at this point in the history
  • Loading branch information
julienp committed Jan 25, 2024
1 parent a5f3d6c commit 387c2eb
Show file tree
Hide file tree
Showing 10 changed files with 405 additions and 84 deletions.
6 changes: 6 additions & 0 deletions .changes/unreleased/Improvements-226.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
component: sdk/auto
kind: Improvements
body: Add new API to install the Pulumi CLI from the Automation API
time: 2024-01-25T13:32:17.304538+01:00
custom:
PR: "226"
129 changes: 127 additions & 2 deletions sdk/Pulumi.Automation.Tests/LocalPulumiCmdTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Pulumi.Automation.Commands;
using Semver;
using Xunit;

namespace Pulumi.Automation.Tests
Expand All @@ -15,7 +17,7 @@ public class LocalPulumiCmdTests
[Fact]
public async Task CheckVersionCommand()
{
var localCmd = new LocalPulumiCmd();
var localCmd = await LocalPulumiCmd.CreateAsync();
var extraEnv = new Dictionary<string, string?>();
var args = new[] { "version" };

Expand Down Expand Up @@ -57,6 +59,129 @@ private List<string> Lines(string s)
.Select(x => x.Trim())
.ToList();
}

[Fact]
public async Task InstallDefaultRoot()
{
var requestedVersion = new SemVersion(3, 102, 0);
await LocalPulumiCmd.Install(new LocalPulumiCmdOptions { Version = requestedVersion });
var home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
var pulumiBin = Path.Combine(home, ".pulumi", "versions", requestedVersion.ToString(), "bin", "pulumi");
Assert.True(File.Exists(pulumiBin));
}

[Fact]
public async Task InstallTwice()
{
var tempDir = Path.Combine(Path.GetTempPath(), "automation-test-" + Guid.NewGuid().ToString());
Directory.CreateDirectory(tempDir);
try
{
var requestedVersion = new SemVersion(3, 102, 0);
await LocalPulumiCmd.Install(new LocalPulumiCmdOptions { Version = requestedVersion, Root = tempDir });
var home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
var pulumiBin = Path.Combine(home, ".pulumi", "versions", requestedVersion.ToString(), "bin", "pulumi");
FileInfo fi1 = new FileInfo(pulumiBin);
var t1 = fi1.CreationTime;
// Install again with the same options
await LocalPulumiCmd.Install(new LocalPulumiCmdOptions { Version = requestedVersion, Root = tempDir });
FileInfo fi2 = new FileInfo(pulumiBin);
var t2 = fi2.CreationTime;
Assert.Equal(t1, t2);
}
finally
{
Directory.Delete(tempDir, true);
}

}

[Fact]
public async Task VersionCheck()
{
var dirPath = Path.Combine(Path.GetTempPath(), "automation-test-" + Guid.NewGuid().ToString());
var dir = Directory.CreateDirectory(dirPath);
try
{
// Install an old version
var installed_version = new SemVersion(3, 99, 0);
await LocalPulumiCmd.Install(new LocalPulumiCmdOptions { Version = installed_version, Root = dirPath });

// Try to create a command with a more recent version
var requested_version = new SemVersion(3, 102, 0);
await Assert.ThrowsAsync<InvalidOperationException>(() => LocalPulumiCmd.CreateAsync(new LocalPulumiCmdOptions
{
Version = requested_version,
Root = dirPath
}));

// Opting out of the version check works
await LocalPulumiCmd.CreateAsync(new LocalPulumiCmdOptions
{
Version = requested_version,
Root = dirPath,
SkipVersionCheck = true
});
}
finally
{
dir.Delete(true);
}
}

[Fact]
public void PulumiEnvironment()
{
var env = new Dictionary<string, string?>{
{"PATH", "/usr/bin"}
};
var newEnv = LocalPulumiCmd.PulumiEnvironment(env, "pulumi", false);
Assert.Equal("/usr/bin", newEnv["PATH"]);

env = new Dictionary<string, string?>{
{"PATH", "/usr/bin"}
};
newEnv = LocalPulumiCmd.PulumiEnvironment(env, "/some/install/root/bin/pulumi", false);
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
Assert.Equal("/some/install/root/bin;/usr/bin", newEnv["PATH"]);
}
else
{
Assert.Equal("/some/install/root/bin:/usr/bin", newEnv["PATH"]);
}
}

[Theory]
[InlineData("100.0.0", true, false)]
[InlineData("1.0.0", true, false)]
[InlineData("2.22.0", false, false)]
[InlineData("2.1.0", true, false)]
[InlineData("2.21.2", false, false)]
[InlineData("2.21.1", false, false)]
[InlineData("2.21.0", true, false)]
// Note that prerelease < release so this case should error
[InlineData("2.21.1-alpha.1234", true, false)]
[InlineData("2.20.0", false, true)]
[InlineData("2.22.0", false, true)]
// Invalid version check
[InlineData("invalid", false, true)]
[InlineData("invalid", true, false)]
public void ValidVersionTheory(string currentVersion, bool errorExpected, bool optOut)
{
var testMinVersion = new SemVersion(2, 21, 1);

if (errorExpected)
{
void ValidatePulumiVersion() => LocalPulumiCmd.ParseAndValidatePulumiVersion(testMinVersion, currentVersion, optOut);
Assert.Throws<InvalidOperationException>(ValidatePulumiVersion);
}
else
{
LocalPulumiCmd.ParseAndValidatePulumiVersion(testMinVersion, currentVersion, optOut);
}
}

}

}
32 changes: 0 additions & 32 deletions sdk/Pulumi.Automation.Tests/LocalWorkspaceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,13 @@
using Pulumi.Automation.Commands.Exceptions;
using Pulumi.Automation.Events;
using Pulumi.Automation.Exceptions;
using Semver;
using Serilog;
using Serilog.Extensions.Logging;
using Xunit;
using Xunit.Abstractions;
using ILogger = Microsoft.Extensions.Logging.ILogger;

using static Pulumi.Automation.Tests.Utility;
using Xunit.Sdk;

namespace Pulumi.Automation.Tests
{
Expand Down Expand Up @@ -1682,36 +1680,6 @@ public async Task PulumiVersionTest()
Assert.Matches("(\\d+\\.)(\\d+\\.)(\\d+)(-.*)?", workspace.PulumiVersion);
}

[Theory]
[InlineData("100.0.0", true, false)]
[InlineData("1.0.0", true, false)]
[InlineData("2.22.0", false, false)]
[InlineData("2.1.0", true, false)]
[InlineData("2.21.2", false, false)]
[InlineData("2.21.1", false, false)]
[InlineData("2.21.0", true, false)]
// Note that prerelease < release so this case should error
[InlineData("2.21.1-alpha.1234", true, false)]
[InlineData("2.20.0", false, true)]
[InlineData("2.22.0", false, true)]
// Invalid version check
[InlineData("invalid", false, true)]
[InlineData("invalid", true, false)]
public void ValidVersionTheory(string currentVersion, bool errorExpected, bool optOut)
{
var testMinVersion = new SemVersion(2, 21, 1);

if (errorExpected)
{
void ValidatePulumiVersion() => LocalWorkspace.ParseAndValidatePulumiVersion(testMinVersion, currentVersion, optOut);
Assert.Throws<InvalidOperationException>(ValidatePulumiVersion);
}
else
{
LocalWorkspace.ParseAndValidatePulumiVersion(testMinVersion, currentVersion, optOut);
}
}

[Fact]
public async Task RespectsProjectSettingsTest()
{
Expand Down
2 changes: 1 addition & 1 deletion sdk/Pulumi.Automation/Commands/CommandResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace Pulumi.Automation.Commands
{
internal class CommandResult
public class CommandResult
{
public int Code { get; }

Expand Down
5 changes: 4 additions & 1 deletion sdk/Pulumi.Automation/Commands/IPulumiCmd.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@
using System.Threading;
using System.Threading.Tasks;
using Pulumi.Automation.Events;
using Semver;

namespace Pulumi.Automation.Commands
{
internal interface IPulumiCmd
public interface IPulumiCmd
{
SemVersion? Version { get; }

Task<CommandResult> RunAsync(
IList<string> args,
string workingDir,
Expand Down
Loading

0 comments on commit 387c2eb

Please sign in to comment.