Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Dev

Testing

Running Tests

cargo test              # Run all tests
cargo test --workspace  # Run tests for the entire workspace

Test Organization

Tests are organized into logical modules under src/tests/:

ModulePurpose
common.rsShared fixtures, helpers, and BibItemBuilder
parser.rsBibTeX/YAML parsing, date extraction, extended fields
citation.rsCitation placeholder replacement, regex patterns
config.rsConfiguration parsing, Zotero, per-chapter settings
backend.rsCustom and CSL backend formatting, regression tests
integration.rsFull book builds (test_book, CSL style variants)
edge_cases.rsError handling, malformed input, unicode support

Test Utilities

The common module provides reusable test infrastructure:

  • BibItemBuilder - Fluent builder for creating test BibItem instances
  • dummy_bibliography() / yaml_bibliography() - Pre-parsed bibliographies (lazy-loaded)
  • create_*_backend() functions - Factory functions for backend instances
  • Test fixtures - DUMMY_BIB_SRC, sample text with citations

Example using the builder:

#![allow(unused)]
fn main() {
let item = BibItemBuilder::article("smith2024")
    .title("Test Article")
    .authors(&["Smith, John"])
    .year("2024")
    .build();
}

Parametrized Tests

Tests use the rstest crate for parametrization. Example:

#![allow(unused)]
fn main() {
#[rstest]
#[case::ieee("ieee")]
#[case::apa("apa")]
#[case::chicago("chicago-author-date")]
fn test_csl_style(#[case] style: &str) {
    let backend = CslBackend::new(style.to_string()).unwrap();
    // test logic...
}
}

Each case runs as a separate test, making it easy to identify failures.

Debug

The preprocessor uses the tracing library for logging. To enable debug output, use the MDBOOK_LOG environment variable:

MDBOOK_LOG=mdbook_bib=debug mdbook build

Examples

MDBOOK_LOG=debug mdbook build # **Set globally for all targets**
MDBOOK_LOG=mdbook_bib=debug,handlebars=warn mdbook build # Debug specific modules like ours (mdbook_bib)

Tips

  • The default log level is info if MDBOOK_LOG is not set
  • Noisy dependencies (handlebars, html5ever) are automatically silenced to warn unless explicitly specified
  • Module paths (targets) are only displayed when MDBOOK_LOG is set

Commits

This project follows the Conventional Commits specification for commit messages. This enables automatic changelog generation with proper categorization.

Commit Format

<type>[optional scope]: <description>

[optional body]

[optional footer(s)]

Common Types

TypeDescriptionChangelog Section
featNew featureFeatures
fixBug fixBug Fixes
docsDocumentation onlyDocumentation
refactorCode change (no new feature or fix)Refactoring
testAdding/updating testsTesting
perfPerformance improvementPerformance
choreMaintenance tasksMiscellaneous
ciCI/CD changesCI/CD

Examples

feat(parser): add YAML bibliography support
fix: handle empty author fields gracefully
docs: update installation instructions
refactor(render): extract template loading into separate module
test: add integration tests for CSL backend

Before Committing

Format and lint your code:

cargo fmt --              # Format all code
cargo clippy --fix        # Run clippy with auto-fixes
cargo clippy --fix --tests  # Run clippy for tests

Pre-commit hooks (.rusty-hook.toml) block commits with formatting errors. GitHub’s test.yml workflow runs on pushes to master. Look for problems in the GitHub Actions.

Versioning

From version 0.5.0, mdbook-bib’s minor version tracks mdbook’s minor version for compatibility.

Release

The release process is managed via make. Run make help to see all options:

make help

Quick Release

To release the next patch version (auto-incremented):

make release              # Releases 0.5.1 → 0.5.2 automatically

To release a specific version:

make release VERSION=1.0.0

Dry-Run Mode

Add DRY_RUN=1 to any command to simulate without making changes:

make release DRY_RUN=1              # Simulate with auto-version
make release DRY_RUN=1 VERSION=1.0.0  # Simulate specific version
make update-cargo DRY_RUN=1         # Simulate just Cargo.toml update

Prerequisites

Install git-cliff for changelog generation:

cargo install git-cliff

Available Targets

TargetDescription
releaseComplete release (update, commit, tag, push)
update-versionUpdate version in Cargo.toml and doc.yml
update-cargoUpdate version only in Cargo.toml
update-docUpdate version only in doc.yml
update-lockfileRegenerate Cargo.lock after version update
update-changelogGenerate CHANGELOG.md using git-cliff
check-releaseValidate release preconditions
show-versionShow current and next version

Release Steps

The release process performs these steps locally:

  1. check-release - Validate version format and clean working directory
  2. update-version - Update Cargo.toml and .github/workflows/doc.yml
  3. update-lockfile - Regenerate Cargo.lock
  4. update-changelog - Generate CHANGELOG.md using git-cliff
  5. Commit all changes with message Prepare for release vX.Y.Z
  6. Create annotated tag vX.Y.Z
  7. Push commit and tag atomically to origin

GitHub Workflows (Sequential)

After the push, GitHub Actions run in sequence with failure gates:

  1. release.yml - Builds binaries for Linux, Windows, and macOS

    • Uploads to GitHub Releases
    • If any platform fails → stops here (no publish)
  2. publish.yml - Publishes to crates.io

    • Only runs if all Release builds succeeded
    • If publish fails → stops here (no docs)
  3. doc.yml - Deploys documentation to GitHub Pages

    • Only runs if Publish succeeded

This ensures you never publish a crate that fails to build on any platform.