Docs-as-Code: Treat Documentation Like Software
Docs-as-code means applying software engineering practices — version control, automated testing, code review, CI/CD — to documentation. Instead of writing docs in a CMS and publishing manually, you write in plain-text formats, store files in Git, and automate the build and deploy pipeline.
Documentation-as-code is the practice of writing, reviewing, and publishing documentation using the same tools and workflows used for software development. This approach ensures documentation stays in sync with code, reduces manual publishing errors, and allows developers to contribute to docs without leaving their editor.
At DodaTech, we use docs-as-code to maintain documentation for Doda Browser, DodaZIP, and Durga Antivirus Pro — all published through the same Hugo-based pipeline you’re reading now.
Docs-as-Code Workflow
flowchart LR
A[Write in Markdown] --> B[Git Commit & PR]
B --> C[Lint with Vale/markdownlint]
C --> D[Peer Review]
D --> E[Merge to Main]
E --> F[CI Build]
F --> G[Deploy to Production]
G --> H[Monitor & Iterate]
A:::current
classDef current fill:#f90,color:#fff,stroke:#333,stroke-width:2px
Why Docs-as-Code Matters
Traditional documentation workflows are broken. Content lives in Google Docs, Confluence, or WordPress — separate from the code it describes. When code changes, docs become outdated. The docs-as-code approach solves this:
Version control: Every change to documentation is tracked in Git. You can see who changed what, when, and why. Rollback is a single command.
Automation: Build, lint, and deploy docs automatically when code changes. No manual steps, no forgotten updates.
Review workflow: Docs go through the same pull request process as code. Reviewers check accuracy, clarity, and formatting before merge.
Developer adoption: Developers already know Git, Markdown, and CI/CD. Docs-as-code removes the barrier of learning a CMS.
Key Technologies
Markdown and AsciiDoc
Markdown is the most popular format for docs-as-code. It’s simple, readable, and supported by every static site generator:
# API Authentication
To authenticate, include an `Authorization` header:
```bash
curl -H "Authorization: Bearer YOUR_TOKEN" https://api.example.com/v1/usersNote: Tokens expire after 24 hours. Use the /auth/refresh endpoint to get a new one.
AsciiDoc offers more features — cross-references, attributes, include directives — making it better for large documentation sets:
```asciidoc
= API Authentication
To authenticate, include an pass:quotes[`Authorization`] header:
[source,bash]
----
curl -H "Authorization: Bearer YOUR_TOKEN" https://api.example.com/v1/users
----
NOTE: Tokens expire after 24 hours. Use the <<auth-refresh>> endpoint.Static Site Generators
| Tool | Language | Best For |
|---|---|---|
| Hugo | Go | Performance, single binary, multilingual |
| Docusaurus | React | Open source projects, versioned docs |
| MkDocs | Python | Python projects, simplicity |
| Jekyll | Ruby | GitHub Pages integration |
Doc Linters
Linting ensures consistency. Two essential tools:
Vale — a prose linter that enforces style rules:
vale docs/api-documentation.md
# docs/api-documentation.md
# 1:1 error 'login' is informal. Use 'sign in' (login)
# 45:12 warning Use 'can' instead of 'may' for permission (can-may)markdownlint — checks Markdown formatting:
markdownlint content/ --fix
# MD009 Trailing spaces (line 34)
# MD025 Multiple top-level headings (line 1, 2)Setting Up a Docs-as-Code Pipeline
1. Initialize the Repository
mkdir project-docs && cd project-docs
git init
echo "node_modules/" > .gitignore
mkdir -p content/ static/ layouts/2. Add a CI Workflow
# .github/workflows/docs.yml
name: Deploy Docs
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: peaceiris/actions-hugo@v2
with:
hugo-version: '0.134.0'
- name: Lint
run: |
npm install -g markdownlint-cli
markdownlint content/
- name: Build
run: hugo --minify
- name: Deploy
if: github.ref == 'refs/heads/main'
run: ./deploy.sh3. Automate Vale in CI
- name: Vale Lint
uses: errata-ai/vale-action@v2
with:
files: content/Docs Review Workflow
Pull requests aren’t just for code. Docs benefit from the same review process:
- Writer creates a branch:
git checkout -b docs/add-authentication-guide - Writer commits changes and opens a PR
- CI runs linters automatically
- Reviewers check: accuracy, clarity, grammar, formatting
- PR is merged and docs deploy automatically
Testing Documentation
Just like code, docs should be tested:
Link checking: Ensure no broken links:
npm install -g broken-link-checker
blc https://example.com/docs/ -roSpell checking: Catch typos before deploy:
npm install -g cspell
cspell "content/**/*.md"Build validation: Ensure the site builds without errors:
hugo --gc --minify 2>&1 | grep -i error && exit 1 || exit 0Common Mistakes
1. Using Proprietary Formats
Writing docs in Google Docs or Confluence makes version control impossible. Always use plain-text formats like Markdown or AsciiDoc.
2. Skipping the Lint Step
Without automated linting, style inconsistencies creep in — “click here” vs “select here”, “login” vs “sign in”. Linters catch these every time.
3. Manual Deployments
Deploying docs by copying files to a server guarantees drift. The docs on production will inevitably differ from what’s in the repository.
4. No Review Process
Docs pushed directly to main without review contain errors, inconsistencies, and omissions that a second set of eyes would catch.
5. Keeping Docs in a Separate Repo
While a separate docs repo works, co-locating docs with code in a monorepo ensures docs change alongside the code they describe.
6. Ignoring Link Maintenance
Links rot. Without automated link checking, readers encounter 404s. Run a link checker in CI.
7. No Style Guide
Without a style guide, every writer uses different terminology, tone, and formatting. This confuses readers and erodes trust.
Practice Questions
1. What is docs-as-code and why does it matter?
It’s the practice of writing documentation using software development tools and workflows — version control, CI/CD, linting, code review. It keeps docs in sync with code, automates publishing, and reduces errors.
2. What are three essential tools in a docs-as-code pipeline?
A static site generator (Hugo, Docusaurus, MkDocs), a linter (Vale, markdownlint), and a CI/CD platform (GitHub Actions, GitLab CI).
3. Why should docs go through a pull request review?
Reviews catch factual errors, unclear language, formatting issues, and omissions. They also ensure the review process is documented and repeatable.
4. How do you test documentation automatically?
Link checking (broken-link-checker), spell checking (cspell), build validation, and prose linting (Vale).
5. Challenge: Set up a complete docs-as-code pipeline for a small project. Initialize a Hugo site, configure markdownlint and Vale in CI, and set up automated deployment to GitHub Pages. Document every step.
Real-World Task
Take an existing README or documentation page from an open source project. Rewrite it in Markdown, add a Vale configuration that enforces Google Developer Documentation Style Guide rules, and create a GitHub Actions workflow that lints and builds it.
FAQ
What’s Next
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro