Skip to content

Comments

fix: preserve leading zeros in SwampVersion calver time component#440

Merged
stack72 merged 1 commit intomainfrom
fix/swamp-version-leading-zeros
Feb 24, 2026
Merged

fix: preserve leading zeros in SwampVersion calver time component#440
stack72 merged 1 commit intomainfrom
fix/swamp-version-leading-zeros

Conversation

@stack72
Copy link
Contributor

@stack72 stack72 commented Feb 24, 2026

Summary

Fixes #439

SwampVersion.create() uses parseInt() to parse calver version segments into integers for comparison. However, toString() was reconstructing the version string from those integers, which strips leading zeros. This is a problem for builds between midnight and ~09:59:59 UTC, where the HHMMSS time component has leading zeros (e.g. 003901).

Example of the bug:

Input:    "20260224.003901.0"
Parsed:   major=20260224, minor=3901, patch=0
Output:   "20260224.3901.0"  ← leading zeros lost
Expected: "20260224.003901.0"

This caused .swamp.yaml version round-tripping to fail — the version written back after parsing didn't match the original, breaking UAT validation for early-morning builds.

Fix

Store the original string segments (rawVersion) alongside the parsed integer values. toString() now returns the preserved raw string instead of reconstructing from integers. The integer fields (major, minor, patch) remain unchanged and continue to be used for compareTo, equals, isNewerThan, and isOlderThan.

This approach preserves exact round-tripping for all version formats:

  • Calver: "20260224.003901.0"toString()"20260224.003901.0"
  • Semver: "1.2.3"toString()"1.2.3"
  • With suffix: "20260224.003901.0-sha.abc123"toString()"20260224.003901.0" (suffix correctly stripped, zeros preserved)

Test plan

  • Added regression test: create("20260224.003901.0").toString() returns "20260224.003901.0"
  • Added regression test: leading zeros preserved when suffix is stripped
  • All 28 existing SwampVersion tests pass (including create("1.2.3").toString() === "1.2.3")
  • Full test suite passes (1877 tests)
  • deno check, deno lint, deno fmt all clean

🤖 Generated with Claude Code

SwampVersion.create() used parseInt() to parse version segments, which
strips leading zeros. For builds between midnight and ~09:59:59, the
HHMMSS time component (e.g. 003901) lost its leading zeros, causing
toString() to return "20260224.3901.0" instead of "20260224.003901.0".

This broke .swamp.yaml version round-tripping and failed UAT validation.

The fix stores the original string segments alongside the parsed integer
values, using the raw strings for toString() while keeping integers for
compareTo/equals. This preserves exact round-tripping for all version
formats (both semver and calver).

Fixes #439

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Summary

This PR correctly fixes the leading zeros issue in SwampVersion calver formatting. The implementation is clean and follows project conventions.

✅ No Blocking Issues

Code Quality Assessment

TypeScript Strict Mode: ✅ Compliant

  • No any types
  • Proper type annotations with readonly modifiers
  • Private constructor maintained for immutability

Code Style (CLAUDE.md): ✅ Compliant

  • Named exports used (export class SwampVersion)
  • AGPLv3 copyright header present
  • Passes linting requirements per PR description

Domain-Driven Design: ✅ Well-designed

  • SwampVersion is correctly implemented as a Value Object
  • The rawVersion field is appropriately private - it's an implementation detail for roundtrip fidelity
  • Comparison operations still use integer values, which is semantically correct since "003901" and "3901" represent the same numeric value
  • Immutability preserved with readonly modifier

Test Coverage: ✅ Good

  • Two regression tests added covering both cases (with and without sha suffix)
  • Tests verify both the string output and numeric parsing
  • Test file properly co-located with source (swamp_version_test.ts)

Security: ✅ No concerns

  • Simple value object change with no security implications

Implementation Notes

The approach of storing rawVersion from regex match groups rather than reconstructing from integers is elegant - it correctly strips the suffix while preserving leading zeros in the version segments. This maintains exact roundtrip fidelity without breaking comparison semantics.

LGTM! 🎉

@stack72 stack72 merged commit b42ede8 into main Feb 24, 2026
4 checks passed
@stack72 stack72 deleted the fix/swamp-version-leading-zeros branch February 24, 2026 01:12
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.

bug: SwampVersion drops leading zeros from calver time component

1 participant