# What Is the CI/CD Workflow in `.github/workflows/curriculum.yml`? A Complete Technical Guide

> Understand the CI/CD workflow in .github/workflows/curriculum.yml. Automate validation, sync docs, and publish your site securely with this technical guide.

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

---

**The [`curriculum.yml`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/curriculum.yml) workflow automates validation, documentation synchronization, and site publication for the AI engineering curriculum, ensuring every code change passes invariant checks before reaching production.**

The repository `rohitg00/ai-engineering-from-scratch` relies on [`.github/workflows/curriculum.yml`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/.github/workflows/curriculum.yml) to enforce quality standards across its modular curriculum. This GitHub Actions workflow orchestrates **continuous integration** (CI) validation and **continuous delivery** (CD) publishing, preventing broken lessons or stale documentation from merging into the `main` branch. It executes three distinct jobs that verify structural integrity, auto-correct README statistics, and regenerate static site assets.

## Workflow Triggers and Event Handling

The CI/CD workflow responds to **push** and **pull request** events targeting the `main` branch. According to the source code, path filters ensure the workflow runs only when relevant content changes.

- **Push triggers** (lines 4-34): Activate when commits modify `phases/**`, `certifications/**`, `skills/**`, `.claude/skills/**`, or supporting scripts and site files
- **Pull request triggers** (lines 36-69): Apply identical path filters to validate proposed changes before merging

This selective triggering prevents unnecessary CI runs on unrelated file changes while guaranteeing that any modification to lessons, certifications, or validation scripts invokes the full test suite.

## The Three Core Jobs Explained

### The `audit` Job – Invariant Checks and Validation

The `audit` job serves as the repository's quality gate, running on every push and pull request. It executes a comprehensive battery of tests in an Ubuntu runner with Python 3.12 (lines 79-84) to verify curriculum integrity.

**Structural Validation Steps:**

- **[`scripts/audit_lessons.py`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/scripts/audit_lessons.py)** – Validates lesson metadata, file structure, and count consistency (lines 85-86)
- **[`scripts/audit_certifications.py`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/scripts/audit_certifications.py)** – Performs identical validation for certification lessons (lines 87-88)
- **`scripts/backfill_certification_references.py --check`** – Ensures every certification reference exists and is properly linked (lines 89-90)

**Runtime Testing:**

- **Certification lab tests** – Executes every `test_*.py` and [`main.py`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/main.py) under `certifications/claude/lessons` to guarantee runnable examples (lines 91-94)
- **[`scripts/test_skill_artifact_bundles.py`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/scripts/test_skill_artifact_bundles.py)** – Verifies that skill-artifact bundles install correctly without dependency conflicts (lines 95-96)
- **[`site/test_build_artifacts.js`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/site/test_build_artifacts.js)** – Confirms skill bundles render as single lesson outputs (lines 97-98)

**Site and SEO Verification:**

- **`node site/build.js`** – Generates the static site for preview testing (lines 99-100)
- **[`scripts/test_seo_routes.js`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/scripts/test_seo_routes.js)** – Validates that dynamic lesson and certification routes preserve public contracts (lines 101-102)
- **[`scripts/test_agent_readiness.py`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/scripts/test_agent_readiness.py)** – Confirms agent-facing discovery data is complete (lines 103-104)
- **[`scripts/test_agent_negotiation.js`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/scripts/test_agent_negotiation.js)** – Guarantees Markdown negotiation remains cache-safe (lines 105-106)

**Content Integrity Checks:**

- **De-biasing scripts** – `debias_quizzes.py --check` and `debias_certification_questions.py --check` validate answer-position distributions (lines 111-114)
- **i18n synchronization** – `build_readme_i18n.py --check` ensures README translations match the English source (lines 115-116)
- **Directory consistency** – `diff -r skills .claude/skills` enforces that the canonical `skills/` directory never diverges from its Claude mirror (lines 119-124)

All steps run sequentially with **fail-fast** behavior; a single validation failure aborts the workflow and blocks the merge.

### The `readme-counts-sync` Job – Automated Documentation Maintenance

This job executes exclusively on `push` events to `main`, maintaining the repository's human-readable documentation through automated commits.

**The synchronization process:**

1. **[`scripts/build_catalog.py`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/scripts/build_catalog.py)** – Constructs an ephemeral catalog of all curriculum content (lines 39-40)
2. **`scripts/check_readme_counts.py --fix`** – Automatically corrects lesson-count tables in [`README.md`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/README.md) (lines 41-42)
3. **[`scripts/build_readme_i18n.py`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/scripts/build_readme_i18n.py)** – Regenerates translated README versions (lines 43-44)
4. **Bot commit and push** – Commits changes using a bot account with safety guards against infinite loops (lines 45-80)

This self-healing mechanism ensures that the repository's public documentation never becomes stale, even when contributors forget to manually update statistics.

### The `site-rebuild` Job – Continuous Delivery

Running conditionally after `readme-counts-sync` succeeds, this job implements the CD pipeline by publishing updated site assets.

**Deployment steps:**

1. Checkout the current `main` commit (lines 91-94)
2. **`node site/build.js`** – Produces a fresh [`site/data.js`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/site/data.js) consumed by the static site generator (lines 95-96)
3. **Commit and push** – Pushes the new [`site/data.js`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/site/data.js) with a bot prefix, ensuring the live curriculum website reflects the latest content without manual intervention (lines 97-100)

This job provides true **continuous delivery**, deploying site updates immediately after validation passes.

## Local Development and Debugging

Reproduce the CI pipeline locally to catch failures before committing. These commands mirror the workflow's validation logic:

### Run Lesson and Certification Audits

```bash
python3 scripts/audit_lessons.py
python3 scripts/audit_certifications.py

```

### Execute Certification Lab Tests

```bash
find certifications/claude/lessons -path '*/code/tests/test_*.py' -print0 | \
  xargs -0 -r -n1 python3

```

### Validate Skill Bundles and Site Artifacts

```bash
node site/test_build_artifacts.js
node --test site/test_build_artifacts.js

```

### Sync README Counts Locally

```bash
python3 scripts/build_catalog.py
python3 scripts/check_readme_counts.py --fix
python3 scripts/build_readme_i18n.py
git diff --stat

```

### Build Static Site Assets

```bash
node site/build.js

```

Running these scripts locally helps identify structural violations, broken lesson tests, or documentation drift before the workflow triggers.

## Summary

- **Selective triggering** – The workflow runs only on changes to curriculum-relevant paths (`phases/**`, `certifications/**`, `skills/**`), conserving CI resources
- **Zero-trust validation** – The `audit` job treats every push and pull request identically, preventing malicious or broken changes from reaching `main`
- **Self-healing documentation** – The `readme-counts-sync` job auto-corrects README statistics and translations without human intervention
- **Automated deployment** – The `site-rebuild` job generates and publishes [`site/data.js`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/site/data.js), providing continuous delivery for the static curriculum website
- **Deterministic environment** – All jobs use pinned Python 3.12 and clean Ubuntu runners to ensure reproducible builds across CI runs

## Frequently Asked Questions

### What triggers the CI/CD workflow in [`.github/workflows/curriculum.yml`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/.github/workflows/curriculum.yml)?

The workflow triggers on **push** and **pull request** events targeting the `main` branch, but only when modifying specific paths including `phases/**`, `certifications/**`, `skills/**`, `.claude/skills/**`, or related scripts and site files (lines 4-69). This path filtering ensures the workflow runs only when curriculum content or validation tooling changes.

### How does the workflow prevent broken curriculum from being merged?

The `audit` job implements **fail-fast** validation that aborts the entire workflow if any check fails. It verifies lesson metadata through [`audit_lessons.py`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/audit_lessons.py), executes all certification lab tests, validates SEO routes, and checks that skill directories remain synchronized. Because these checks run on every pull request, a single failing test blocks the merge.

### What is the difference between the `audit`, `readme-counts-sync`, and `site-rebuild` jobs?

- **`audit`** runs on every push and PR to validate structural integrity and run tests
- **`readme-counts-sync`** runs only on `main` branch pushes to auto-correct README lesson counts and translations
- **`site-rebuild`** runs after `readme-counts-sync` succeeds to regenerate [`site/data.js`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/site/data.js) and deploy site updates

The three jobs operate sequentially, ensuring validation passes before documentation updates, and documentation updates complete before site deployment.

### How can I run the CI checks locally before pushing?

Execute the audit scripts manually using Python 3.12:

```bash
python3 scripts/audit_lessons.py
python3 scripts/audit_certifications.py
node site/build.js

```

These commands reproduce the core validation steps from the `audit` job, allowing you to fix structural errors or broken tests before the workflow executes.