diff --git a/.github/workflows/tinytorch-preview-dev.yml b/.github/workflows/tinytorch-preview-dev.yml index 2412ee77c..5cbb8bc9a 100644 --- a/.github/workflows/tinytorch-preview-dev.yml +++ b/.github/workflows/tinytorch-preview-dev.yml @@ -50,6 +50,13 @@ jobs: pip install --upgrade pip pip install -r site/requirements.txt + - name: ๐Ÿ‘ฅ Generate team page from contributors + working-directory: tinytorch/site + run: | + echo "๐Ÿ‘ฅ Generating team page from .all-contributorsrc..." + python3 scripts/generate_team.py + echo "โœ… Team page generated" + - name: ๐Ÿ”จ Build Jupyter Book working-directory: tinytorch/site run: | diff --git a/.github/workflows/tinytorch-publish-live.yml b/.github/workflows/tinytorch-publish-live.yml index 060fc3d8d..342e73ba7 100644 --- a/.github/workflows/tinytorch-publish-live.yml +++ b/.github/workflows/tinytorch-publish-live.yml @@ -367,6 +367,13 @@ jobs: pip install --upgrade pip pip install -r site/requirements.txt + - name: ๐Ÿ‘ฅ Generate team page from contributors + working-directory: tinytorch/site + run: | + echo "๐Ÿ‘ฅ Generating team page from .all-contributorsrc..." + python3 scripts/generate_team.py + echo "โœ… Team page generated" + - name: ๐Ÿ”จ Build Jupyter Book working-directory: tinytorch/site run: | diff --git a/tinytorch/site/scripts/generate_team.py b/tinytorch/site/scripts/generate_team.py new file mode 100644 index 000000000..7baa4153a --- /dev/null +++ b/tinytorch/site/scripts/generate_team.py @@ -0,0 +1,428 @@ +#!/usr/bin/env python3 +""" +Generate team.md from .all-contributorsrc for TinyTorch site. + +This script reads the .all-contributorsrc file and generates the team.md page +with all contributors automatically. Run this before building the site. + +Usage: + python3 scripts/generate_team.py +""" + +import json +from pathlib import Path + +# Contribution type to emoji mapping (matches all-contributors spec) +CONTRIBUTION_EMOJIS = { + "bug": "๐Ÿชฒ", + "code": "๐Ÿง‘โ€๐Ÿ’ป", + "doc": "โœ๏ธ", + "design": "๐ŸŽจ", + "ideas": "๐Ÿง ", + "review": "๐Ÿ”Ž", + "test": "๐Ÿงช", + "tool": "๐Ÿ› ๏ธ", + "content": "โœ๏ธ", + "maintenance": "๐Ÿ› ๏ธ", +} + +# Special roles for staff members (not auto-generated) +STAFF_MEMBERS = { + "profvjreddi": { + "role": "๐Ÿค“ Nerdy Professor ยท Harvard University", + "bio": "Gordon McKay Professor of Electrical Engineering at Harvard. Passionate about creating the next generation of AI engineers.", + "is_lead": True, + }, + "AndreaMattiaGaravagno": { + "role": "๐Ÿงญ Tech Lead", + "is_staff": True, + }, + "kai4avaya": { + "role": "๐ŸŒ Web Wizard", + "is_staff": True, + }, +} + +# Non-GitHub staff (manually added) +MANUAL_STAFF = [ + { + "name": "Kari Janapareddi", + "role": "๐Ÿ‘‘ Chief of Staff", + "avatar_url": "https://ui-avatars.com/api/?name=Kari+Janapareddi&background=f97316&color=fff&size=120", + "profile": "#", + }, +] + + +def load_contributors(rc_path: Path) -> list[dict]: + """Load contributors from .all-contributorsrc file.""" + if not rc_path.exists(): + print(f"Warning: {rc_path} not found") + return [] + + with open(rc_path) as f: + data = json.load(f) + + return data.get("contributors", []) + + +def get_contribution_emojis(contributions: list[str]) -> str: + """Convert contribution types to emoji string.""" + emojis = [] + for contrib in contributions: + if contrib in CONTRIBUTION_EMOJIS: + emojis.append(CONTRIBUTION_EMOJIS[contrib]) + return " ".join(emojis) + + +def generate_team_md(contributors: list[dict]) -> str: + """Generate the team.md content from contributors list.""" + + # Separate lead, staff, and regular contributors + lead = None + staff = [] + regular = [] + + for c in contributors: + login = c.get("login", "") + if login in STAFF_MEMBERS: + info = STAFF_MEMBERS[login] + c["_role"] = info.get("role", "") + c["_bio"] = info.get("bio", "") + if info.get("is_lead"): + lead = c + elif info.get("is_staff"): + staff.append(c) + else: + regular.append(c) + else: + regular.append(c) + + # Sort regular contributors by number of contributions (descending) + regular.sort(key=lambda x: len(x.get("contributions", [])), reverse=True) + + # Build the markdown + lines = [] + + # Header + lines.append("# Team") + lines.append("") + lines.append("**Meet the people building TinyTorch.**") + lines.append("") + lines.append("TinyTorch is built by a passionate community dedicated to making ML systems education accessible to everyone.") + lines.append("") + + # CSS styles + lines.append("```{raw} html") + lines.append(CSS_STYLES) + lines.append("") + + # Role legend + lines.append('
') + lines.append(' ๐Ÿชฒ Bug Hunter') + lines.append(' ๐Ÿง‘โ€๐Ÿ’ป Code Warrior') + lines.append(' โœ๏ธ Documentation') + lines.append(' ๐ŸŽจ Design') + lines.append(' ๐Ÿง  Ideas') + lines.append(' ๐Ÿ”Ž Reviewer') + lines.append(' ๐Ÿงช Testing') + lines.append(' ๐Ÿ› ๏ธ Tooling') + lines.append('
') + lines.append("") + + # Team grid + lines.append('
') + + # Lead + if lead: + avatar = lead.get("avatar_url", "") + if "?" not in avatar: + avatar += "?v=4&s=200" + name = lead.get("name", lead.get("login", "")) + profile = lead.get("profile", f"https://github.com/{lead.get('login', '')}") + emojis = get_contribution_emojis(lead.get("contributions", [])) + + lines.append('
') + lines.append(f' ') + lines.append(f' {name}') + lines.append(' ') + lines.append('
') + lines.append(f'
{name}
') + lines.append(f'
{lead.get("_role", "")}
') + lines.append(f'
{lead.get("_bio", "")}
') + lines.append(f'
{emojis}
') + lines.append('
') + lines.append('
') + lines.append("") + + # Staff section + if staff or MANUAL_STAFF: + lines.append('
Community Staff
') + lines.append("") + lines.append('
') + + for s in staff: + avatar = s.get("avatar_url", "") + if "?" not in avatar: + avatar += "?v=4&s=120" + name = s.get("name", s.get("login", "")) + profile = s.get("profile", f"https://github.com/{s.get('login', '')}") + role = s.get("_role", "") + + lines.append(f' ') + lines.append(f' {name}') + lines.append(f'
{name}
') + lines.append(f'
{role}
') + lines.append('
') + lines.append("") + + # Add manual staff + for s in MANUAL_STAFF: + lines.append(f' ') + lines.append(f' {s[') + lines.append(f'
{s["name"]}
') + lines.append(f'
{s["role"]}
') + lines.append('
') + lines.append("") + + lines.append('
') + lines.append("") + + # Contributors section + if regular: + lines.append('
Contributors
') + + for c in regular: + avatar = c.get("avatar_url", "") + if "?" not in avatar: + avatar += "?v=4&s=160" + name = c.get("name", c.get("login", "")) + profile = c.get("profile", f"https://github.com/{c.get('login', '')}") + emojis = get_contribution_emojis(c.get("contributions", [])) + + lines.append(f' ') + lines.append(f' {name}') + lines.append(f' {name}') + lines.append(f' {emojis}') + lines.append(' ') + + lines.append('
') + lines.append('```') + lines.append("") + + # Footer + lines.append("## Join the Team") + lines.append("") + lines.append("TinyTorch is open source and we welcome contributors of all experience levels!") + lines.append("") + lines.append("**Ways to get involved:**") + lines.append("") + lines.append("- ๐Ÿชฒ **Found a bug?** [Report it on GitHub](https://github.com/harvard-edge/cs249r_book/issues)") + lines.append("- ๐Ÿ’ก **Have an idea?** [Start a discussion](https://github.com/harvard-edge/cs249r_book/discussions)") + lines.append("- ๐Ÿง‘โ€๐Ÿ’ป **Want to contribute code?** [See our contributing guide](https://github.com/harvard-edge/cs249r_book/blob/main/CONTRIBUTING.md)") + lines.append("- โœ๏ธ **Improve documentation?** Submit a pull request") + lines.append("") + lines.append('**Get recognized:** Comment on any issue or PR with `@all-contributors please add @username for bug, code, doc, or ideas`') + lines.append("") + lines.append("") + lines.append("## Contact") + lines.append("") + lines.append("- **GitHub Issues**: [Report bugs or request features](https://github.com/harvard-edge/cs249r_book/issues)") + lines.append("- **GitHub Discussions**: [Ask questions or share ideas](https://github.com/harvard-edge/cs249r_book/discussions)") + lines.append("- **Project Lead**: [Prof. Vijay Janapa Reddi](https://scholar.harvard.edu/vijay-janapa-reddi) ยท Harvard University") + lines.append("") + + return "\n".join(lines) + + +# CSS styles (kept separate for readability) +CSS_STYLES = """""" + + +def main(): + # Find the .all-contributorsrc file + script_dir = Path(__file__).parent + site_dir = script_dir.parent + tinytorch_dir = site_dir.parent + rc_path = tinytorch_dir / ".all-contributorsrc" + + # Load contributors + contributors = load_contributors(rc_path) + if not contributors: + print("No contributors found!") + return 1 + + print(f"Found {len(contributors)} contributors") + + # Generate team.md + content = generate_team_md(contributors) + + # Write to team.md + team_path = site_dir / "team.md" + with open(team_path, "w") as f: + f.write(content) + + print(f"Generated {team_path}") + return 0 + + +if __name__ == "__main__": + exit(main()) diff --git a/tinytorch/site/team.md b/tinytorch/site/team.md index 1a1e358b6..51e2c4655 100644 --- a/tinytorch/site/team.md +++ b/tinytorch/site/team.md @@ -192,9 +192,15 @@ TinyTorch is built by a passionate community dedicated to making ML systems educ
Community Staff
+ + kai +
kai
+
๐ŸŒ Web Wizard
+
+ - Andrea Garavagno -
Andrea Garavagno
+ AndreaMattiaGaravagno +
AndreaMattiaGaravagno
๐Ÿงญ Tech Lead
@@ -204,11 +210,6 @@ TinyTorch is built by a passionate community dedicated to making ML systems educ
๐Ÿ‘‘ Chief of Staff
- - Kai Kleinbard -
Kai Kleinbard
-
๐ŸŒ Web Wizard
-
Contributors
@@ -263,22 +264,22 @@ TinyTorch is built by a passionate community dedicated to making ML systems educ ๐Ÿชฒ - Ng Bo Lin + Ng Bo Lin Ng Bo Lin โœ๏ธ - keo-dara + keo-dara keo-dara ๐Ÿชฒ - Wayne Norman + Wayne Norman Wayne Norman ๐Ÿชฒ - Ilham Rafiqin + Ilham Rafiqin Ilham Rafiqin ๐Ÿชฒ