Skip to content

Use file creation time for GetNearestPackages when version is non-SemVer#1973

Open
NickJosevski wants to merge 4 commits into
mainfrom
nj/non-semver-package-cache-ordering
Open

Use file creation time for GetNearestPackages when version is non-SemVer#1973
NickJosevski wants to merge 4 commits into
mainfrom
nj/non-semver-package-cache-ordering

Conversation

@NickJosevski
Copy link
Copy Markdown
Contributor

Summary

Follow-up to OctopusDeploy/OctopusDeploy#43750 which adds a MostRecentlyPublished ordering strategy for Channel Package Version Rules.

PackageStore.GetNearestPackages is called when a package is not already cached on a Tentacle. It finds up to 5 locally cached packages to offer as delta bases for compressed transfer.

Before: The method filtered with version.CompareTo(target) <= 0 and ordered by version descending — both operations are unreliable for non-SemVer version strings (Docker tags, build numbers, date-stamps). Calamari would find no useful delta candidates, causing the full package to be downloaded instead of a delta.

After: When version.Format != VersionFormat.Semver, the method skips the version filter and instead orders all cached packages for the same package ID by file creation time descending. The most recently cached package is the best delta candidate.

SemVer behaviour is unchanged.

Changes

  • Calamari.Shared/Integration/Certificates/FileSystem/PackageStore.cs — branch on version.Format in GetNearestPackages
  • Calamari.Tests/Fixtures/Integration/FileSystem/PackageStoreFixture.cs — new test with Docker tag versions and deterministic creation times

Test plan

  • Existing FiltersPackagesWithHigherVersion, OldFormatsAreIgnored, IgnoresInvalidFiles tests unchanged
  • New NonSemVerVersionsReturnPackagesOrderedByCreationTime test verifies creation-time ordering for Docker tags
  • dotnet build clean

NickJosevski and others added 3 commits May 28, 2026 22:16
For SemVer versions the existing behaviour is unchanged: filter to versions
<= target and order by version descending so the closest lower version is
offered as the delta base.

For non-SemVer versions (Docker tags, build numbers, date-stamps) the
SemVer comparison is unreliable and may return no candidates or the wrong
ones. Fall back to ordering all cached packages for the same package ID by
file creation time descending, so the most recently cached package is
offered as the delta candidate.

This is a performance-only change — if no suitable delta candidate is found
Calamari already falls back to downloading the full package. The fix improves
delta compression quality for deployments using the MostRecentlyPublished
channel ordering strategy (OctopusDeploy/OctopusDeploy#43750).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…System

File.SetCreationTimeUtc is a no-op on Linux — the test was using it to set
deterministic ordering which caused failures across all Linux CI targets.

GetLastWriteTime is fully settable on all platforms via File.SetLastWriteTimeUtc.
Added GetLastWriteTime to IFile, StandardFile, ICalamariFileSystem,
CalamariPhysicalFileSystem, and TestFile. Updated PackageStore to use
fileSystem.GetLastWriteTime and the test to use File.SetLastWriteTimeUtc.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… versions

The previous test used PackageBuilder.BuildSamplePackage which runs
`dotnet pack /p:Version=<tag>` — but dotnet pack rejects non-SemVer
versions like 'feature-login-100' and 'main-9999', causing the test to
fail across all Linux/Windows/macOS Calamari netcore test runners.

Switched to using .zip extension with dummy file content. The PackageStore
only reads file metadata (hash, size, last-write time) for delta candidate
selection, so the file content is irrelevant. Using .zip also avoids
PackageName.FromFile attempting to parse NuGet metadata when the extension
is .nupkg.

Test passes locally now. Verified with:
  dotnet test --filter FullyQualifiedName~PackageStoreFixture

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@NickJosevski NickJosevski force-pushed the nj/non-semver-package-cache-ordering branch from 1d97b6a to f60f1d3 Compare May 29, 2026 00:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant