---
title: Increment version from template
summary: Apply wildcard, retention, and date-token rules to update the current version in place.
status: draft
owner: SAIF Team
last_reviewed: 2026-07-30
library: SAIF.Framework.Version
reference_type: package
operation_id: OP-VER-004
trigger: Caller invokes Version.Increment(format)
---

# Increment version from template

This operation advances an existing `Version` instance according to a caller-supplied four-part `format` template, typically used in version-stamping workflows during a build. Each template segment independently chooses one of four behaviors: auto-increment the prior numeric value (`*`), retain the current value (empty token), substitute a literal string, or expand a date placeholder. Once all four segments are resolved, the assembled string is re-parsed and applied back onto the same instance.

| Field | Value |
| --- | --- |
| **Operation ID** | `OP-VER-004` |
| **Trigger** | Caller invokes `Version.Increment(format)` |
| **Inputs** | `format As String`, current `Major`, `Minor`, `Build`, and `Revision` values |
| **Outputs** | Updated `Version` instance (`Me`) |
| **Primary components** | `Version.Increment`, `Version.Parse`, `Version.Update`, `Extensions.ToInt` |
| **Entry point** | `SAIF.Framework.Version\Version.vb` |

## Steps

1. Snapshot the instance's current `Major`, `Minor`, `Build`, and `Revision` values into `m_lastVersion`, preserving the pre-increment state for use in wildcard substitution.
2. Split `format` on `.` and initialize the assembly template `"{0}.{1}.{2}.{3}"`.
   - On failure: if `format` is `Nothing`, `String.Split` throws and the exception propagates to the caller unhandled.
3. Iterate segment indexes `0` through `3`, mapping each index to the corresponding current value — `Major`, `Minor`, `Build`, or `Revision`.
4. For each index, attempt to read the matching token from the split `format` array.
   - If the array access fails because `format` supplied fewer than four segments: fall back to the prior segment value (`lastValue`) for that position, so a short-format string still resolves to a complete four-part result.
5. If the token contains `*`, substitute the placeholder with `(lastValue.ToInt + 1)` — the prior value's numeric form, incremented by one ([BR-001](../business-rules.md#br-001-non-numeric-leading-characters-in-a-version-segment-are-coerced-to-0), [BR-003](../business-rules.md#br-003-a-wildcard-token-in-an-increment-format-means-auto-increment-this-segment)).
   - `ToInt` normalizes the prior segment before the increment is applied, matching the same rule used for comparisons.
   - On failure: a prior segment value that is non-numeric or fails conversion normalizes to `0` before incrementing, so the resulting segment becomes `1` rather than raising an error ([BR-001](../business-rules.md#br-001-non-numeric-leading-characters-in-a-version-segment-are-coerced-to-0)).
6. If the token is an empty string, keep the segment's existing value unchanged rather than replacing or blanking it ([BR-004](../business-rules.md#br-004-an-empty-increment-format-token-means-retain-the-current-segment-value-unchanged)).
7. For any other token, copy the literal text into the output segment as-is; no numeric validation is applied to literal tokens.
8. Once all four segments are resolved, replace any `{year}`, `{month}`, and `{day}` placeholders in the assembled string with the corresponding parts of the current date (`Now`) ([BR-005](../business-rules.md#br-005-increment-format-supports-date-template-tokens-year-month-day)).
9. Parse the fully assembled four-part string with `Version.Parse`, apply the result to the current instance via `Update`, and return `Me`.
   - This final parse reuses the same segment-splitting and default-filling logic described in [Parse version input](parse-version-input.md), so any segment left incomplete by the template resolves the same way a directly parsed string would.

## Process flow

The following diagram visualizes this operation's control flow.

```mermaid
flowchart TD
	Start([Caller invokes Increment]) --> Snapshot[Snapshot current version as last version]
	Snapshot --> Split[Split format into per-segment tokens]
	Split --> Loop{Evaluate each segment token}
	Loop -->|Wildcard| Auto[Increment normalized prior value by 1]
	Loop -->|Empty| Keep[Keep existing segment value]
	Loop -->|Literal| Literal[Copy literal token unchanged]
	Loop -->|Missing token| Fallback[Fall back to prior segment value]
	Auto --> Date[Expand year month day placeholders]
	Keep --> Date
	Literal --> Date
	Fallback --> Date
	Date --> Parse[Parse the assembled four-part string]
	Parse --> Update[Apply parsed segments to current instance]
	Update --> EndOk([Return Me, updated in place])
```

## Failure and edge-case behavior

- A `Nothing` `format` is not handled locally; the resulting exception propagates to the caller.
- A `format` string shorter than four segments is not rejected — the missing positions simply fall back to their prior values through the array-access failure path rather than an explicit length check.
- Literal segment text passes through without numeric validation; only the wildcard path is normalized through `ToInt`.
- Wildcard increments always operate on the normalized prior value, so a malformed or non-numeric current segment increments from `0` rather than failing ([BR-001](../business-rules.md#br-001-non-numeric-leading-characters-in-a-version-segment-are-coerced-to-0), [BR-003](../business-rules.md#br-003-a-wildcard-token-in-an-increment-format-means-auto-increment-this-segment)).

## Related documentation
- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)

## Sources
- `SAIF.Framework.Version\Version.vb`
