From c819290aa9df84214ad7bd0e58644bf06018c90b Mon Sep 17 00:00:00 2001 From: Eddy Moulton <8491021+eddymoulton@users.noreply.github.com> Date: Tue, 2 Jun 2026 23:24:33 +0000 Subject: [PATCH 1/2] Block SSH on windows (#1978) --- .../AuthenticatingRepositoryFactoryTests.cs | 4 ++++ .../ArgoCD/Git/RepositoryFactoryTests.cs | 2 ++ .../Calamari/ArgoCD/Git/RepositoryFactory.cs | 4 +++- source/Calamari/ArgoCD/Git/WindowsSshKeys.cs | 20 +++++++++++++++++++ 4 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 source/Calamari/ArgoCD/Git/WindowsSshKeys.cs diff --git a/source/Calamari.Tests/ArgoCD/Git/AuthenticatingRepositoryFactoryTests.cs b/source/Calamari.Tests/ArgoCD/Git/AuthenticatingRepositoryFactoryTests.cs index 3d4593717..5d559298f 100644 --- a/source/Calamari.Tests/ArgoCD/Git/AuthenticatingRepositoryFactoryTests.cs +++ b/source/Calamari.Tests/ArgoCD/Git/AuthenticatingRepositoryFactoryTests.cs @@ -81,6 +81,8 @@ public void AnonymousCloneWhenNoCredentialsMatch() public class SshUrlTests : AuthenticatingRepositoryFactoryTestBase { [Test] + // SSH not currently functional on Windows + [Category(TestCategory.CompatibleOS.OnlyNixOrMac)] public void SshCredentialBranch_IsSelectedAndDispatchesSshKeyGitConnection() { // Use an ssh:// URL so the new strict validation allows it, and mock the factory @@ -108,6 +110,8 @@ public void HttpsCredentialTakesPriorityOverSshWhenBothMatchAnSshUrl() } [Test] + // SSH not currently functional on Windows + [Category(TestCategory.CompatibleOS.OnlyNixOrMac)] public void KnownHostsFromDtoAreCarriedOntoSshKeyGitConnection() { const string sshUrl = "ssh://git@github.com/org/repo.git"; diff --git a/source/Calamari.Tests/ArgoCD/Git/RepositoryFactoryTests.cs b/source/Calamari.Tests/ArgoCD/Git/RepositoryFactoryTests.cs index d9103a546..f52231a15 100644 --- a/source/Calamari.Tests/ArgoCD/Git/RepositoryFactoryTests.cs +++ b/source/Calamari.Tests/ArgoCD/Git/RepositoryFactoryTests.cs @@ -96,6 +96,8 @@ public void CanCloneAnExistingRepositoryAtHEADAndAssociatedFiles() } [Test] + // SSH not currently functional on Windows + [Category(TestCategory.CompatibleOS.OnlyNixOrMac)] public void CloningSshKeyGitConnectionDoesNotResolveAPullRequestClientAndLogsVerboseMessage() { var filename = "sshTest.txt"; diff --git a/source/Calamari/ArgoCD/Git/RepositoryFactory.cs b/source/Calamari/ArgoCD/Git/RepositoryFactory.cs index 6b70ec16b..771c9b83b 100644 --- a/source/Calamari/ArgoCD/Git/RepositoryFactory.cs +++ b/source/Calamari/ArgoCD/Git/RepositoryFactory.cs @@ -1,10 +1,10 @@ using System; using System.IO; using System.Linq; -using System.Text; using System.Threading; using Calamari.ArgoCD.Git.PullRequests; using Calamari.Common.Commands; +using Calamari.Common.Plumbing; using Calamari.Common.Plumbing.Extensions; using Calamari.Common.Plumbing.FileSystem; using Calamari.Common.Plumbing.Logging; @@ -48,6 +48,8 @@ public RepositoryFactory(ILog log, ICalamariFileSystem fileSystem, string reposi public RepositoryWrapper CloneRepository(string repositoryName, IGitConnection gitConnection) { + WindowsSshKeys.AssertSupported(gitConnection); + var repositoryPath = Path.Combine(repositoryParentDirectory, repositoryName); fileSystem.CreateDirectory(repositoryPath); diff --git a/source/Calamari/ArgoCD/Git/WindowsSshKeys.cs b/source/Calamari/ArgoCD/Git/WindowsSshKeys.cs new file mode 100644 index 000000000..e84bb5208 --- /dev/null +++ b/source/Calamari/ArgoCD/Git/WindowsSshKeys.cs @@ -0,0 +1,20 @@ +using System; +using Calamari.Common.Plumbing; +using NuGet.Commands; + +namespace Calamari.ArgoCD.Git; + +// Our fork LibGit2Sharp uses WinCNG for it's SSH support, and WinCNG does not support some keys. +// This first implementation blocks on all as we want to get the feature out for Linux first and +// we'll come back to attempt to handle it more gracefully at a later date. +public class WindowsSshKeys +{ + public static void AssertSupported(IGitConnection? connection) + { + if (!CalamariEnvironment.IsRunningOnWindows) return; + if (connection is not SshKeyGitConnection) return; + + throw new CommandException( + "SSH credentials are not currently supported for Git operations running on Windows. Use HTTPS credentials (username + password or PAT) instead or run the deployment on a Linux worker."); + } +} \ No newline at end of file From 0f17395ac034e1476ecd11915561ea5de0c8ea7d Mon Sep 17 00:00:00 2001 From: Frank Lin Date: Wed, 3 Jun 2026 11:20:26 +1000 Subject: [PATCH 2/2] Move Argo file changes stuff into Calamari contracts (#1914) --- source/Calamari.Contracts/ArgoCD/FileHash.cs | 5 +++ .../ArgoCD/FileJsonPatch.cs | 5 +++ .../ArgoCD/ServiceMessages.cs | 18 ++++++++++ .../ArgoCD/SourceFileChanges.cs | 10 ++++++ .../ArgoCD/ArgoCDFilesUpdatedReporterTests.cs | 1 + .../ArgoCD/ArgoCDFilesUpdatedReporter.cs | 36 +++++++++---------- .../CopyTemplatesSourceUpdater.cs | 1 + .../ManifestUpdateResult.cs | 1 + .../ArgoCD/Conventions/SourceUpdateResult.cs | 1 + .../UpdateImageTag/AbstractHelmUpdater.cs | 1 + .../Conventions/UpdateImageTag/BaseUpdater.cs | 1 + .../UpdateImageTag/FileUpdateResult.cs | 1 + .../ArgoCD/ProcessApplicationResult.cs | 5 +-- .../Calamari/Kubernetes/SpecialVariables.cs | 12 ------- 14 files changed, 64 insertions(+), 34 deletions(-) create mode 100644 source/Calamari.Contracts/ArgoCD/FileHash.cs create mode 100644 source/Calamari.Contracts/ArgoCD/FileJsonPatch.cs create mode 100644 source/Calamari.Contracts/ArgoCD/ServiceMessages.cs create mode 100644 source/Calamari.Contracts/ArgoCD/SourceFileChanges.cs diff --git a/source/Calamari.Contracts/ArgoCD/FileHash.cs b/source/Calamari.Contracts/ArgoCD/FileHash.cs new file mode 100644 index 000000000..3d37e4f5e --- /dev/null +++ b/source/Calamari.Contracts/ArgoCD/FileHash.cs @@ -0,0 +1,5 @@ +using System; + +namespace Octopus.Calamari.Contracts.ArgoCD; + +public record FileHash(string FilePath, string Hash); \ No newline at end of file diff --git a/source/Calamari.Contracts/ArgoCD/FileJsonPatch.cs b/source/Calamari.Contracts/ArgoCD/FileJsonPatch.cs new file mode 100644 index 000000000..1b5e41848 --- /dev/null +++ b/source/Calamari.Contracts/ArgoCD/FileJsonPatch.cs @@ -0,0 +1,5 @@ +using System; + +namespace Octopus.Calamari.Contracts.ArgoCD; + +public record FileJsonPatch(string FilePath, string JsonPatch); \ No newline at end of file diff --git a/source/Calamari.Contracts/ArgoCD/ServiceMessages.cs b/source/Calamari.Contracts/ArgoCD/ServiceMessages.cs new file mode 100644 index 000000000..794a4f2d4 --- /dev/null +++ b/source/Calamari.Contracts/ArgoCD/ServiceMessages.cs @@ -0,0 +1,18 @@ +using System; + +namespace Octopus.Calamari.Contracts.ArgoCD; + +public static class ServiceMessages +{ + public static class ArgoCDFilesUpdated + { + public const string Name = "argocd-files-updated"; + + public static class Attributes + { + public const string GatewayId = "gatewayId"; + public const string ApplicationName = "applicationName"; + public const string Sources = "sources"; + } + } +} \ No newline at end of file diff --git a/source/Calamari.Contracts/ArgoCD/SourceFileChanges.cs b/source/Calamari.Contracts/ArgoCD/SourceFileChanges.cs new file mode 100644 index 000000000..21adb0062 --- /dev/null +++ b/source/Calamari.Contracts/ArgoCD/SourceFileChanges.cs @@ -0,0 +1,10 @@ +using System; + +namespace Octopus.Calamari.Contracts.ArgoCD; + +public record SourceFileChanges( + string? CommitSha, + DateTimeOffset? CommitTimestamp, + int SourceIndex, + List ReplacedFiles, + List PatchedFiles); \ No newline at end of file diff --git a/source/Calamari.Tests/ArgoCD/ArgoCDFilesUpdatedReporterTests.cs b/source/Calamari.Tests/ArgoCD/ArgoCDFilesUpdatedReporterTests.cs index 5805e1bab..4cc5d0ba3 100644 --- a/source/Calamari.Tests/ArgoCD/ArgoCDFilesUpdatedReporterTests.cs +++ b/source/Calamari.Tests/ArgoCD/ArgoCDFilesUpdatedReporterTests.cs @@ -8,6 +8,7 @@ using Calamari.Testing.Helpers; using FluentAssertions; using NUnit.Framework; +using Octopus.Calamari.Contracts.ArgoCD; namespace Calamari.Tests.ArgoCD { diff --git a/source/Calamari/ArgoCD/ArgoCDFilesUpdatedReporter.cs b/source/Calamari/ArgoCD/ArgoCDFilesUpdatedReporter.cs index ebf06cdc9..bf9a513b4 100644 --- a/source/Calamari/ArgoCD/ArgoCDFilesUpdatedReporter.cs +++ b/source/Calamari/ArgoCD/ArgoCDFilesUpdatedReporter.cs @@ -7,7 +7,8 @@ using Calamari.Common.Plumbing.Logging; using Calamari.Common.Plumbing.ServiceMessages; using Calamari.Kubernetes; -using ArgoCDFilesUpdatedAttributes = Calamari.Kubernetes.SpecialVariables.ServiceMessages.ArgoCDFilesUpdated.Attributes; +using Octopus.Calamari.Contracts.ArgoCD; +using ArgoCDFilesUpdatedAttributes = Octopus.Calamari.Contracts.ArgoCD.ServiceMessages.ArgoCDFilesUpdated.Attributes; namespace Calamari.ArgoCD { @@ -34,33 +35,32 @@ public void ReportFilesUpdated(GitCommitParameters gitCommitParameters, IReadOnl { { ArgoCDFilesUpdatedAttributes.GatewayId, appResult.GatewayId }, { ArgoCDFilesUpdatedAttributes.ApplicationName, appResult.ApplicationName.Value }, - { ArgoCDFilesUpdatedAttributes.Sources, JsonSerializer.Serialize(ConvertPathsToPosix(appResult.TrackedSourceDetails)) } + { ArgoCDFilesUpdatedAttributes.Sources, JsonSerializer.Serialize(appResult.TrackedSourceDetails.Select(MapSource).ToList()) } }; var message = new ServiceMessage( - SpecialVariables.ServiceMessages.ArgoCDFilesUpdated.Name, + ServiceMessages.ArgoCDFilesUpdated.Name, parameters); log.WriteServiceMessage(message); } } - List ConvertPathsToPosix(List inputs) + static SourceFileChanges MapSource(TrackedSourceDetail trackedSourceDetail) { - return inputs.Select(usd => usd with - { - ReplacedFiles = usd.ReplacedFiles.Select(rf => rf with - { - FilePath = rf.FilePath.EnsurePosixDirectorySeparator() - }) - .ToList(), - PatchedFiles = usd.PatchedFiles.Select(pf => pf with - { - FilePath = pf.FilePath.EnsurePosixDirectorySeparator() - }) - .ToList() - }) - .ToList(); + return new SourceFileChanges( + trackedSourceDetail.CommitSha, + trackedSourceDetail.CommitTimestamp, + trackedSourceDetail.SourceIndex, + trackedSourceDetail.ReplacedFiles.Select(f => f with + { + FilePath = f.FilePath.EnsurePosixDirectorySeparator() + }).ToList(), + trackedSourceDetail.PatchedFiles.Select(f => f with + { + FilePath = f.FilePath.EnsurePosixDirectorySeparator() + }).ToList() + ); } } } \ No newline at end of file diff --git a/source/Calamari/ArgoCD/Conventions/ManifestTemplating/CopyTemplatesSourceUpdater.cs b/source/Calamari/ArgoCD/Conventions/ManifestTemplating/CopyTemplatesSourceUpdater.cs index f061a422f..42c876a2a 100644 --- a/source/Calamari/ArgoCD/Conventions/ManifestTemplating/CopyTemplatesSourceUpdater.cs +++ b/source/Calamari/ArgoCD/Conventions/ManifestTemplating/CopyTemplatesSourceUpdater.cs @@ -6,6 +6,7 @@ using Calamari.Common.Plumbing.Extensions; using Calamari.Common.Plumbing.FileSystem; using Calamari.Common.Plumbing.Logging; +using Octopus.Calamari.Contracts.ArgoCD; using Octopus.CoreUtilities.Extensions; namespace Calamari.ArgoCD.Conventions.ManifestTemplating; diff --git a/source/Calamari/ArgoCD/Conventions/ManifestTemplating/ManifestUpdateResult.cs b/source/Calamari/ArgoCD/Conventions/ManifestTemplating/ManifestUpdateResult.cs index e9c05e588..508436fd5 100644 --- a/source/Calamari/ArgoCD/Conventions/ManifestTemplating/ManifestUpdateResult.cs +++ b/source/Calamari/ArgoCD/Conventions/ManifestTemplating/ManifestUpdateResult.cs @@ -1,6 +1,7 @@ #nullable enable using System; using System.Collections.Generic; +using Octopus.Calamari.Contracts.ArgoCD; namespace Calamari.ArgoCD.Conventions.ManifestTemplating; diff --git a/source/Calamari/ArgoCD/Conventions/SourceUpdateResult.cs b/source/Calamari/ArgoCD/Conventions/SourceUpdateResult.cs index 89667949a..06b38eff9 100644 --- a/source/Calamari/ArgoCD/Conventions/SourceUpdateResult.cs +++ b/source/Calamari/ArgoCD/Conventions/SourceUpdateResult.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using Calamari.ArgoCD.Git; +using Octopus.Calamari.Contracts.ArgoCD; namespace Calamari.ArgoCD.Conventions; diff --git a/source/Calamari/ArgoCD/Conventions/UpdateImageTag/AbstractHelmUpdater.cs b/source/Calamari/ArgoCD/Conventions/UpdateImageTag/AbstractHelmUpdater.cs index c19af78be..dfca12fec 100644 --- a/source/Calamari/ArgoCD/Conventions/UpdateImageTag/AbstractHelmUpdater.cs +++ b/source/Calamari/ArgoCD/Conventions/UpdateImageTag/AbstractHelmUpdater.cs @@ -9,6 +9,7 @@ using Calamari.Common.Plumbing.FileSystem; using Calamari.Common.Plumbing.Logging; using Calamari.Kubernetes.Patching.JsonPatch; +using Octopus.Calamari.Contracts.ArgoCD; namespace Calamari.ArgoCD.Conventions.UpdateImageTag; diff --git a/source/Calamari/ArgoCD/Conventions/UpdateImageTag/BaseUpdater.cs b/source/Calamari/ArgoCD/Conventions/UpdateImageTag/BaseUpdater.cs index 0ccdb023f..d62143780 100644 --- a/source/Calamari/ArgoCD/Conventions/UpdateImageTag/BaseUpdater.cs +++ b/source/Calamari/ArgoCD/Conventions/UpdateImageTag/BaseUpdater.cs @@ -11,6 +11,7 @@ using Calamari.Common.Plumbing.Logging; using Calamari.Kubernetes.Patching; using Calamari.Kubernetes.Patching.JsonPatch; +using Octopus.Calamari.Contracts.ArgoCD; using YamlDotNet.RepresentationModel; namespace Calamari.ArgoCD.Conventions.UpdateImageTag; diff --git a/source/Calamari/ArgoCD/Conventions/UpdateImageTag/FileUpdateResult.cs b/source/Calamari/ArgoCD/Conventions/UpdateImageTag/FileUpdateResult.cs index 400265eff..80a49f09f 100644 --- a/source/Calamari/ArgoCD/Conventions/UpdateImageTag/FileUpdateResult.cs +++ b/source/Calamari/ArgoCD/Conventions/UpdateImageTag/FileUpdateResult.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using Octopus.Calamari.Contracts.ArgoCD; namespace Calamari.ArgoCD.Conventions.UpdateImageTag; diff --git a/source/Calamari/ArgoCD/ProcessApplicationResult.cs b/source/Calamari/ArgoCD/ProcessApplicationResult.cs index abad5c14e..f185e88f5 100644 --- a/source/Calamari/ArgoCD/ProcessApplicationResult.cs +++ b/source/Calamari/ArgoCD/ProcessApplicationResult.cs @@ -3,13 +3,10 @@ using System.Collections.Generic; using System.Linq; using Calamari.ArgoCD.Models; +using Octopus.Calamari.Contracts.ArgoCD; namespace Calamari.ArgoCD { - public record FileHash(string FilePath, string Hash); - - public record FileJsonPatch(string FilePath, string JsonPatch); - public record TrackedSourceDetail( string? CommitSha, DateTimeOffset? CommitTimestamp, diff --git a/source/Calamari/Kubernetes/SpecialVariables.cs b/source/Calamari/Kubernetes/SpecialVariables.cs index 86cddcf04..78ebf3022 100644 --- a/source/Calamari/Kubernetes/SpecialVariables.cs +++ b/source/Calamari/Kubernetes/SpecialVariables.cs @@ -174,18 +174,6 @@ public static class ManifestApplied public const string ManifestAttribute = "manifest"; public const string NamespaceAttribute = "ns"; } - - public static class ArgoCDFilesUpdated - { - public const string Name = "argocd-files-updated"; - - public static class Attributes - { - public const string GatewayId = "gatewayId"; - public const string ApplicationName = "applicationName"; - public const string Sources = "sources"; - } - } } } } \ No newline at end of file