Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

docs(adr): ADR-0014: Configuration Schema Versioning

Aperta
#22 0 commenti 0 reazioni 1 assegnatario Vedi su GitHub

@aRustyDev ci sta già lavorando.

Dal 5/1/2026.

Valutazione

Questa issue non è ancora stata valutata.

Descrizione

documentation

ADR-0014: Configuration Schema Versioning

Status

Accepted

Context

The [output.htmx] configuration in book.toml defines how mdbook-htmx behaves during build. As the project evolves, configuration options will be added, modified, or deprecated. We need a versioning strategy that:

  1. Enables backward-compatible changes without breaking existing books
  2. Provides clear upgrade paths when breaking changes occur
  3. Validates configuration against the correct schema version
  4. Allows new features without forcing all users to upgrade

Decision Drivers

  1. Backward Compatibility - Existing books should continue working
  2. Clear Upgrades - Breaking changes must be explicit and documented
  3. Validation - Catch configuration errors at build time
  4. Discoverability - IDE autocompletion and documentation
  5. Simplicity - Don't overcomplicate for authors

Decision

Use semantic versioning for configuration schema, with explicit version field and migration tooling.

Configuration Version Field

Add an optional version field to [output.htmx]:

[output.htmx]
version = "1.0"  # Configuration schema version (not HTMX library version)
htmx-version = "2.0.4"  # HTMX library version to include
# ... rest of configuration
Version Resolution
version Field Behavior
Omitted Use latest compatible (with deprecation warnings)
"1.0" Use v1.0 schema, error on unknown fields
"1" Use latest v1.x (minor upgrades allowed)
"2.0" Use v2.0 schema
Schema Evolution Rules
Minor Version (1.0 → 1.1)
  • Add new optional fields with defaults
  • Deprecate fields (warn but accept)
  • Never remove or change field semantics
# v1.0 configuration
[output.htmx]
boost = true

# v1.1 adds new optional field
[output.htmx]
boost = true
preload = true  # New in v1.1, defaults to false
Major Version (1.x → 2.0)
  • Remove deprecated fields
  • Change field semantics or types
  • Rename fields
  • Restructure sections
# v1.x (deprecated)
[output.htmx]
authz.enabled = true

# v2.0 (restructured)
[output.htmx.authorization]
enabled = true
provider = "manifest"

Schema Versioning

JSON Schema for Validation
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://schemas.arusty.dev/mdbook-htmx/book-config/v1.0.schema.json",
  "title": "mdbook-htmx Configuration Schema v1.0",
  "description": "Configuration schema for [output.htmx] in book.toml",
  "type": "object",
  "properties": {
    "version": {
      "type": "string",
      "pattern": "^[0-9]+\\.[0-9]+$",
      "description": "Configuration schema version"
    },
    "htmx-version": {
      "type": "string",
      "default": "2.0.4",
      "description": "HTMX library version to bundle"
    },
    "boost": {
      "type": "boolean",
      "default": true,
      "description": "Enable hx-boost on body element"
    }
  },
  "additionalProperties": true
}
Version-Specific Schemas
schemas/
├── book-config/
│   ├── v1.0.schema.json
│   ├── v1.1.schema.json
│   └── v2.0.schema.json
└── book-config.schema.json  # Always latest stable

Implementation

Rust Configuration Types
use serde::Deserialize;

#[derive(Debug, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct HtmxConfigV1 {
    #[serde(default = "default_version")]
    pub version: String,

    #[serde(rename = "htmx-version", default = "default_htmx_version")]
    pub htmx_version: String,

    #[serde(default = "default_boost")]
    pub boost: bool,

    #[serde(default)]
    pub swap_strategy: SwapStrategy,

    #[serde(default = "default_target")]
    pub target: String,

    #[serde(default = "default_push_url")]
    pub push_url: bool,

    #[serde(rename = "template-engine", default)]
    pub template_engine: TemplateEngine,

    #[serde(default)]
    pub theme: Option<String>,

    #[serde(rename = "output-mode", default)]
    pub output_mode: OutputMode,

    #[serde(default)]
    pub navigation: NavigationConfig,

    #[serde(default)]
    pub authn: AuthnConfig,

    #[serde(default)]
    pub authz: AuthzConfig,

    #[serde(default)]
    pub search: SearchConfig,

    #[serde(default)]
    pub assets: AssetsConfig,

    #[serde(default)]
    pub scopes: ScopesConfig,
}

fn default_version() -> String { "1.0".to_string() }
fn default_htmx_version() -> String { "2.0.4".to_string() }
fn default_boost() -> bool { true }
fn default_target() -> String { "#content".to_string() }
fn default_push_url() -> bool { true }
Version Detection and Migration
pub fn load_config(toml_value: &toml::Value) -> Result<HtmxConfig> {
    // Extract version field
    let version = toml_value
        .get("version")
        .and_then(|v| v.as_str())
        .unwrap_or("1.0");

    let (major, minor) = parse_version(version)?;

    match major {
        1 => {
            let config: HtmxConfigV1 = toml_value.clone().try_into()?;
            check_deprecations_v1(&config);
            Ok(HtmxConfig::V1(config))
        }
        2 => {
            let config: HtmxConfigV2 = toml_value.clone().try_into()?;
            Ok(HtmxConfig::V2(config))
        }
        _ => anyhow::bail!(
            "Unsupported configuration version: {}. \
             Supported versions: 1.x, 2.x",
            version
        ),
    }
}

fn check_deprecations_v1(config: &HtmxConfigV1) {
    // Example: auth field renamed to authz in v1.1
    if config.auth.is_some() {
        log::warn!(
            "Configuration field 'auth' is deprecated. \
             Use 'authz' instead. See ADR-0008."
        );
    }
}
CLI Migration Tool
# Check configuration for issues
$ mdbook-htmx config check
Configuration: book.toml
Version: 1.0
Issues:
  - DEPRECATED: 'auth' field should be 'authz' (will be removed in v2.0)
  - WARNING: 'theme' path 'my-theme' does not exist

# Migrate to latest version
$ mdbook-htmx config migrate --target 1.1
Migrating configuration from v1.0 to v1.1...
  - Renamed 'auth' to 'authz'
  - Added default 'scopes.available = ["all"]'
Written: book.toml.new

# Validate against specific schema
$ mdbook-htmx config validate --schema v1.1
Configuration is valid for schema v1.1

Deprecation Policy

  1. Announce deprecation in release notes
  2. Warn during build for at least 2 minor versions
  3. Remove only in major version bump
  4. Provide migration tool or instructions
Deprecation Timeline Example
v1.0: [auth] introduced
v1.1: [auth] deprecated, [authz] introduced (warn if [auth] used)
v1.2: [auth] still works (warn)
v2.0: [auth] removed (error if present)

Configuration Reference Generation

Generate documentation from JSON Schema:

# Generate markdown documentation
$ mdbook-htmx docs config > docs/config-reference.md

# Output includes:
# - All fields with types and defaults
# - Deprecation notices
# - Version where field was introduced
# - Links to relevant ADRs

Consequences

Positive
  • Users can lock to specific schema version
  • Clear upgrade path with deprecation warnings
  • IDE support via JSON Schema
  • Validation catches errors early
  • Migration tooling eases transitions
Negative
  • Additional complexity in configuration parsing
  • Must maintain multiple schema versions
  • Version field adds noise to simple configs
Mitigation
  • Version field is optional (defaults to latest compatible)
  • Automated migration tools
  • Clear deprecation timeline
  • Schema versions published to CDN for IDE integration

Alternatives Considered

No Versioning

Just evolve configuration organically.

Rejected because:

  • Breaking changes would silently fail
  • No way to validate against known-good schema
  • Hard to document which fields work with which versions
Date-Based Versioning

Use dates like 2024-01 for schema versions.

Rejected because:

  • Semver is more familiar
  • Harder to understand compatibility promises
  • Dates don't indicate breaking vs non-breaking
Per-Field Versioning

Mark each field with its minimum version.

Rejected because:

  • Overly complex
  • Hard to manage dependencies between fields
  • Full schema versioning is simpler

References

Lingua principale
Rust
Stelle
0
Fork
1
Metriche di merge delle PR
Nessuna PR unita negli ultimi 30g

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di aRustyDev/mdbook-htmx

Tutte le issue di aRustyDev/mdbook-htmx

Issue simili

Altre issue su Rust

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.