Skip to content

Commit d6f82c3

Browse files
authored
Implement a --prerelease global option (#39)
* Implement a --prerelease global option * Add messaging when pre image isn't present * Remove --prerelease flag from arguments forwarded to container
1 parent ada5bcb commit d6f82c3

File tree

10 files changed

+54
-20
lines changed

10 files changed

+54
-20
lines changed

src/ActionsImporter.UnitTests/AppTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public void AfterEachTest()
3939
public async Task CheckForUpdates_NoUpdatesNeeded(string? latestImage, string? currentImage, string result)
4040
{
4141
// Arrange
42-
var image = "actions-importer/cli";
42+
var image = "actions-importer/cli:latest";
4343
var server = "ghcr.io";
4444

4545
using var stringWriter = new StringWriter();

src/ActionsImporter.UnitTests/Services/DockerServiceTests.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,7 @@ public void VerifyImagePresentAsync_IsPresent_NoException()
434434
).Returns(Task.CompletedTask);
435435

436436
// Act, Assert
437-
Assert.DoesNotThrowAsync(() => _dockerService.VerifyImagePresentAsync(image, server, version));
437+
Assert.DoesNotThrowAsync(() => _dockerService.VerifyImagePresentAsync(image, server, version, false));
438438
_processService.VerifyAll();
439439
}
440440

@@ -457,21 +457,21 @@ public void VerifyImagePresentAsync_NotPresent_ThrowsException()
457457
).ThrowsAsync(new Exception());
458458

459459
// Act, Assert
460-
Assert.ThrowsAsync<Exception>(() => _dockerService.VerifyImagePresentAsync(image, server, version));
460+
Assert.ThrowsAsync<Exception>(() => _dockerService.VerifyImagePresentAsync(image, server, version, false));
461461
_processService.VerifyAll();
462462
}
463463

464464
[Test]
465465
public async Task GetCurrentImageDigest_ParsesDigestCorrectly()
466466
{
467467
// Arrange
468-
var image = "actions-importer/cli";
468+
var image = "actions-importer/cli:latest";
469469
var server = "ghcr.io";
470470

471471
_processService.Setup(handler =>
472472
handler.RunAndCaptureAsync(
473473
"docker",
474-
$"image inspect --format={{{{.Id}}}} {server}/{image}:latest",
474+
$"image inspect --format={{{{.Id}}}} {server}/{image}",
475475
It.IsAny<string?>(),
476476
It.IsAny<IEnumerable<(string, string)>?>(),
477477
It.IsAny<bool>(),
@@ -491,7 +491,7 @@ public async Task GetCurrentImageDigest_ParsesDigestCorrectly()
491491
public async Task GetLatestImageDigest_ParsesDigestCorrectly()
492492
{
493493
// Arrange
494-
var image = "actions-importer/cli";
494+
var image = "actions-importer/cli:latest";
495495
var server = "ghcr.io";
496496
var manifestResult = @"
497497
{
@@ -554,7 +554,7 @@ public async Task GetLatestImageDigest_ParsesDigestCorrectly()
554554
_processService.Setup(handler =>
555555
handler.RunAndCaptureAsync(
556556
"docker",
557-
$"manifest inspect {server}/{image}:latest",
557+
$"manifest inspect {server}/{image}",
558558
It.IsAny<string?>(),
559559
It.IsAny<IEnumerable<(string, string)>?>(),
560560
It.IsAny<bool>(),

src/ActionsImporter/App.cs

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ public class App
1212
private readonly IProcessService _processService;
1313
private readonly IConfigurationService _configurationService;
1414

15+
public bool IsPrerelease { get; set; }
16+
17+
private string ImageTag => IsPrerelease ? "pre" : "latest";
18+
19+
private string ImageName => $"{ActionsImporterImage}:{ImageTag}";
20+
1521
public App(IDockerService dockerService, IProcessService processService, IConfigurationService configurationService)
1622
{
1723
_dockerService = dockerService;
@@ -37,7 +43,7 @@ public async Task<int> UpdateActionsImporterAsync(string? username = null, strin
3743
await _dockerService.UpdateImageAsync(
3844
ActionsImporterImage,
3945
ActionsImporterContainerRegistry,
40-
"latest",
46+
ImageTag,
4147
username,
4248
password,
4349
passwordStdin
@@ -52,13 +58,14 @@ public async Task<int> ExecuteActionsImporterAsync(string[] args)
5258
await _dockerService.VerifyImagePresentAsync(
5359
ActionsImporterImage,
5460
ActionsImporterContainerRegistry,
55-
"latest"
61+
ImageTag,
62+
IsPrerelease
5663
).ConfigureAwait(false);
5764

5865
await _dockerService.ExecuteCommandAsync(
5966
ActionsImporterImage,
6067
ActionsImporterContainerRegistry,
61-
"latest",
68+
ImageTag,
6269
args.Select(x => x.EscapeIfNeeded()).ToArray()
6370
);
6471
return 0;
@@ -68,7 +75,7 @@ public async Task<int> GetVersionAsync()
6875
{
6976
var (standardOutput, standardError, exitCode) = await _processService.RunAndCaptureAsync("gh", "version");
7077
var ghActionsImporterVersion = await _processService.RunAndCaptureAsync("gh", "extension list");
71-
var actionsImporterVersion = await _processService.RunAndCaptureAsync("docker", $"run --rm {ActionsImporterContainerRegistry}/{ActionsImporterImage}:latest version", throwOnError: false);
78+
var actionsImporterVersion = await _processService.RunAndCaptureAsync("docker", $"run --rm {ActionsImporterContainerRegistry}/{ImageName} version", throwOnError: false);
7279

7380
var formattedGhVersion = standardOutput.Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries).FirstOrDefault();
7481
var formattedGhActionsImporterVersion = ghActionsImporterVersion.standardOutput.Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)
@@ -77,7 +84,7 @@ public async Task<int> GetVersionAsync()
7784

7885
Console.WriteLine(formattedGhVersion);
7986
Console.WriteLine(formattedGhActionsImporterVersion);
80-
Console.WriteLine($"actions-importer/cli\t{formattedActionsImporterVersion}");
87+
Console.WriteLine($"actions-importer/cli:{ImageTag}\t{formattedActionsImporterVersion}");
8188

8289
return 0;
8390
}
@@ -86,8 +93,8 @@ public async Task CheckForUpdatesAsync()
8693
{
8794
try
8895
{
89-
var latestImageDigestTask = _dockerService.GetLatestImageDigestAsync(ActionsImporterImage, ActionsImporterContainerRegistry);
90-
var currentImageDigestTask = _dockerService.GetCurrentImageDigestAsync(ActionsImporterImage, ActionsImporterContainerRegistry);
96+
var latestImageDigestTask = _dockerService.GetLatestImageDigestAsync(ImageName, ActionsImporterContainerRegistry);
97+
var currentImageDigestTask = _dockerService.GetCurrentImageDigestAsync(ImageName, ActionsImporterContainerRegistry);
9198

9299
await Task.WhenAll(latestImageDigestTask, currentImageDigestTask);
93100

src/ActionsImporter/Commands/Common.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@ namespace ActionsImporter.Commands;
66
public static class Common
77
{
88

9+
public static readonly Option<bool> Prerelease = new("--prerelease")
10+
{
11+
Description = "Use prerelease image for GitHub Actions Importer",
12+
IsRequired = false,
13+
};
14+
915
public static Command AppendTransformerOptions(this Command command)
1016
{
1117
ArgumentNullException.ThrowIfNull(command);
@@ -73,6 +79,15 @@ public static Command AppendTransformerOptions(this Command command)
7379
return command;
7480
}
7581

82+
public static Command AppendPrereleaseOption(this Command command)
83+
{
84+
ArgumentNullException.ThrowIfNull(command);
85+
86+
command.AddGlobalOption(Prerelease);
87+
88+
return command;
89+
}
90+
7691
public static Command AppendGeneralOptions(this Command command)
7792
{
7893
ArgumentNullException.ThrowIfNull(command);
@@ -105,6 +120,8 @@ public static Command AppendGeneralOptions(this Command command)
105120
}
106121
);
107122

123+
command.AddGlobalOption(Prerelease);
124+
108125
return command;
109126
}
110127

src/ActionsImporter/Commands/ContainerCommand.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ public abstract class ContainerCommand : BaseCommand
1010

1111
protected ContainerCommand(string[] args)
1212
{
13-
_args = args;
13+
// Don't forward the --prerelease flag to GitHub Actions Importer image
14+
_args = args.Where(arg => !arg.Contains(Common.Prerelease.Name, StringComparison.Ordinal)).ToArray();
1415
}
1516

1617
protected abstract ImmutableArray<Option> Options { get; }

src/ActionsImporter/Commands/Update.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ protected override Command GenerateCommand(App app)
3333
command.AddOption(UsernameOption);
3434
command.AddOption(PasswordOption);
3535
command.AddOption(PasswordStdInOption);
36+
command.AppendPrereleaseOption();
3637

3738
command.Handler = CommandHandler.Create((string? username, string? password, bool passwordStdin) => app.UpdateActionsImporterAsync(username, password, passwordStdin));
3839

src/ActionsImporter/Commands/Version.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ protected override Command GenerateCommand(App app)
1414

1515
var command = base.GenerateCommand(app);
1616

17+
command.AppendPrereleaseOption();
18+
1719
command.Handler = CommandHandler.Create(app.GetVersionAsync);
1820

1921
return command;

src/ActionsImporter/Interfaces/IDockerService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ public interface IDockerService
88

99
Task VerifyDockerRunningAsync();
1010

11-
Task VerifyImagePresentAsync(string image, string server, string version);
11+
Task VerifyImagePresentAsync(string image, string server, string version, bool isPrerelease);
1212

1313
Task<string?> GetLatestImageDigestAsync(string image, string server);
1414

src/ActionsImporter/Program.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@
4343
.CancelOnProcessTermination()
4444
.Build();
4545

46+
47+
app.IsPrerelease = parser.Parse(args).HasOption(Common.Prerelease);
48+
4649
try
4750
{
4851
if (!Array.Exists(args, x => x == "update"))

src/ActionsImporter/Services/DockerService.cs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,10 @@ await _processService.RunAsync(
8484
}
8585
}
8686

87-
public async Task VerifyImagePresentAsync(string image, string server, string version)
87+
public async Task VerifyImagePresentAsync(string image, string server, string version, bool isPrerelease)
8888
{
89+
var imageName = $"{server}/{image}:{version}";
90+
var preReleaseOption = isPrerelease ? " --prerelease" : string.Empty;
8991
try
9092
{
9193
await _processService.RunAsync(
@@ -94,23 +96,24 @@ await _processService.RunAsync(
9496
output: false
9597
);
9698
}
99+
97100
catch (Exception)
98101
{
99-
throw new Exception("Unable to locate GitHub Actions Importer image locally. Please run `gh actions-importer update` to fetch the latest image prior to running this command.");
102+
throw new Exception($"Unable to locate {imageName} image locally. Please run `gh actions-importer update{preReleaseOption}` to fetch the latest image prior to running this command.");
100103
}
101104
}
102105

103106
public async Task<string?> GetLatestImageDigestAsync(string image, string server)
104107
{
105-
var (standardOutput, _, _) = await _processService.RunAndCaptureAsync("docker", $"manifest inspect {server}/{image}:latest");
108+
var (standardOutput, _, _) = await _processService.RunAndCaptureAsync("docker", $"manifest inspect {server}/{image}");
106109
Manifest? manifest = JsonSerializer.Deserialize<Manifest>(standardOutput);
107110

108111
return manifest?.GetDigest();
109112
}
110113

111114
public async Task<string?> GetCurrentImageDigestAsync(string image, string server)
112115
{
113-
var (standardOutput, _, _) = await _processService.RunAndCaptureAsync("docker", $"image inspect --format={{{{.Id}}}} {server}/{image}:latest");
116+
var (standardOutput, _, _) = await _processService.RunAndCaptureAsync("docker", $"image inspect --format={{{{.Id}}}} {server}/{image}");
114117

115118
return standardOutput.Split(":").ElementAtOrDefault(1)?.Trim();
116119
}

0 commit comments

Comments
 (0)