# How Dewy Handles Versioning for Deployments: SemVer, CalVer, and Blue/Green Support

> Discover how Dewy manages deployment versioning with SemVer, CalVer, and blue/green strategies. Seamlessly parse and compare versions for robust deployments.

- Repository: [Tomohisa Oda/dewy](https://github.com/linyows/dewy)
- Tags: deep-dive
- Published: 2026-03-06

---

**Dewy handles versioning for deployments by parsing Semantic Versioning (SemVer) or Calendar Versioning (CalVer) tags, comparing versions using scheme-specific logic, and extracting deployment slots from build metadata to support blue/green strategies.**

Dewy is an open-source deployment agent written in Go that automates artifact retrieval and deployment workflows. Understanding how Dewy handles versioning for deployments is essential for configuring reliable release pipelines, as the tool supports multiple versioning schemes and uses build metadata to manage deployment slots.

## The Unified Version Interface

Dewy abstracts version handling through a common interface that allows different versioning schemes to be processed uniformly across all registry implementations.

### Common Contract for All Version Types

All version types in Dewy implement the `Version` interface defined in [`registry/version.go`](https://github.com/linyows/dewy/blob/main/registry/version.go):

```go
type Version interface {
    String() string               // full tag string
    GetBuildMetadata() string     // slot / build‑metadata part
}

```

*Source:* [[`registry/version.go`](https://github.com/linyows/dewy/blob/main/registry/version.go) lines 8‑12](https://github.com/linyows/dewy/blob/main/registry/version.go#L8-L12)

This interface ensures that whether you use SemVer or CalVer, Dewy can extract the build metadata (used for deployment slots) and compare versions consistently.

## Supported Version Schemes

Dewy natively supports two major versioning schemes, allowing teams to choose the approach that fits their release cadence.

### Semantic Versioning (SemVer)

Dewy parses SemVer tags using `ParseSemVer` in [`registry/semver.go`](https://github.com/linyows/dewy/blob/main/registry/semver.go). The implementation recognizes the classic `vMAJOR.MINOR.PATCH[-PRERELEASE][+METADATA]` pattern and includes comparison logic and build-metadata extraction.

Key components include:
- **Regex parsing** for version components
- **Comparison method** for ordering versions
- **Build metadata extraction** for slot identification

*Source:* [[`registry/semver.go`](https://github.com/linyows/dewy/blob/main/registry/semver.go) lines 9‑13, 46‑64, 84‑92](https://github.com/linyows/dewy/blob/main/registry/semver.go#L9-L13)

### Calendar Versioning (CalVer)

For teams using date-based versioning, Dewy provides `NewCalVerFormat` and `Parse` in [`registry/calver.go`](https://github.com/linyows/dewy/blob/main/registry/calver.go). The format is user-configurable (e.g., `YYYY.0M.MICRO`), allowing flexible date schemes.

Key capabilities include:
- **Dynamic regex generation** from format strings
- **Segment-by-segment comparison** for ordering
- **Pre-release handling** within CalVer tags

*Source:* [[`registry/calver.go`](https://github.com/linyows/dewy/blob/main/registry/calver.go) lines 10‑22, 50‑69, 131‑158](https://github.com/linyows/dewy/blob/main/registry/calver.go#L10-L22)

## Selecting the Latest Version for Deployment

Dewy determines which artifact to deploy by comparing available versions and selecting the highest valid tag according to the configured scheme.

### Registry-Specific Implementation

Each registry implementation (S3, Google Storage, GitHub Release, OCI, gRPC) lists version directories or tags and delegates to helper functions:

- **`FindLatestSemVer`** – Chooses the highest SemVer, optionally excluding pre-releases based on the `PreRelease` flag.
  *Source:* [[`registry/semver.go`](https://github.com/linyows/dewy/blob/main/registry/semver.go) lines 90‑122](https://github.com/linyows/dewy/blob/main/registry/semver.go#L90-L122)

- **`FindLatestCalVer`** – Analogous logic for CalVer formats.
  *Source:* [[`registry/calver.go`](https://github.com/linyows/dewy/blob/main/registry/calver.go) lines 170‑205](https://github.com/linyows/dewy/blob/main/registry/calver.go#L170-L205)

The decision logic in the S3 registry (mirrored in other registries) appears as:

```go
if s.CalVer != "" {
    latestVersion, latestName, err = FindLatestCalVer(versionNames, s.CalVer, s.PreRelease)
} else {
    latestVersion, latestName, err = FindLatestSemVer(versionNames, s.PreRelease)
}

```

*Source:* [[`registry/s3.go`](https://github.com/linyows/dewy/blob/main/registry/s3.go) lines 299‑306](https://github.com/linyows/dewy/blob/main/registry/s3.go#L299-L306)

## Extracting Deployment Slots from Build Metadata

Dewy supports blue/green deployment strategies by extracting the **slot** identifier from the build metadata portion of version tags.

The `extractSlot` helper in [`registry/registry.go`](https://github.com/linyows/dewy/blob/main/registry/registry.go) handles both CalVer and SemVer:

```go
func extractSlot(tag, calverFormat string) string {
    if calverFormat != "" {
        if f, err := NewCalVerFormat(calverFormat); err == nil {
            if cv := f.Parse(tag); cv != nil {
                return cv.BuildMetadata
            }
        }
    }
    if sv := ParseSemVer(tag); sv != nil {
        return sv.BuildMetadata
    }
    return ""
}

```

*Source:* [[`registry/registry.go`](https://github.com/linyows/dewy/blob/main/registry/registry.go) lines 80‑95](https://github.com/linyows/dewy/blob/main/registry/registry.go#L80-L95)

The extracted slot populates `CurrentResponse.Slot`, enabling downstream blue/green logic to determine which environment to target.

## Configuration Options for Version Control

Dewy exposes several configuration fields that control versioning behavior:

- **`Config.CalVer`** – Optional format string enabling CalVer parsing (e.g., `YYYY.0M.MICRO`).
- **`Config.Slot`** – The desired deployment slot used when reporting deployment status.
- **`Config.PreRelease`** – Boolean flag per registry; when **true**, pre-release versions are considered candidates, otherwise they are ignored.

*Sources:*

- `Config.CalVer` / `Config.Slot`: [[`config.go`](https://github.com/linyows/dewy/blob/main/config.go) lines 95‑99](https://github.com/linyows/dewy/blob/main/config.go#L95-L99)
- `PreRelease` field: [[`registry/s3.go`](https://github.com/linyows/dewy/blob/main/registry/s3.go) lines 31‑33](https://github.com/linyows/dewy/blob/main/registry/s3.go#L31-L33) (similar patterns in [`registry/gs.go`](https://github.com/linyows/dewy/blob/main/registry/gs.go), [`registry/ghr.go`](https://github.com/linyows/dewy/blob/main/registry/ghr.go), and [`registry/oci.go`](https://github.com/linyows/dewy/blob/main/registry/oci.go))

## End-to-End Deployment Flow

The complete versioning and deployment process in Dewy follows this sequence:

1. **Registry Creation** – `registry.New(ctx, "<scheme>://…", logger)` returns a concrete implementation (S3, GCS, GitHub, OCI, or gRPC).
2. **Version Resolution** – The `Current` method invokes `LatestVersion`, which selects the most recent tag according to the configured scheme (CalVer or SemVer) and the `PreRelease` flag.
3. **Slot Extraction** – `extractSlot` derives the deployment slot from the selected tag's build metadata and populates `CurrentResponse.Slot`.
4. **Deployment** – Callers use `Tag`, `ArtifactURL`, and `Slot` to perform the actual deployment (e.g., Docker run, server start).
5. **Reporting** – The `Report` method records success or failure, optionally using the slot for blue/green tracking.

## Practical Code Examples

### Retrieving the Latest Artifact from S3

```go
ctx := context.Background()
log := logging.New()                     // Dewy logger
reg, err := registry.New(ctx,
    "s3://us-east-1/my-bucket/releases/",
    log)
if err != nil { panic(err) }

cur, err := reg.Current(ctx)
if err != nil { panic(err) }

fmt.Printf("Deploying %s from %s (slot=%s)\n",
    cur.Tag, cur.ArtifactURL, cur.Slot)

```

*Key calls:* `registry.New` → `S3.LatestVersion` → `FindLatestSemVer` / `FindLatestCalVer` → `extractSlot`.

### Configuring CalVer and Slot Filtering

```go
cfg := dewy.DefaultConfig()
cfg.Registry = "s3://us-east-1/my-bucket/releases/"
cfg.CalVer   = "YYYY.0M.MICRO"   // use calendar versioning
cfg.PreRelease = false           // ignore prereleases
cfg.Slot = "blue"                // expect blue‑slot artifacts

dewy := dewy.New(cfg)
dewy.Start()                     // Internally uses the flow described above

```

### Manual Slot Extraction

```go
tag := "2024.06.15-rc.1+green"
slot := registry.ExtractSlot(tag, "YYYY.0M.MICRO") // → "green"
fmt.Println("Slot:", slot)

```

*(Note: `ExtractSlot` is an exported helper in the actual code base; the internal implementation is `extractSlot`.)*

## Key Source Files and Architecture

| File | Purpose |
|------|---------|
| [[`registry/version.go`](https://github.com/linyows/dewy/blob/main/registry/version.go)](https://github.com/linyows/dewy/blob/main/registry/version.go) | `Version` interface and pre‑release comparison logic |
| [[`registry/semver.go`](https://github.com/linyows/dewy/blob/main/registry/semver.go)](https://github.com/linyows/dewy/blob/main/registry/semver.go) | SemVer parsing, comparison, and latest‑SemVer selection |
| [[`registry/calver.go`](https://github.com/linyows/dewy/blob/main/registry/calver.go)](https://github.com/linyows/dewy/blob/main/registry/calver.go) | CalVer parsing, comparison, and latest‑CalVer selection |
| [[`registry/registry.go`](https://github.com/linyows/dewy/blob/main/registry/registry.go)](https://github.com/linyows/dewy/blob/main/registry/registry.go) | Registry factory, `extractSlot` helper, and common utilities |
| [[`registry/s3.go`](https://github.com/linyows/dewy/blob/main/registry/s3.go)](https://github.com/linyows/dewy/blob/main/registry/s3.go) | S3 implementation – lists version directories and calls the version‑selection helpers |
| [[`registry/gs.go`](https://github.com/linyows/dewy/blob/main/registry/gs.go)](https://github.com/linyows/dewy/blob/main/registry/gs.go) | Google Storage implementation (same version flow) |
| [[`registry/ghr.go`](https://github.com/linyows/dewy/blob/main/registry/ghr.go)](https://github.com/linyows/dewy/blob/main/registry/ghr.go) | GitHub Release implementation |
| [[`registry/oci.go`](https://github.com/linyows/dewy/blob/main/registry/oci.go)](https://github.com/linyows/dewy/blob/main/registry/oci.go) | OCI image registry implementation |
| [[`config.go`](https://github.com/linyows/dewy/blob/main/config.go)](https://github.com/linyows/dewy/blob/main/config.go) | Configuration fields (`CalVer`, `PreRelease`, `Slot`) that control version handling |
| [[`dewy.go`](https://github.com/linyows/dewy/blob/main/dewy.go)](https://github.com/linyows/dewy/blob/main/dewy.go) | Main runtime – uses `Current` response for deployment and reporting |

These components together give Dewy a flexible, test‑driven versioning system that can work with either conventional SemVer or user‑defined CalVer, honor pre‑release preferences, and expose the build‑metadata slot for blue/green deployment strategies.

## Summary

- Dewy supports both **Semantic Versioning (SemVer)** and **Calendar Versioning (CalVer)** through a unified interface defined in [`registry/version.go`](https://github.com/linyows/dewy/blob/main/registry/version.go).
- Version selection logic resides in scheme‑specific files: `FindLatestSemVer` in [`registry/semver.go`](https://github.com/linyows/dewy/blob/main/registry/semver.go) and `FindLatestCalVer` in [`registry/calver.go`](https://github.com/linyows/dewy/blob/main/registry/calver.go).
- The **slot** for blue/green deployments is extracted from build metadata using the `extractSlot` helper in [`registry/registry.go`](https://github.com/linyows/dewy/blob/main/registry/registry.go).
- Configuration fields `CalVer`, `PreRelease`, and `Slot` in [`config.go`](https://github.com/linyows/dewy/blob/main/config.go) control which versioning scheme to use and whether to include pre‑release candidates.
- All registry implementations (S3, Google Storage, GitHub Releases, OCI) follow the same pattern: list tags, delegate to version selection helpers, and extract slots.

## Frequently Asked Questions

### How does Dewy decide between SemVer and CalVer?

Dewy checks the `Config.CalVer` field. If a non‑empty format string is provided (e.g., `YYYY.0M.MICRO`), Dewy uses `FindLatestCalVer` in [`registry/calver.go`](https://github.com/linyows/dewy/blob/main/registry/calver.go). Otherwise, it defaults to SemVer parsing via `FindLatestSemVer` in [`registry/semver.go`](https://github.com/linyows/dewy/blob/main/registry/semver.go).

### Can Dewy deploy pre‑release versions?

Yes, but only if configured to do so. The `PreRelease` boolean field in each registry configuration (defined in [`registry/s3.go`](https://github.com/linyows/dewy/blob/main/registry/s3.go) and similar files) controls whether tags with pre‑release identifiers (like `-rc.1` or `-beta`) are considered valid deployment candidates.

### What is the "slot" and how is it extracted?

The **slot** is a deployment environment identifier (e.g., "blue" or "green") used for blue/green deployment strategies. Dewy extracts it from the **build metadata** portion of the version tag (the part after `+` in SemVer or CalVer). The `extractSlot` function in [`registry/registry.go`](https://github.com/linyows/dewy/blob/main/registry/registry.go) handles this extraction for both versioning schemes.

### Which registries support Dewy's versioning system?

All built‑in registry implementations use the same versioning logic: **S3** ([`registry/s3.go`](https://github.com/linyows/dewy/blob/main/registry/s3.go)), **Google Cloud Storage** ([`registry/gs.go`](https://github.com/linyows/dewy/blob/main/registry/gs.go)), **GitHub Releases** ([`registry/ghr.go`](https://github.com/linyows/dewy/blob/main/registry/ghr.go)), and **OCI** ([`registry/oci.go`](https://github.com/linyows/dewy/blob/main/registry/oci.go)). Each delegates to the shared `FindLatestSemVer` or `FindLatestCalVer` helpers after listing available tags.