chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
github: [rohitg00]
|
||||
custom: ["https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/SPONSORS.md"]
|
||||
@@ -0,0 +1,31 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Something in a lesson or on the site is wrong
|
||||
title: "[bug] "
|
||||
labels: bug
|
||||
---
|
||||
|
||||
## Where
|
||||
|
||||
- Phase / lesson: <!-- e.g. Phase 4 · 06-object-detection-yolo -->
|
||||
- File / URL: <!-- e.g. phases/04-computer-vision/06-object-detection-yolo/code/main.py or aiengineeringfromscratch.com/lesson.html?path=... -->
|
||||
|
||||
## What's wrong
|
||||
|
||||
<!-- One-paragraph description. What did you expect vs. what you saw. -->
|
||||
|
||||
## Reproduce
|
||||
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
|
||||
## Environment
|
||||
|
||||
- OS:
|
||||
- Python / Node / other runtime version:
|
||||
- How you ran it (local, Colab, Docker, etc.):
|
||||
|
||||
## Screenshot or logs
|
||||
|
||||
<!-- Drop a screenshot or paste the traceback if you have one. -->
|
||||
@@ -0,0 +1,46 @@
|
||||
---
|
||||
name: New lesson proposal
|
||||
about: Pitch a lesson before writing it
|
||||
title: "[lesson] Phase NN · "
|
||||
labels: new-lesson
|
||||
---
|
||||
|
||||
## Lesson
|
||||
|
||||
- Phase: <!-- e.g. Phase 5 (NLP) -->
|
||||
- Proposed number: <!-- e.g. 03 (lessons are numbered within a phase) -->
|
||||
- Working title:
|
||||
- Type: Build | Learn
|
||||
- Languages: <!-- Python, TypeScript, Rust, Julia -->
|
||||
- Estimated time: <!-- e.g. ~75 min -->
|
||||
|
||||
## Why it belongs
|
||||
|
||||
<!-- Two or three sentences. What can't a learner do without this lesson? Why here in the sequence? -->
|
||||
|
||||
## Prerequisites
|
||||
|
||||
<!-- Which prior lessons does this depend on? -->
|
||||
|
||||
## What the learner ships
|
||||
|
||||
<!-- Every lesson produces a reusable artifact. Which one? -->
|
||||
|
||||
- [ ] Prompt
|
||||
- [ ] Skill
|
||||
- [ ] Agent
|
||||
- [ ] MCP server
|
||||
- [ ] Tool / script
|
||||
|
||||
## Outline
|
||||
|
||||
1. **The Problem** — what pain does this solve?
|
||||
2. **The Concept** — core mental model, no code yet
|
||||
3. **Build It** — from-scratch implementation plan
|
||||
4. **Use It** — which framework / library to show after
|
||||
5. **Ship It** — the artifact to produce
|
||||
6. **Exercises** — 3 proposed
|
||||
|
||||
## Open questions
|
||||
|
||||
<!-- Anything you want input on before starting. -->
|
||||
@@ -0,0 +1,31 @@
|
||||
<!-- Thanks for contributing. Fill out what applies. Delete sections that don't. -->
|
||||
|
||||
## What this PR does
|
||||
|
||||
<!-- One-sentence summary. -->
|
||||
|
||||
## Kind of change
|
||||
|
||||
- [ ] New lesson
|
||||
- [ ] Fix to an existing lesson
|
||||
- [ ] Translation
|
||||
- [ ] New output (prompt, skill, agent, MCP server)
|
||||
- [ ] Docs / website / tooling
|
||||
|
||||
## Checklist
|
||||
|
||||
- [ ] Code runs without errors with the listed dependencies
|
||||
- [ ] No comments in code files (docs explain, code is self-explanatory)
|
||||
- [ ] Built from scratch first, then shown with a framework (for new lessons)
|
||||
- [ ] Lesson folder matches `LESSON_TEMPLATE.md` structure
|
||||
- [ ] ROADMAP.md row for the lesson is a markdown link (`[Name](phases/...)`), not bare text
|
||||
- [ ] One lesson per commit (atomic per-lesson rule)
|
||||
- [ ] Tested locally / code output matches what `docs/en.md` claims
|
||||
|
||||
## Phase / lesson
|
||||
|
||||
<!-- e.g. Phase 5 · 03-tokenizers -->
|
||||
|
||||
## Notes for reviewer
|
||||
|
||||
<!-- Anything surprising, any deviations from the template, open questions. -->
|
||||
@@ -0,0 +1,166 @@
|
||||
name: curriculum
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
paths:
|
||||
- "phases/**"
|
||||
- "scripts/audit_lessons.py"
|
||||
- "scripts/build_catalog.py"
|
||||
- "scripts/check_readme_counts.py"
|
||||
- "README.md"
|
||||
- "ROADMAP.md"
|
||||
- "glossary/**"
|
||||
- "site/build.js"
|
||||
- ".github/workflows/curriculum.yml"
|
||||
pull_request:
|
||||
branches: [main]
|
||||
paths:
|
||||
- "phases/**"
|
||||
- "scripts/audit_lessons.py"
|
||||
- "scripts/build_catalog.py"
|
||||
- "scripts/check_readme_counts.py"
|
||||
- "README.md"
|
||||
- "ROADMAP.md"
|
||||
- "glossary/**"
|
||||
- "site/build.js"
|
||||
- ".github/workflows/curriculum.yml"
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
audit:
|
||||
name: invariant checks
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
|
||||
with:
|
||||
python-version: "3.12"
|
||||
- name: run scripts/audit_lessons.py
|
||||
run: python3 scripts/audit_lessons.py
|
||||
|
||||
readme-counts-sync:
|
||||
name: README counts auto-fix (main only)
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
if: github.event_name == 'push'
|
||||
steps:
|
||||
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
||||
with:
|
||||
ref: ${{ github.ref }}
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
|
||||
with:
|
||||
python-version: "3.12"
|
||||
- name: build ephemeral catalog
|
||||
run: python3 scripts/build_catalog.py
|
||||
- name: sync README counts
|
||||
run: python3 scripts/check_readme_counts.py --fix
|
||||
- name: commit + push if README changed
|
||||
env:
|
||||
BOT_COMMIT_PREFIX: "chore(readme): sync counts"
|
||||
run: |
|
||||
if git diff --quiet README.md; then
|
||||
echo "README.md already in sync"
|
||||
exit 0
|
||||
fi
|
||||
last_msg=$(git log -1 --pretty=%s)
|
||||
if [[ "$last_msg" == "$BOT_COMMIT_PREFIX"* ]]; then
|
||||
echo "last commit was already a bot regen; not pushing to avoid loop"
|
||||
exit 0
|
||||
fi
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||
git add README.md
|
||||
git commit -m "$BOT_COMMIT_PREFIX"
|
||||
# Retry on non-fast-forward when another merge to main races us
|
||||
branch="${GITHUB_REF#refs/heads/}"
|
||||
for attempt in 1 2 3 4 5; do
|
||||
if git push origin "HEAD:${branch}"; then
|
||||
echo "push succeeded on attempt $attempt"
|
||||
exit 0
|
||||
fi
|
||||
echo "push attempt $attempt rejected; rebasing onto origin/${branch}"
|
||||
git fetch origin "${branch}"
|
||||
if ! git rebase "origin/${branch}"; then
|
||||
echo "rebase produced a conflict; aborting and giving up cleanly"
|
||||
git rebase --abort || true
|
||||
exit 0
|
||||
fi
|
||||
sleep "$((attempt * 2))"
|
||||
done
|
||||
echo "push failed after 5 attempts; main will self-heal on next push"
|
||||
exit 0
|
||||
|
||||
site-rebuild:
|
||||
name: site/data.js auto-rebuild (main only)
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
needs: readme-counts-sync
|
||||
if: github.event_name == 'push'
|
||||
steps:
|
||||
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
||||
with:
|
||||
ref: ${{ github.ref }}
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: rebuild site/data.js
|
||||
run: node site/build.js
|
||||
- name: commit + push if site/data.js changed
|
||||
env:
|
||||
BOT_COMMIT_PREFIX: "chore(site): rebuild data.js"
|
||||
run: |
|
||||
if git diff --quiet site/data.js; then
|
||||
echo "site/data.js already in sync"
|
||||
exit 0
|
||||
fi
|
||||
last_msg=$(git log -1 --pretty=%s)
|
||||
if [[ "$last_msg" == "$BOT_COMMIT_PREFIX"* ]]; then
|
||||
echo "last commit was already a bot regen; not pushing to avoid loop"
|
||||
exit 0
|
||||
fi
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||
git add site/data.js
|
||||
git commit -m "$BOT_COMMIT_PREFIX"
|
||||
branch="${GITHUB_REF#refs/heads/}"
|
||||
for attempt in 1 2 3 4 5; do
|
||||
if git push origin "HEAD:${branch}"; then
|
||||
echo "push succeeded on attempt $attempt"
|
||||
exit 0
|
||||
fi
|
||||
echo "push attempt $attempt rejected; rebasing onto origin/${branch}"
|
||||
git fetch origin "${branch}"
|
||||
if ! git rebase "origin/${branch}"; then
|
||||
echo "rebase produced a conflict; aborting and giving up cleanly"
|
||||
git rebase --abort || true
|
||||
exit 0
|
||||
fi
|
||||
sleep "$((attempt * 2))"
|
||||
done
|
||||
echo "push failed after 5 attempts; main will self-heal on next push"
|
||||
exit 0
|
||||
|
||||
readme-counts-drift:
|
||||
name: README.md counts drift advisory
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'pull_request'
|
||||
steps:
|
||||
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
|
||||
with:
|
||||
python-version: "3.12"
|
||||
- name: build ephemeral catalog
|
||||
run: python3 scripts/build_catalog.py
|
||||
- name: check README counts
|
||||
run: |
|
||||
if ! python3 scripts/check_readme_counts.py; then
|
||||
echo "::warning::README.md counts drift detected. Main will self-heal on merge."
|
||||
fi
|
||||
Reference in New Issue
Block a user