Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
9bfea2d
extracting helm-yaml-path from package variable, but is unused
rain-on Feb 16, 2026
d044ce6
yay - got first test passing
rain-on Feb 17, 2026
cc0bd84
sort out containerImageReferenceTest
rain-on Feb 17, 2026
b6861d4
Merge remote-tracking branch 'origin/main' into tmm/new_helm_approach
rain-on Feb 18, 2026
27fc491
yeah that
rain-on Feb 18, 2026
7623779
gotta smallenate this
rain-on Feb 18, 2026
37f4092
clean it a little
rain-on Feb 18, 2026
2430d3f
what?
rain-on Feb 18, 2026
d56544d
no idea
rain-on Feb 18, 2026
9cb28ec
splitting it out
rain-on Feb 18, 2026
45bc92d
is this a better solution?
rain-on Feb 19, 2026
830ed42
refactor is working
rain-on Feb 19, 2026
b3b520e
basic test in for helm source
rain-on Feb 19, 2026
8e10f29
Merge remote-tracking branch 'origin/main' into tmm/new_helm_approach
rain-on Feb 20, 2026
f7ed775
reformat
rain-on Feb 23, 2026
f195394
Merge remote-tracking branch 'origin/main' into tmm/new_helm_approach
rain-on Feb 23, 2026
9e23d97
Merge remote-tracking branch 'origin/main' into tmm/new_helm_approach
rain-on Feb 24, 2026
b007979
unrequired change removed
rain-on Feb 24, 2026
9b716bf
remove the unused field
rain-on Feb 24, 2026
be04614
trying to reduce footprint of change
rain-on Feb 24, 2026
b3a09ac
trying to shrink it
rain-on Feb 24, 2026
5e08a82
remove changes to valueseditor
rain-on Feb 24, 2026
1eb66fe
tidying up
rain-on Feb 24, 2026
7d9aaca
don't think I can clean better
rain-on Feb 24, 2026
b4682b3
after personal review
rain-on Feb 24, 2026
914037c
minor renames
rain-on Feb 24, 2026
5776f62
factor in the featuretoggle
rain-on Feb 24, 2026
219cc69
fixup the feature-toggle stuffs
rain-on Feb 24, 2026
2476557
fix up the feature toggle in tests
rain-on Feb 24, 2026
940b2b7
no idea
rain-on Feb 25, 2026
1bc9315
fixed issues when actually running
rain-on Feb 25, 2026
5d09206
move logging
rain-on Feb 25, 2026
4a64470
reduce to verbose
rain-on Feb 25, 2026
2f089c2
include the featuretoggle in the tests
rain-on Feb 25, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ public static class OctopusFeatureToggles
public static class KnownSlugs
{
public const string AnsiColorsInTaskLogFeatureToggle = "ansi-colors";
public const string ArgoCDHelmReplacePathFromContainerReferenceFeatureToggle = "argo-cd-helm-replace-path-from-container-reference";
};

public static readonly OctopusFeatureToggle AnsiColorsInTaskLogFeatureToggle = new OctopusFeatureToggle(KnownSlugs.AnsiColorsInTaskLogFeatureToggle);
public static readonly OctopusFeatureToggle AnsiColorsInTaskLogFeatureToggle = new(KnownSlugs.AnsiColorsInTaskLogFeatureToggle);
public static readonly OctopusFeatureToggle ArgoCDHelmReplacePathFromContainerReferenceFeatureToggle = new(KnownSlugs.ArgoCDHelmReplacePathFromContainerReferenceFeatureToggle);

public class OctopusFeatureToggle
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public static class PackageVariables

public static string IndexedPackagePurpose(string packageReferenceName) => $"Octopus.Action.Package[{packageReferenceName}].Purpose";

public static string HelmValueYamlPath(string packageReferenceName) => $"Octopus.Action.Package[{packageReferenceName}].HelmReplacementPath";
public static string HelmReplacementPath(string packageReferenceName) => $"Octopus.Action.Package[{packageReferenceName}].HelmReplacementPath";

public static string IndexedOriginalPath(string packageReferenceName)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using Calamari.ArgoCD.Git.GitVendorApiAdapters;
using Calamari.ArgoCD.Models;
using Calamari.Common.Commands;
using Calamari.Common.FeatureToggles;
using Calamari.Common.Plumbing.Deployment;
using Calamari.Common.Plumbing.FileSystem;
using Calamari.Common.Plumbing.Variables;
Expand Down Expand Up @@ -1348,6 +1349,7 @@ public void DirectorySource_ImageMatches_ReportsDeploymentWithNonEmptyCommitSha(
[PackageVariables.IndexedPackagePurpose("nginx")] = "DockerImageReference",
[PackageVariables.IndexedImage("alpine")] = "alpine:2.2",
[PackageVariables.IndexedPackagePurpose("alpine")] = "DockerImageReference",
[KnownVariables.EnabledFeatureToggles] = OctopusFeatureToggles.KnownSlugs.ArgoCDHelmReplacePathFromContainerReferenceFeatureToggle,
};

//Act
Expand Down Expand Up @@ -1382,6 +1384,171 @@ public void DirectorySource_ImageMatches_ReportsDeploymentWithNonEmptyCommitSha(
]);
}

[Test]
public void CanUpdateRefSourceUsingStepBasedVariables()
{
// Arrange
var updater = CreateConvention();
var variables = new CalamariVariables
{
[PackageVariables.IndexedImage("nginx")] = "index.docker.io/nginx:1.27.1",
[PackageVariables.IndexedPackagePurpose("nginx")] = "DockerImageReference",
[PackageVariables.HelmReplacementPath("nginx")] = "image.nginx", //NOTE: no .Values to start, and no leading .
[ProjectVariables.Slug] = ProjectSlug,
[DeploymentEnvironment.Slug] = EnvironmentSlug,
[KnownVariables.EnabledFeatureToggles] = OctopusFeatureToggles.KnownSlugs.ArgoCDHelmReplacePathFromContainerReferenceFeatureToggle,
};
var runningDeployment = new RunningDeployment(null, variables);
runningDeployment.CurrentDirectoryProvider = DeploymentWorkingDirectory.StagingDirectory;
runningDeployment.StagingDirectory = tempDirectory;


var existingYamlFile = "otherRepoPath/values.yaml";
var filesInRepo = new (string, string)[]
{
(
existingYamlFile,
@"
image:
nginx: index.docker.io/nginx:1.0
containerPort: 8080
service:
type: LoadBalancer
"
)
};
originRepo.AddFilesToBranch(argoCDBranchName, filesInRepo);

var argoCDAppWithHelmSource = new ArgoCDApplicationBuilder()
.WithName("App1")
.WithAnnotations(new Dictionary<string, string>()
{
[ArgoCDConstants.Annotations.OctopusProjectAnnotationKey(new ApplicationSourceName("ref-source"))] = ProjectSlug,
[ArgoCDConstants.Annotations.OctopusEnvironmentAnnotationKey(new ApplicationSourceName("ref-source"))] = EnvironmentSlug,
})
.WithSource(new ApplicationSource
{
OriginalRepoUrl = "https://github.com/org/repo",
Path = "",
TargetRevision = ArgoCDBranchFriendlyName,
Helm = new HelmConfig
{
ValueFiles = new List<string>()
{
"$values/otherRepoPath/values.yaml"
}
},
Name = "helm-source",
},
SourceTypeConstants.Helm)
.WithSource(new ApplicationSource
{
Name = "ref-source",
Ref = "values",
TargetRevision = ArgoCDBranchFriendlyName,
OriginalRepoUrl = OriginPath,
},
SourceTypeConstants.Directory)
.Build();

argoCdApplicationManifestParser.ParseManifest(Arg.Any<string>())
.Returns(argoCDAppWithHelmSource);
// Act
updater.Install(runningDeployment);

//Assert
const string updatedYamlContent =
@"
image:
nginx: index.docker.io/nginx:1.27.1
containerPort: 8080
service:
type: LoadBalancer
";

var clonedRepoPath = RepositoryHelpers.CloneOrigin(tempDirectory, OriginPath, argoCDBranchName);
AssertFileContents(clonedRepoPath, existingYamlFile, updatedYamlContent);
}


[Test]
public void CanUpdateHelmSourceUsingStepBasedVariables()
{
// Arrange
var updater = CreateConvention();
var variables = new CalamariVariables
{
[PackageVariables.IndexedImage("nginx")] = "docker.io/nginx:1.27.1", // NOTE the lack of "index"
[PackageVariables.IndexedPackagePurpose("nginx")] = "DockerImageReference",
[PackageVariables.HelmReplacementPath("nginx")] = "image.nginx", //NOTE: no .Values to start, and no leading .
[ProjectVariables.Slug] = ProjectSlug,
[DeploymentEnvironment.Slug] = EnvironmentSlug,
[KnownVariables.EnabledFeatureToggles] = OctopusFeatureToggles.KnownSlugs.ArgoCDHelmReplacePathFromContainerReferenceFeatureToggle,
};
var runningDeployment = new RunningDeployment(null, variables);
runningDeployment.CurrentDirectoryProvider = DeploymentWorkingDirectory.StagingDirectory;
runningDeployment.StagingDirectory = tempDirectory;


var existingYamlFile = "subFolder/values.yaml";
var filesInRepo = new (string, string)[]
{
(
existingYamlFile,
@"
image:
nginx: index.docker.io/nginx:1.0
containerPort: 8080
service:
type: LoadBalancer
"
)
};
originRepo.AddFilesToBranch(argoCDBranchName, filesInRepo);

var argoCDAppWithHelmSource = new ArgoCDApplicationBuilder()
.WithName("App1")
.WithAnnotations(new Dictionary<string, string>()
{
[ArgoCDConstants.Annotations.OctopusProjectAnnotationKey(new ApplicationSourceName("helm-source"))] = ProjectSlug,
[ArgoCDConstants.Annotations.OctopusEnvironmentAnnotationKey(new ApplicationSourceName("helm-source"))] = EnvironmentSlug,
})
.WithSource(new ApplicationSource
{
TargetRevision = ArgoCDBranchFriendlyName,
OriginalRepoUrl = OriginPath,
Path = "",
Helm = new HelmConfig
{
ValueFiles = new List<string>()
{
"subFolder/values.yaml"
}
},
Name = "helm-source",
},
SourceTypeConstants.Helm)
.Build();

argoCdApplicationManifestParser.ParseManifest(Arg.Any<string>())
.Returns(argoCDAppWithHelmSource);
// Act
updater.Install(runningDeployment);

//Assert
const string updatedYamlContent =
@"
image:
nginx: index.docker.io/nginx:1.27.1
containerPort: 8080
service:
type: LoadBalancer
";

var clonedRepoPath = RepositoryHelpers.CloneOrigin(tempDirectory, OriginPath, argoCDBranchName);
AssertFileContents(clonedRepoPath, existingYamlFile, updatedYamlContent);
}

void AssertFileContents(string clonedRepoPath, string relativeFilePath, string expectedContent)
{
var absolutePath = Path.Combine(clonedRepoPath, relativeFilePath);
Expand Down Expand Up @@ -1411,4 +1578,4 @@ void AssertOutputVariables(bool updated = true, string matchingApplicationTotalS
}
}
}
}
}
4 changes: 2 additions & 2 deletions source/Calamari/ArgoCD/Conventions/DeploymentConfigFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ public UpdateArgoCDAppDeploymentConfig CreateUpdateImageConfig(RunningDeployment
var commitParameters = CommitParameters(deployment);
var packageHelmReference = deployment.Variables.GetContainerPackages().Select(p => new ContainerImageReferenceAndHelmReference(ContainerImageReference.FromReferenceString(p.PackageName),
p.HelmReference)).ToList();

return new UpdateArgoCDAppDeploymentConfig(commitParameters, packageHelmReference);
var useHelmReferenceFromContainer = OctopusFeatureToggles.ArgoCDHelmReplacePathFromContainerReferenceFeatureToggle.IsEnabled(deployment.Variables);
return new UpdateArgoCDAppDeploymentConfig(commitParameters, packageHelmReference, useHelmReferenceFromContainer);
}

bool RequiresPullRequest(RunningDeployment deployment)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
using System.Collections.Generic;
using Calamari.ArgoCD.Models;
using System.Linq;

namespace Calamari.ArgoCD.Conventions
{
public class UpdateArgoCDAppDeploymentConfig
{
public GitCommitParameters CommitParameters { get; }
public List<ContainerImageReferenceAndHelmReference> ImageReferences { get; }
public bool UseHelmReferenceFromContainer { get; }

public UpdateArgoCDAppDeploymentConfig(GitCommitParameters commitParameters, List<ContainerImageReferenceAndHelmReference> imageReferences)
public UpdateArgoCDAppDeploymentConfig(GitCommitParameters commitParameters, List<ContainerImageReferenceAndHelmReference> imageReferences, bool useHelmReferenceFromContainer)
{
CommitParameters = commitParameters;
ImageReferences = imageReferences;
UseHelmReferenceFromContainer = useHelmReferenceFromContainer;
}

public bool HasStepBasedHelmValueReferences()
{
return ImageReferences.Any(ir => ir.HelmReference is not null) && UseHelmReferenceFromContainer;
}
}
}
Loading