docs(adr): ADR-0014: Configuration Schema Versioning
@aRustyDev ci sta già lavorando.
Dal 5/1/2026.
Valutazione
Questa issue non è ancora stata valutata.
Descrizione
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:
- Enables backward-compatible changes without breaking existing books
- Provides clear upgrade paths when breaking changes occur
- Validates configuration against the correct schema version
- Allows new features without forcing all users to upgrade
Decision Drivers
- Backward Compatibility - Existing books should continue working
- Clear Upgrades - Breaking changes must be explicit and documented
- Validation - Catch configuration errors at build time
- Discoverability - IDE autocompletion and documentation
- 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
- Announce deprecation in release notes
- Warn during build for at least 2 minor versions
- Remove only in major version bump
- 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
- Nessun Dockerfile né file Docker Compose
- Nessun modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di aRustyDev/mdbook-htmx
-
feat(ci): Implement cross-repo-validate compliance for docs syncForse di nuovo libera @aRustyDev l’ha presa 284 giorni fa e non c’è nessuna pull request aperta. Apertaci enhancement
aRustyDev/mdbook-htmx#58 · 1 commento · 1 assegnatario ·
-
docs(htmx): Explain how HTMX worksForse di nuovo libera @aRustyDev l’ha presa 286 giorni fa e non c’è nessuna pull request aperta. Aperta
aRustyDev/mdbook-htmx#48 · 3 commenti · 1 assegnatario ·
-
docs(mdbook-htmx): Parent Issue for documentationForse di nuovo libera @aRustyDev l’ha presa 286 giorni fa e non c’è nessuna pull request aperta. Apertadocumentation
aRustyDev/mdbook-htmx#47 · 1 assegnatario ·
-
docs(examples): Secure Self-Hosted Meilisearch via CloudflareForse di nuovo libera @aRustyDev l’ha presa 286 giorni fa e non c’è nessuna pull request aperta. Apertadocumentation
aRustyDev/mdbook-htmx#46 · 1 assegnatario ·
-
docs(examples): Kubernetes with MeilisearchForse di nuovo libera @aRustyDev l’ha presa 286 giorni fa e non c’è nessuna pull request aperta. Apertadocumentation
aRustyDev/mdbook-htmx#45 · 1 assegnatario ·
Tutte le issue di aRustyDev/mdbook-htmx
Issue simili
-
Can't import CSV parametersApertaarea:io needs-info needs-triage
Difficoltà 2/5 1-3 ore Idoneità per principianti 63/100
bherbruck/solvecraft#3216 · 1 commento ·
-
bug triage/needs-triage
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
praxis-proxy/grid#412 ·
I maintainer di solito rispondono entro 1 giorno
-
priority: low
Difficoltà 2/5 1-3 ore Idoneità per principianti 63/100
storytold/photocraft#7824 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
area:ui chore could help wanted
Difficoltà 2/5 1-3 ore Idoneità per principianti 88/100
I maintainer di solito rispondono entro 1 giorno
-
`[daemons]` fails to resolve standalone file tasks by their display name (`runs unknown task`)Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 84/100
I maintainer di solito rispondono entro 1 giorno