# CI Workflows in ai-engineering-from-scratch: GitHub Actions Validation Pipeline

> Explore CI workflows in ai-engineering-from-scratch GitHub Actions. Discover how workflows validate lesson invariants, sync README stats, rebuild site data, and detect documentation drift on every push and PR.

- Repository: [Rohit Ghumare/ai-engineering-from-scratch](https://github.com/rohitg00/ai-engineering-from-scratch)
- Tags: how-to-guide
- Published: 2026-06-17

---

**The repository uses a single GitHub Actions workflow defined in [`.github/workflows/curriculum.yml`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/.github/workflows/curriculum.yml) that runs four distinct jobs—`audit`, `readme-counts-sync`, `site-rebuild`, and `readme-counts-drift`—to validate lesson invariants, auto-fix README statistics, regenerate site data, and detect documentation drift on every push and pull request.**

The `ai-engineering-from-scratch` curriculum repository relies on automated **CI workflows** to maintain consistency across lesson content and documentation. Rather than manual checks, the project uses a single comprehensive workflow file that orchestrates validation, auto-fixing, and site generation tasks. These CI workflows ensure that every lesson follows the curriculum contract while keeping the README and documentation website synchronized with the actual repository structure.

## The Central Workflow Configuration

All automation is contained in [`.github/workflows/curriculum.yml`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/.github/workflows/curriculum.yml). This workflow triggers on every **push** to the `main` branch and on every **pull request** across all branches. The file defines specific job dependencies and conditional execution logic to prevent race conditions when multiple CI runs overlap.

## The Four CI Jobs Explained

### Audit Job – Lesson Invariant Validation

The **`audit`** job runs on every push and pull request to enforce curriculum standards. It executes [`scripts/audit_lessons.py`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/scripts/audit_lessons.py) to verify that each lesson conforms to the required structure.

This validation includes:
- **File layout** compliance per lesson directory
- **Quiz schema** integrity 
- **Test count** verification

According to the source code, the audit job definition begins at line 33 in the workflow file. It uses Python 3.12 and fails the build if any lesson violates the invariant rules.

### Readme Counts Sync – Automated Documentation Fixes

The **`readme-counts-sync`** job runs exclusively on pushes to `main` (starting at line 46). It automatically updates the lesson count tables in [`README.md`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/README.md) to reflect the actual repository state.

The job executes two Python scripts:
1. [`scripts/build_catalog.py`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/scripts/build_catalog.py) – generates a temporary catalog of all lessons
2. `scripts/check_readme_counts.py --fix` – rewrites the count tables in [`README.md`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/README.md)

If the README changes, the workflow commits and pushes the update directly to the `main` branch, ensuring the documentation never displays stale statistics.

### Site Rebuild – Static Site Generation

The **`site-rebuild`** job (defined at line 99) regenerates the documentation website's data file after any README update. It runs only on `main` branch pushes and depends on the completion of `readme-counts-sync`.

The job executes `node site/build.js` to generate [`site/data.js`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/site/data.js), which powers the curriculum's static documentation site. Like the README sync job, it automatically commits changes if the generated file differs from the repository version.

### Readme Counts Drift – Pull Request Validation

The **`readme-counts-drift`** job (line 149) provides safety checks for pull requests without modifying the repository. It runs only on PRs to detect whether the README lesson counts have diverged from the actual lesson catalog.

If drift is detected, the job emits a GitHub warning annotation. This allows contributors to see discrepancies while the `main` branch will auto-heal the counts upon merge via the `readme-counts-sync` job.

## Running CI Checks Locally

You can execute the same validation steps locally before submitting a pull request. Run these commands from the repository root:

```bash

# Validate lesson invariants (same as the audit job)

python3 scripts/audit_lessons.py

# Regenerate and fix README counts (same as readme-counts-sync)

python3 scripts/build_catalog.py
python3 scripts/check_readme_counts.py --fix

# Rebuild site data (same as site-rebuild)

node site/build.js

```

These local commands produce identical results to the CI pipeline, allowing you to debug issues before the GitHub Actions workflow runs.

## Key Files in the CI Pipeline

| File | Purpose |
|------|---------|
| [`.github/workflows/curriculum.yml`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/.github/workflows/curriculum.yml) | Central workflow defining all four jobs and execution logic |
| [`scripts/audit_lessons.py`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/scripts/audit_lessons.py) | Validates lesson structure, quizzes, and test counts |
| [`scripts/build_catalog.py`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/scripts/build_catalog.py) | Generates temporary catalog for README and site generation |
| [`scripts/check_readme_counts.py`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/scripts/check_readme_counts.py) | Validates and updates lesson count tables in README |
| [`site/build.js`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/site/build.js) | Node.js script generating [`site/data.js`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/site/data.js) for the documentation website |

## Summary

- **Single workflow file**: [`.github/workflows/curriculum.yml`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/.github/workflows/curriculum.yml) orchestrates all CI tasks.
- **Four distinct jobs**: `audit`, `readme-counts-sync`, `site-rebuild`, and `readme-counts-drift` handle validation, auto-fixing, site generation, and drift detection.
- **Dual trigger strategy**: Push events to `main` trigger auto-fixing jobs, while pull requests trigger validation-only jobs with warnings.
- **Python 3.12 runtime**: All Python-based validation scripts run under Python 3.12 in the CI environment.
- **Local parity**: The same shell commands used in CI can run locally for pre-commit validation.

## Frequently Asked Questions

### What triggers the CI workflows in ai-engineering-from-scratch?

The workflow triggers on every **push** to the `main` branch and on every **pull request** to any branch. Specific jobs have additional filters—for example, `readme-counts-sync` only runs on `main` branch pushes, while `readme-counts-drift` only runs during pull requests.

### How does the audit job validate lesson content?

The audit job executes [`scripts/audit_lessons.py`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/scripts/audit_lessons.py) to verify **lesson invariants**, including proper file directory layouts, valid quiz schema structures, and minimum test counts per lesson. This ensures every lesson in the curriculum meets the repository's pedagogical and technical standards before merging.

### Why are there separate jobs for README counts on main versus pull requests?

The repository separates concerns to maintain safety and automation. On `main` pushes, `readme-counts-sync` has write permissions to auto-fix and commit updated counts. On pull requests, `readme-counts-drift` runs read-only checks that emit warnings without modifying files, allowing the `main` branch to self-heal documentation after merge.

### Can I run these CI checks locally before submitting a pull request?

Yes. You can execute `python3 scripts/audit_lessons.py` to validate lesson invariants, and `python3 scripts/check_readme_counts.py` to check README synchronization. These commands use the same logic as the GitHub Actions workflow, allowing you to catch errors before the CI pipeline runs.