diff --git a/build/_build.csproj b/build/_build.csproj index b178179720..d4a839b8e6 100644 --- a/build/_build.csproj +++ b/build/_build.csproj @@ -24,7 +24,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/source/Calamari.AzureAppService/Calamari.AzureAppService.csproj b/source/Calamari.AzureAppService/Calamari.AzureAppService.csproj index aa124dd30b..1f444dd39b 100644 --- a/source/Calamari.AzureAppService/Calamari.AzureAppService.csproj +++ b/source/Calamari.AzureAppService/Calamari.AzureAppService.csproj @@ -17,7 +17,9 @@ - + + NU1902 + diff --git a/source/Calamari.ConsolidateCalamariPackages.Tests/Calamari.ConsolidateCalamariPackages.Tests.csproj b/source/Calamari.ConsolidateCalamariPackages.Tests/Calamari.ConsolidateCalamariPackages.Tests.csproj index 078fa3263e..a2ff998be7 100644 --- a/source/Calamari.ConsolidateCalamariPackages.Tests/Calamari.ConsolidateCalamariPackages.Tests.csproj +++ b/source/Calamari.ConsolidateCalamariPackages.Tests/Calamari.ConsolidateCalamariPackages.Tests.csproj @@ -15,7 +15,9 @@ - + + NU1902 + diff --git a/source/Calamari.ConsolidateCalamariPackages/Calamari.ConsolidateCalamariPackages.csproj b/source/Calamari.ConsolidateCalamariPackages/Calamari.ConsolidateCalamariPackages.csproj index 7a93745308..11096e249b 100644 --- a/source/Calamari.ConsolidateCalamariPackages/Calamari.ConsolidateCalamariPackages.csproj +++ b/source/Calamari.ConsolidateCalamariPackages/Calamari.ConsolidateCalamariPackages.csproj @@ -19,7 +19,9 @@ - + + NU1902 + diff --git a/source/Calamari.Tests/ArgoCD/Helm/HelmValuesImageReplaceStepVariablesTests.cs b/source/Calamari.Tests/ArgoCD/Helm/HelmValuesImageReplaceStepVariablesTests.cs new file mode 100644 index 0000000000..028ab96656 --- /dev/null +++ b/source/Calamari.Tests/ArgoCD/Helm/HelmValuesImageReplaceStepVariablesTests.cs @@ -0,0 +1,178 @@ +using System; +using System.Collections.Generic; +using Calamari.ArgoCD; +using Calamari.ArgoCD.Conventions; +using Calamari.ArgoCD.Models; +using Calamari.Testing.Helpers; +using FluentAssertions; +using FluentAssertions.Execution; +using NUnit.Framework; + +namespace Calamari.Tests.ArgoCD.Helm; + +public class HelmValuesImageReplaceStepVariablesTests +{ + const string DefaultRegistry = "docker.io"; + readonly InMemoryLog log = new(); + + [Test] + public void UnstructuredValue_UpdatesTag_TracksWithFriendlyName() + { + const string yaml = @" +image: + tag: 1.0 +"; + var replacer = new HelmValuesImageReplaceStepVariables(yaml, DefaultRegistry, log); + var images = new List + { + new(ContainerImageReference.FromReferenceString("nginx:1.27.1", DefaultRegistry), "image.tag") + }; + + var result = replacer.UpdateImages(images); + + using var scope = new AssertionScope(); + result.UpdatedImageReferences.Should().BeEquivalentTo(["nginx:1.27.1"]); + result.UpdatedContents.Should().Contain("tag: 1.27.1"); + } + + [Test] + public void UnstructuredValue_AlreadyAtTarget_TracksWithFriendlyName() + { + const string yaml = @" +image: + tag: 1.27.1 +"; + var replacer = new HelmValuesImageReplaceStepVariables(yaml, DefaultRegistry, log); + var images = new List + { + new(ContainerImageReference.FromReferenceString("nginx:1.27.1", DefaultRegistry), "image.tag") + }; + + var result = replacer.UpdateImages(images); + + using var scope = new AssertionScope(); + result.UpdatedImageReferences.Should().BeEmpty(); + } + + [Test] + public void StructuredValue_UpdatesFullRef() + { + const string yaml = @" +image: + name: nginx:1.0 +"; + var replacer = new HelmValuesImageReplaceStepVariables(yaml, DefaultRegistry, log); + var images = new List + { + new(ContainerImageReference.FromReferenceString("nginx:1.27.1", DefaultRegistry), "image.name") + }; + + var result = replacer.UpdateImages(images); + + using var scope = new AssertionScope(); + result.UpdatedImageReferences.Should().HaveCount(1); + result.UpdatedContents.Should().Contain("name: nginx:1.27.1"); + } + + [Test] + public void StructuredValue_AlreadyAtTarget_TracksWithFriendlyName() + { + const string yaml = @" +image: + name: nginx:1.27.1 +"; + var replacer = new HelmValuesImageReplaceStepVariables(yaml, DefaultRegistry, log); + var images = new List + { + new(ContainerImageReference.FromReferenceString("nginx:1.27.1", DefaultRegistry), "image.name") + }; + + var result = replacer.UpdateImages(images); + + using var scope = new AssertionScope(); + result.UpdatedImageReferences.Should().BeEmpty(); + } + + [Test] + public void TwoImagesWithSameTag_OnlyUpdatesConfiguredPath() + { + const string yaml = @" +nginx: + tag: 1.0 +redis: + tag: 1.0 +"; + + var replacer = new HelmValuesImageReplaceStepVariables(yaml, DefaultRegistry, log); + var images = new List + { + new(ContainerImageReference.FromReferenceString("nginx:1.27.1", DefaultRegistry), "nginx.tag") + }; + + var result = replacer.UpdateImages(images); + + using var scope = new AssertionScope(); + result.UpdatedImageReferences.Should().BeEquivalentTo(["nginx:1.27.1"]); + result.UpdatedContents.Should().Contain($"nginx:{Environment.NewLine} tag: 1.27.1"); + result.UpdatedContents.Should().Contain($"redis:{Environment.NewLine} tag: 1.0"); + } + + [Test] + public void NoHelmReference_SkipsImage() + { + const string yaml = @" +image: + tag: 1.0 +"; + var replacer = new HelmValuesImageReplaceStepVariables(yaml, DefaultRegistry, log); + var images = new List + { + new(ContainerImageReference.FromReferenceString("nginx:1.27.1", DefaultRegistry)) + }; + + var result = replacer.UpdateImages(images); + + using var scope = new AssertionScope(); + result.UpdatedImageReferences.Should().BeEmpty(); + } + + [Test] + public void PathNotFoundInYaml_SkipsImage() + { + const string yaml = @" +image: + tag: 1.0 +"; + var replacer = new HelmValuesImageReplaceStepVariables(yaml, DefaultRegistry, log); + var images = new List + { + new(ContainerImageReference.FromReferenceString("nginx:1.27.1", DefaultRegistry), "nonexistent.path") + }; + + var result = replacer.UpdateImages(images); + + using var scope = new AssertionScope(); + result.UpdatedImageReferences.Should().BeEmpty(); + result.UpdatedContents.Should().Be(yaml); + } + + [Test] + public void StructuredValue_MismatchedImageName_DoesNotUpdate() + { + const string yaml = @" +image: + name: alpine:3.18 +"; + var replacer = new HelmValuesImageReplaceStepVariables(yaml, DefaultRegistry, log); + var images = new List + { + new(ContainerImageReference.FromReferenceString("nginx:1.27.1", DefaultRegistry), "image.name") + }; + + var result = replacer.UpdateImages(images); + + using var scope = new AssertionScope(); + result.UpdatedImageReferences.Should().BeEmpty(); + result.UpdatedContents.Should().Contain("name: alpine:3.18"); + } +} diff --git a/source/Calamari.Tests/Calamari.Tests.csproj b/source/Calamari.Tests/Calamari.Tests.csproj index b121284417..94b43b7483 100644 --- a/source/Calamari.Tests/Calamari.Tests.csproj +++ b/source/Calamari.Tests/Calamari.Tests.csproj @@ -15,7 +15,7 @@ true - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/source/Calamari/ArgoCD/Conventions/UpdateArgoCDAppDeploymentConfig.cs b/source/Calamari/ArgoCD/Conventions/UpdateArgoCDAppDeploymentConfig.cs index 82503f14dc..fccf3c4cc1 100644 --- a/source/Calamari/ArgoCD/Conventions/UpdateArgoCDAppDeploymentConfig.cs +++ b/source/Calamari/ArgoCD/Conventions/UpdateArgoCDAppDeploymentConfig.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Linq; +using Octopus.CoreUtilities.Extensions; namespace Calamari.ArgoCD.Conventions { @@ -18,7 +19,7 @@ public UpdateArgoCDAppDeploymentConfig(GitCommitParameters commitParameters, Lis public bool HasStepBasedHelmValueReferences() { - return ImageReferences.Any(ir => ir.HelmReference is not null) && UseHelmReferenceFromContainer; + return ImageReferences.Any(ir => !ir.HelmReference.IsNullOrEmpty()) && UseHelmReferenceFromContainer; } } } diff --git a/source/Calamari/ArgoCD/HelmValuesImageReplaceStepVariables.cs b/source/Calamari/ArgoCD/HelmValuesImageReplaceStepVariables.cs index 24bd71c1ba..fbb4b0b999 100644 --- a/source/Calamari/ArgoCD/HelmValuesImageReplaceStepVariables.cs +++ b/source/Calamari/ArgoCD/HelmValuesImageReplaceStepVariables.cs @@ -33,13 +33,17 @@ public ImageReplacementResult UpdateImages(IReadOnlyCollection - + + NU1902 +