Skip to content

SI-32: Define package versioning strategy for EPIC #1669 #1926

Description

@josecelano

Subissue of EPIC #1669 — Overhaul: Packages

Goal

Define an explicit and maintainable SemVer policy for workspace packages, replacing the implicit "everything shares one workspace version" rule with independent versioning for every package.

This issue defines policy only — actual version migration is deferred to a follow-up implementation issue.

Problem Statement

Current state:

  • All workspace crates use version.workspace = true and currently resolve to 3.0.0-develop.
  • This keeps internal releases simple but couples unrelated packages to the same release cadence.

Observed downside:

  • Generic crates and tool crates are version-bumped even when no API or behavior changed in those crates.
  • Consumers cannot infer change risk from version numbers when every crate bumps together.
  • Extraction and independent publication plans in EPIC Overhaul: packages #1669 become harder to execute cleanly when package identity and version cadence are still mixed.

Analysis Summary

From current workspace topology:

  • All packages currently share the workspace root version (version.workspace = true3.0.0-develop).
  • The workspace contains packages with very different consumer surfaces: tightly-coupled tracker runtime crates, utility/platform crates, and extraction candidates.
  • Since all dependencies use path = "..." within the workspace, there is no runtime compatibility risk from independent versions — Cargo always uses the local copy regardless of the version number in Cargo.toml.

Conclusion:

  • A single lockstep version is suboptimal — it inflates churn on unrelated packages and gives weak SemVer signals.
  • A hybrid two-tier split imposes a guess about future coupling instead of letting it emerge naturally.
  • Independent versioning for all packages is the simplest correct approach: path dependencies make it safe, and individual release cadences can evolve without coordination overhead.

Proposed Versioning Policy

All packages version independently. Each package declares its own version field (not version.workspace = true), starting from their current 3.0.0-develop value with an appropriate initial release version.

Rationale:

  • Path dependencies make linked versions unnecessary — the workspace always resolves the local copy regardless of the declared version.
  • Avoids unnecessary SemVer churn on unrelated packages when only part of the workspace changes.
  • Gives accurate SemVer signals to external consumers of published crates.
  • Aligns with the EPIC Overhaul: packages #1669 extraction goal — packages moving to standalone repos already version independently.
  • If packages naturally evolve together over time, that coupling can be formalised later when there is evidence, not before.

Release Process Implications

Independent versioning splits the current unified release model into two distinct concepts:

Concept Description Cadence
Tracker application release Root binary torrust-tracker + the tightly-coupled runtime crates Existing process: tag releases/v*, CI publishes the whole set as a bundle
Individual package publish Any workspace crate published independently at its own cadence Per-package decision — no need to wait for a full tracker release

Why This Matters Now

The client extraction draft is blocked on two unpublished workspace crates: torrust-tracker-udp-protocol and torrust-tracker-client-lib. With independent versioning, each can be published with a single cargo publish -p <crate> when ready, without requiring a full tracker release.

Affected Artifacts

docs/release_process.md: Rename to "Tracker Application Release Process" (existing workflow stays as one path). Add a second "Publishing an Individual Package" path.

.github/workflows/deployment.yaml: Remove crates extracted to standalone repos (stale entries). Convert from one monolithic list to either a reusable workflow or a split design.

What Does Not Change

  • The existing tracker application release process continues to work as before.
  • Path dependencies within the workspace are unaffected.

Implementation Strategy

Phase 1 (this issue): policy definition only

  1. Define the policy contract: all packages version independently.
  2. Create an ADR in docs/adrs/ documenting the decision.
  3. Document release process impact.
  4. Document in the EPIC and EPIC references the ADR.
  5. Open a follow-up implementation issue for Phase 2 (version migration) and another for release process automation changes.

Phase 2 (follow-up implementation issue):

  1. Remove version.workspace = true from all packages.
  2. Set appropriate initial versions.
  3. Add CI checks to prevent reintroducing version.workspace = true.
  4. Validate publish workflows for per-package versioning.

Alternatives Considered

Alternative A - Keep all crates on one shared workspace version (discarded)

Why considered: minimal tooling complexity, easy coordinated release process.

Why discarded: over-couples unrelated packages and inflates churn; weak SemVer signal; conflicts with EPIC extraction goals.

Alternative B - Hybrid two-tier strategy (discarded)

Why considered: appeared to balance coordination simplicity for tightly-coupled runtime crates against independent evolution for utility crates.

Why discarded: linked-tier advantage is illusory — path dependencies already guarantee compatibility within the workspace; imposes a guess about future coupling; adds unnecessary policy complexity.

Scope

In Scope

  • Define and document the independent versioning policy.
  • Document the rationale (path deps make linked versions unnecessary).
  • Create an ADR documenting the policy decision for permanent reference in docs/adrs/.
  • Update EPIC documentation with the adopted proposal once approved.
  • Open a follow-up implementation issue for Phase 2 (execution).
  • Document required changes to the release process and deployment CI to support per-package publishing.

Out of Scope

  • Migrating any package to independent versions (follow-up implementation issue).
  • Setting specific initial versions for each package.
  • Publishing extracted crates in external repositories.
  • Renaming packages as part of this policy issue.

Acceptance Criteria

  • The policy explicitly states that all packages version independently.
  • The rationale explains why linked versions are unnecessary (path deps guarantee compatibility).
  • An ADR is created in docs/adrs/ documenting the independent versioning decision.
  • ADR is linked from EPIC Overhaul: packages #1669 documentation.
  • At least two alternatives are documented with discard reasons.
  • EPIC Overhaul: packages #1669 references the approved versioning policy.
  • Release process impact is documented in this spec and a follow-up issue is opened for execution.
  • Deployment CI impact is documented in this spec and a follow-up issue is opened for execution.

Metadata

Metadata

Assignees

Labels

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions