name: Documentation
on:
push:
branches: [ "main" ]
paths:
- 'src/**'
- 'Cargo.toml'
- 'README.md'
- 'docs/**'
- '.github/workflows/docs.yml'
pull_request:
branches: [ "main" ]
paths:
- 'src/**'
- 'Cargo.toml'
- 'README.md'
- 'docs/**'
workflow_dispatch:
schedule:
- cron: '0 4 * * *'
env:
CARGO_TERM_COLOR: always
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: "pages"
cancel-in-progress: false
jobs:
check-docs:
name: Check Documentation
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Cache cargo
uses: actions/cache@v4
with:
path: |
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target
key: ${{ runner.os }}-cargo-docs-${{ hashFiles('**/Cargo.lock') }}
- name: Check documentation builds without warnings
run: |
RUSTDOCFLAGS="-D warnings" cargo doc --all-features --no-deps --document-private-items
- name: Test documentation examples
run: cargo test --doc --all-features
build-docs:
name: Build Documentation
runs-on: ubuntu-latest
if: github.event_name != 'pull_request'
outputs:
docs-built: ${{ steps.build.outputs.docs-built }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Cache cargo
uses: actions/cache@v4
with:
path: |
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target
key: ${{ runner.os }}-cargo-docs-build-${{ hashFiles('**/Cargo.lock') }}
- name: Install additional tools
run: |
cargo install cargo-readme || true
cargo install mdbook || true
- name: Generate API documentation
id: build
run: |
# Generate rustdoc with all features
cargo doc --all-features --no-deps --document-private-items
# Set custom HTML head with CSS and metadata
cat > target/doc/head.html << 'EOF'
<meta name="description" content="ThreatFlux Cache - A flexible async cache library for Rust">
<meta name="keywords" content="rust, cache, async, lru, storage, serialization">
<meta property="og:title" content="ThreatFlux Cache Documentation">
<meta property="og:description" content="API documentation for ThreatFlux Cache library">
<meta property="og:type" content="website">
<style>
.sidebar { background-color: #f8f9fa; }
.theme-picker { margin-top: 10px; }
.content { max-width: 1200px; }
</style>
EOF
# Create index.html that redirects to the crate docs
cat > target/doc/index.html << 'EOF'
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>ThreatFlux Cache Documentation</title>
<meta http-equiv="refresh" content="0; url=threatflux_cache/index.html">
<link rel="canonical" href="threatflux_cache/index.html">
</head>
<body>
<p>If you are not redirected automatically, follow this <a href="threatflux_cache/index.html">link to ThreatFlux Cache documentation</a>.</p>
</body>
</html>
EOF
echo "docs-built=true" >> $GITHUB_OUTPUT
- name: Generate README from lib.rs
run: |
if command -v cargo-readme >/dev/null 2>&1; then
cargo readme --output README.md || true
fi
- name: Create additional documentation
run: |
mkdir -p target/doc/guides
# Create getting started guide
cat > target/doc/guides/getting-started.html << 'EOF'
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Getting Started - ThreatFlux Cache</title>
<link rel="stylesheet" href="../main.css">
<link rel="stylesheet" href="../settings.css">
<link rel="stylesheet" href="../noscript.css">
</head>
<body class="rustdoc">
<main>
<div class="width-limiter">
<div class="sub-container">
<div class="sidebar">
<a class="sidebar-logo" href="../index.html">ThreatFlux Cache</a>
</div>
<section id="main-content" class="content">
<h1>Getting Started with ThreatFlux Cache</h1>
<h2>Installation</h2>
<pre><code>[dependencies]
threatflux-cache = "0.1.0"</code></pre>
<h2>Basic Usage</h2>
<pre><code>use threatflux_cache::{Cache, MemoryBackend, JsonSerialization};
use tokio;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Create a cache with memory backend and JSON serialization
let cache = Cache::new(
MemoryBackend::new(),
JsonSerialization::new(),
).await?;
// Store a value
cache.set("key1", &"Hello, World!").await?;
// Retrieve a value
let value: Option<String> = cache.get("key1").await?;
println!("Retrieved: {:?}", value);
Ok(())
}</code></pre>
<h2>Features</h2>
<ul>
<li><strong>Async Support</strong> - Built with async/await from the ground up</li>
<li><strong>Pluggable Backends</strong> - Memory and filesystem backends included</li>
<li><strong>Multiple Serialization</strong> - JSON, bincode, and custom serialization</li>
<li><strong>LRU Eviction</strong> - Automatic cache eviction with configurable policies</li>
<li><strong>Compression</strong> - Optional compression with flate2</li>
<li><strong>Metrics</strong> - Prometheus metrics integration</li>
<li><strong>Tracing</strong> - Built-in tracing support</li>
</ul>
<h2>Next Steps</h2>
<p>Check out the <a href="../threatflux_cache/index.html">API documentation</a> for detailed information about all available features.</p>
</section>
</div>
</div>
</main>
</body>
</html>
EOF
# Create examples index
cat > target/doc/examples.html << 'EOF'
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Examples - ThreatFlux Cache</title>
<link rel="stylesheet" href="main.css">
<link rel="stylesheet" href="settings.css">
<link rel="stylesheet" href="noscript.css">
</head>
<body class="rustdoc">
<main>
<div class="width-limiter">
<div class="sub-container">
<div class="sidebar">
<a class="sidebar-logo" href="index.html">ThreatFlux Cache</a>
</div>
<section id="main-content" class="content">
<h1>Examples</h1>
<h2>Available Examples</h2>
<ul>
<li><a href="#basic-usage">Basic Usage</a> - Simple cache operations</li>
<li><a href="#custom-entry">Custom Entry</a> - Using custom data types</li>
<li><a href="#file-scanner-migration">File Scanner Migration</a> - Migration from file-scanner cache</li>
<li><a href="#simple-test">Simple Test</a> - Basic functionality test</li>
</ul>
<h2 id="basic-usage">Basic Usage</h2>
<p>Run with: <code>cargo run --example basic_usage</code></p>
<p>Demonstrates basic cache operations with different backends and serialization formats.</p>
<h2 id="custom-entry">Custom Entry</h2>
<p>Run with: <code>cargo run --example custom_entry</code></p>
<p>Shows how to use custom data types with the cache system.</p>
<h2 id="file-scanner-migration">File Scanner Migration</h2>
<p>Run with: <code>cargo run --example file_scanner_migration</code></p>
<p>Example of migrating from the file-scanner cache system.</p>
<h2 id="simple-test">Simple Test</h2>
<p>Run with: <code>cargo run --example simple_test</code></p>
<p>Simple functionality test and performance benchmark.</p>
</section>
</div>
</div>
</main>
</body>
</html>
EOF
- name: Setup Pages
uses: actions/configure-pages@v5
if: github.ref == 'refs/heads/main'
with:
enablement: true
- name: Upload Pages artifact
uses: actions/upload-pages-artifact@v3
if: github.ref == 'refs/heads/main'
with:
path: target/doc
deploy-docs:
name: Deploy Documentation
runs-on: ubuntu-latest
needs: build-docs
if: github.ref == 'refs/heads/main' && needs.build-docs.outputs.docs-built == 'true'
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
permissions:
pages: write
id-token: write
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
benchmark-docs:
name: Documentation Benchmarks
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Cache cargo
uses: actions/cache@v4
with:
path: |
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target
key: ${{ runner.os }}-cargo-docs-benchmark-${{ hashFiles('**/Cargo.lock') }}
- name: Benchmark documentation build time
run: |
echo "đ Starting documentation build benchmark..."
START_TIME=$(date +%s)
# Build docs with timing
time cargo doc --all-features --no-deps --document-private-items --quiet
END_TIME=$(date +%s)
DURATION=$((END_TIME - START_TIME))
echo "âąī¸ Documentation build completed in ${DURATION} seconds"
# Count documentation items
DOC_COUNT=$(find target/doc -name "*.html" | wc -l)
echo "đ Generated $DOC_COUNT HTML files"
# Calculate documentation size
DOC_SIZE=$(du -sh target/doc | cut -f1)
echo "đ Total documentation size: $DOC_SIZE"
link-checker:
name: Check Documentation Links
runs-on: ubuntu-latest
needs: build-docs
if: github.ref == 'refs/heads/main'
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Cache cargo
uses: actions/cache@v4
with:
path: |
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target
key: ${{ runner.os }}-cargo-docs-linkcheck-${{ hashFiles('**/Cargo.lock') }}
- name: Build documentation
run: cargo doc --all-features --no-deps --document-private-items
- name: Install link checker
run: |
wget -q -O - https://github.com/lycheeverse/lychee/releases/download/v0.15.1/lychee-v0.15.1-x86_64-unknown-linux-gnu.tar.gz | tar -xz
chmod +x lychee
- name: Check internal links
run: |
# Check for broken internal links in documentation
./lychee --verbose --no-progress --exclude-path target/doc/src \
target/doc/**/*.html || true
- name: Generate link report
run: |
echo "# đ Documentation Link Check Report" > link-report.md
echo "" >> link-report.md
echo "Link check completed on $(date)" >> link-report.md
echo "" >> link-report.md
echo "For detailed results, check the workflow logs." >> link-report.md
- name: Upload link report
uses: actions/upload-artifact@v4
with:
name: link-check-report
path: link-report.md
docs-quality:
name: Documentation Quality Check
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Cache cargo
uses: actions/cache@v4
with:
path: |
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target
key: ${{ runner.os }}-cargo-docs-quality-${{ hashFiles('**/Cargo.lock') }}
- name: Check documentation coverage
run: |
echo "đ Analyzing documentation coverage..."
# Build docs with coverage information
RUSTDOCFLAGS="--show-coverage" cargo doc --all-features --no-deps 2>&1 | tee doc-coverage.txt
# Extract coverage statistics
if grep -q "coverage:" doc-coverage.txt; then
echo "â
Documentation coverage information generated"
echo ""
echo "Coverage Summary:"
grep "coverage:" doc-coverage.txt || echo "No coverage summary found"
else
echo "âšī¸ No coverage information available"
fi
- name: Check for missing documentation
run: |
echo "đ Checking for missing documentation..."
# Look for public items without documentation
MISSING_DOCS=$(cargo clippy --all-features -- -W missing-docs 2>&1 | grep "warning:" | wc -l)
if [ $MISSING_DOCS -gt 0 ]; then
echo "â ī¸ Found $MISSING_DOCS items missing documentation"
echo "Run 'cargo clippy -- -W missing-docs' for details"
else
echo "â
All public items have documentation"
fi
- name: Upload quality report
uses: actions/upload-artifact@v4
with:
name: docs-quality-report
path: doc-coverage.txt
if: always()
docs-summary:
name: Documentation Summary
runs-on: ubuntu-latest
needs: [check-docs, build-docs, deploy-docs, docs-quality]
if: always()
steps:
- name: Generate documentation summary
run: |
echo "# đ Documentation Build Summary" > docs-summary.md
echo "" >> docs-summary.md
echo "## Job Results" >> docs-summary.md
echo "- **Check Docs**: ${{ needs.check-docs.result }}" >> docs-summary.md
echo "- **Build Docs**: ${{ needs.build-docs.result }}" >> docs-summary.md
echo "- **Deploy Docs**: ${{ needs.deploy-docs.result }}" >> docs-summary.md
echo "- **Quality Check**: ${{ needs.docs-quality.result }}" >> docs-summary.md
echo "" >> docs-summary.md
if [ "${{ github.ref }}" = "refs/heads/main" ] && [ "${{ needs.deploy-docs.result }}" = "success" ]; then
echo "## đ Documentation Deployed" >> docs-summary.md
echo "The documentation has been successfully built and deployed to GitHub Pages." >> docs-summary.md
echo "" >> docs-summary.md
fi
echo "## đ Resources" >> docs-summary.md
echo "- [API Documentation](https://docs.rs/threatflux-cache)" >> docs-summary.md
echo "- [Crates.io](https://crates.io/crates/threatflux-cache)" >> docs-summary.md
echo "- [GitHub Repository](https://github.com/ThreatFlux/threatflux-cache)" >> docs-summary.md
echo "" >> docs-summary.md
echo "Summary generated on: $(date)" >> docs-summary.md
- name: Upload summary
uses: actions/upload-artifact@v4
with:
name: docs-build-summary
path: docs-summary.md