# Facilitator Setup Guide - The Great Print Project This guide helps workshop facilitators set up the cloud-based multiplayer Git module. ## Overview The Great Print Project is a collaborative Git exercise where pairs of students work together on a shared repository hosted on your Gitea server at **https://git.frod.dk/multiplayer**. **What participants will do:** - Clone a real repository from your server - Collaborate with partners on shared branches - Deliberately create and resolve merge conflicts - Create pull requests and review code - Experience the full collaborative Git workflow --- ## Prerequisites ### Gitea Server Setup You should have: - Gitea running at https://git.frod.dk/multiplayer - Admin access to create repositories and users - HTTPS or SSH access enabled for Git operations **Need to set up Gitea?** See the main workshop's `GITEA-SETUP.md` for Docker + Cloudflare Tunnel instructions. ### Workshop Materials Participants need: - Access to the module README in `01_essentials/09-multiplayer/README.md` - Git installed (version 2.23+) - Python 3.6+ (to run the print project) - Text editor --- ## Pre-Workshop Setup ### Step 1: Create User Accounts Create individual Gitea accounts for each participant. **Recommended naming:** - `student01`, `student02`, `student03`, etc. - Or use their real names/emails if preferred **Two approaches:** **Option A: Manual account creation** 1. Go to Gitea admin panel 2. Create users one by one 3. Set initial passwords (students can change later) 4. Provide credentials to students **Option B: Self-registration** (if you trust your network) 1. Enable self-registration in Gitea settings 2. Provide registration URL to students 3. They create their own accounts 4. You verify and approve accounts **Access tokens (recommended for HTTPS):** - Have students create personal access tokens after logging in - Settings → Applications → Generate New Token - Token needs `repo` scope - Students use token as password when pushing/pulling ### Step 2: Create the Repository Create the shared repository: **great-print-project** **Via Gitea web UI:** 1. Log in as admin or organization account 2. Click "+" → "New Repository" 3. **Name:** `great-print-project` 4. **Owner:** `multiplayer` (organization) or your admin account 5. **Visibility:** Private (only visible to students you add) 6. **Initialize:** Check "Initialize this repository with selected files" 7. **README:** Yes 8. **License:** None 9. **.gitignore:** Python 10. Click "Create Repository" **Via command line (alternative):** ```bash # Create local directory mkdir great-print-project cd great-print-project # Initialize git git init # Add files (see Step 3) git add . git commit -m "Initial commit: The Great Print Project" # Create bare repo on server ssh user@git.frod.dk cd /path/to/gitea/repositories/multiplayer git init --bare great-print-project.git exit # Push to server git remote add origin git@git.frod.dk:multiplayer/great-print-project.git git push -u origin main ``` ### Step 3: Add Starter Code to Repository Commit these four files to the repository: #### File 1: main.py ```python #!/usr/bin/env python3 """ The Great Print Project A collaborative Git exercise When everyone completes their assigned functions, this program will print the complete alphabet and numbers! """ from letters import print_letters from numbers import print_numbers def main(): print("=" * 50) print(" THE GREAT PRINT PROJECT") print("=" * 50) print("\nLetters:") print_letters() print() # New line after letters print("\nNumbers:") print_numbers() print() # New line after numbers print("\n" + "=" * 50) print(" PROJECT COMPLETE!") print("=" * 50) if __name__ == "__main__": main() ``` #### File 2: letters.py ```python """ Letter Printing Functions Each pair completes their assigned functions. Expected output: A B C D E F G H I J K L M N O P Q R S T U V W X Y Z """ def print_a(): """Print letter A - EXAMPLE (already completed)""" print("A", end=" ") def print_b(): # TODO: Pair 1 - implement this function pass def print_c(): # TODO: Pair 1 - implement this function pass def print_d(): # TODO: Pair 1 - implement this function pass def print_e(): # TODO: Pair 2 - implement this function pass def print_f(): # TODO: Pair 2 - implement this function pass def print_g(): # TODO: Pair 2 - implement this function pass def print_h(): # TODO: Pair 3 - implement this function pass def print_i(): # TODO: Pair 3 - implement this function pass def print_j(): # TODO: Pair 3 - implement this function pass def print_k(): # TODO: Pair 4 - implement this function pass def print_l(): # TODO: Pair 4 - implement this function pass def print_m(): # TODO: Pair 4 - implement this function pass def print_n(): # TODO: Pair 5 - implement this function pass def print_o(): # TODO: Pair 5 - implement this function pass def print_p(): # TODO: Pair 5 - implement this function pass def print_q(): # TODO: Pair 6 - implement this function pass def print_r(): # TODO: Pair 6 - implement this function pass def print_s(): # TODO: Pair 6 - implement this function pass def print_t(): # TODO: Pair 7 - implement this function pass def print_u(): # TODO: Pair 7 - implement this function pass def print_v(): # TODO: Pair 7 - implement this function pass def print_w(): # TODO: Pair 8 - implement this function pass def print_x(): # TODO: Pair 8 - implement this function pass def print_y(): # TODO: Pair 8 - implement this function pass def print_z(): # TODO: Pair 9 - implement this function pass def print_letters(): """Print all letters A-Z""" print_a() print_b() print_c() print_d() print_e() print_f() print_g() print_h() print_i() print_j() print_k() print_l() print_m() print_n() print_o() print_p() print_q() print_r() print_s() print_t() print_u() print_v() print_w() print_x() print_y() print_z() ``` #### File 3: numbers.py ```python """ Number Printing Functions Each pair completes their assigned functions. Expected output: 0 1 2 3 4 5 6 7 8 9 """ def print_0(): # TODO: Pair 9 - implement this function pass def print_1(): # TODO: Pair 10 - implement this function pass def print_2(): # TODO: Pair 10 - implement this function pass def print_3(): # TODO: Pair 10 - implement this function pass def print_4(): # TODO: Pair 11 - implement this function pass def print_5(): # TODO: Pair 11 - implement this function pass def print_6(): # TODO: Pair 11 - implement this function pass def print_7(): # TODO: Pair 12 - implement this function pass def print_8(): # TODO: Pair 12 - implement this function pass def print_9(): # TODO: Pair 12 - implement this function pass def print_numbers(): """Print all numbers 0-9""" print_0() print_1() print_2() print_3() print_4() print_5() print_6() print_7() print_8() print_9() ``` #### File 4: assignments.md ```markdown # Pair Assignments ## How This Works Each pair is assigned 3 functions to implement. You'll work together on a shared branch. **Important:** Check with your facilitator for your pair number and assignment! --- ## Assignments ### Pair 1 - **Functions:** `print_b()`, `print_c()`, `print_d()` - **File:** `letters.py` - **Branch:** `pair-1-bcd` ### Pair 2 - **Functions:** `print_e()`, `print_f()`, `print_g()` - **File:** `letters.py` - **Branch:** `pair-2-efg` ### Pair 3 - **Functions:** `print_h()`, `print_i()`, `print_j()` - **File:** `letters.py` - **Branch:** `pair-3-hij` ### Pair 4 - **Functions:** `print_k()`, `print_l()`, `print_m()` - **File:** `letters.py` - **Branch:** `pair-4-klm` ### Pair 5 - **Functions:** `print_n()`, `print_o()`, `print_p()` - **File:** `letters.py` - **Branch:** `pair-5-nop` ### Pair 6 - **Functions:** `print_q()`, `print_r()`, `print_s()` - **File:** `letters.py` - **Branch:** `pair-6-qrs` ### Pair 7 - **Functions:** `print_t()`, `print_u()`, `print_v()` - **File:** `letters.py` - **Branch:** `pair-7-tuv` ### Pair 8 - **Functions:** `print_w()`, `print_x()`, `print_y()` - **File:** `letters.py` - **Branch:** `pair-8-wxy` ### Pair 9 - **Functions:** `print_z()`, `print_0()`, `print_1()` - **Files:** `letters.py`, `numbers.py` - **Branch:** `pair-9-z01` ### Pair 10 - **Functions:** `print_2()`, `print_3()`, `print_4()` - **File:** `numbers.py` - **Branch:** `pair-10-234` ### Pair 11 - **Functions:** `print_5()`, `print_6()`, `print_7()` - **File:** `numbers.py` - **Branch:** `pair-11-567` ### Pair 12 - **Functions:** `print_8()`, `print_9()` - **File:** `numbers.py` - **Branch:** `pair-12-89` --- ## Example Implementation ```python def print_a(): """Print letter A - EXAMPLE (already completed)""" print("A", end=" ") ``` **Your functions should follow the same pattern:** ```python def print_x(): """Print letter/number X""" print("X", end=" ") ``` --- ## Testing After implementing your functions, test with: ```bash python main.py ``` You should see your letters/numbers in the output! --- ## Questions? Ask your facilitator for: - Your pair number - Your Gitea credentials - Help with authentication setup - Any Git or Python issues ``` #### File 5: README.md (in repository) ```markdown # The Great Print Project 🎯 A collaborative Git exercise for learning teamwork with version control! ## Goal When everyone completes their assigned functions, running `python main.py` will print: ``` ================================================== THE GREAT PRINT PROJECT ================================================== Letters: A B C D E F G H I J K L M N O P Q R S T U V W X Y Z Numbers: 0 1 2 3 4 5 6 7 8 9 ================================================== PROJECT COMPLETE! ================================================== ``` ## Your Mission 1. Find your pair assignment in `assignments.md` 2. Clone this repository 3. Create your feature branch 4. Implement your assigned functions 5. Practice collaboration: push, pull, resolve conflicts 6. Create a pull request 7. Celebrate when your code is merged! ## Quick Start ```bash # Clone the repository git clone https://git.frod.dk/multiplayer/great-print-project.git cd great-print-project # Check your assignment cat assignments.md # Create your branch (replace X with your pair number) git switch -c pair-X-feature # Edit your file (letters.py or numbers.py) # Implement your functions # Test it python main.py # Commit and push git add . git commit -m "Implement print_x() functions" git push -u origin pair-X-feature ``` ## Files - **main.py** - Orchestrator (runs the whole program) - **letters.py** - Functions for printing A-Z - **numbers.py** - Functions for printing 0-9 - **assignments.md** - See which functions your pair should implement ## Need Help? See the module README in the workshop repository for detailed step-by-step instructions! **Happy Collaborating! 🚀** ``` **Commit these files:** ```bash git add main.py letters.py numbers.py assignments.md README.md git commit -m "Add Great Print Project starter code" git push origin main ``` ### Step 4: Grant Student Access Add students as collaborators with write access: **Via Gitea web UI:** 1. Go to repository → Settings → Collaborators 2. Add each student account 3. Set permission level: **Write** (allows push, pull, branch creation) **Important:** Students need **Write** access to: - Create branches - Push commits - Create pull requests ### Step 5: Configure Branch Protection (Optional) To prevent accidental pushes to main: 1. Repository → Settings → Branches 2. Add protection rule for `main` branch 3. Settings: - **Block direct pushes:** Yes (requires pull requests) - **Require PR reviews:** Optional (you can review PRs yourself) - **Auto-merge:** Disabled (you merge manually or students do) This ensures students: - MUST use feature branches - MUST create pull requests - Can't accidentally break main **For beginners:** Consider allowing students to merge their own PRs after approval to complete the full workflow. ### Step 6: Test the Setup Before the workshop, test as a student would: ```bash # Clone as a test student git clone https://git.frod.dk/multiplayer/great-print-project.git cd great-print-project # Run the program python main.py # Should show only "A" with missing letters/numbers # Create test branch git switch -c test-branch # Edit letters.py, add print_b() def print_b(): print("B", end=" ") # Commit and push git add letters.py git commit -m "Test commit" git push -u origin test-branch # Create test pull request # (Do this via web UI) # Clean up test branch after git push origin --delete test-branch ``` --- ## During the Workshop ### Pairing Students **Strategies for assigning pairs:** **Option 1: Random pairing** - Use a random number generator - Pair students as they arrive **Option 2: Skill-based pairing** - Mix experienced and beginner students - Balance pair capabilities **Option 3: Let them choose** - Students pick their own partners - Good for building team dynamics **Announce pairs clearly:** - Write on board/screen: "Pair 1: Alice & Bob" - Provide printed assignment sheet - Update `assignments.md` in repo if needed ### Timeline **Suggested schedule for 2-hour session:** - **0:00-0:10** (10 min): Introduction, distribute credentials - **0:10-0:20** (10 min): Students clone repo, verify access - **0:20-0:35** (15 min): Part 1 - Getting Started - **0:35-0:55** (20 min): Part 2 - First Contribution - **0:55-1:25** (30 min): Part 3 - Conflict Exercise (key learning!) - **1:25-1:45** (20 min): Part 4 - Pull Requests - **1:45-2:00** (15 min): Part 5 - Syncing, Q&A, wrap-up ### Monitoring Progress **Use Gitea to track:** 1. **Branches created:** Repository → Branches - Should see `pair-1-bcd`, `pair-2-efg`, etc. 2. **Commits:** Repository → Commits - Each pair should have multiple commits 3. **Pull requests:** Repository → Pull Requests - Should see one PR per pair **Walk around the room:** - Check screens for conflict markers - Ask pairs how they're resolving conflicts - Ensure both partners are engaged **Common issues to watch for:** - Partners not using the same branch name - Forgetting to pull before pushing - Not removing conflict markers completely - Committing to main instead of feature branch ### Managing Pull Requests **Your role:** **Option A: Review and merge yourself** - Teaches students what good reviews look like - Ensures quality before merging - More facilitator work **Option B: Students merge their own** - More autonomous learning - Students experience complete workflow - Risk of messy main branch **Recommended approach:** 1. First 2-3 PRs: You review and merge (demonstrate good practices) 2. Remaining PRs: Students review each other, you approve 3. Students can merge after approval **What to check in PR reviews:** - Functions implemented correctly - No conflict markers in code - Code follows pattern (e.g., `print("X", end=" ")`) - Meaningful commit messages ### Handling Problems **Common issues and solutions:** **Problem: "I can't push!"** - Check they're authenticated (token or SSH key) - Check they pulled latest changes first - Check branch name matches their partner's **Problem: "Merge conflict won't resolve!"** - Walk through Part 3 step-by-step with them - Show them the conflict markers - Verify they removed ALL markers - Run `python main.py` together to test **Problem: "We both committed to main!"** - Have them create proper feature branch - Use `git cherry-pick` to move commits - Reset main to origin/main **Problem: "GitHub Desktop / GUI tool shows something different"** - Recommend command line for this exercise - GUIs can hide important details during conflicts ### Celebrating Success When all pairs have merged: ```bash git pull origin main python main.py ``` **Everyone should see:** ``` ================================================== THE GREAT PRINT PROJECT ================================================== Letters: A B C D E F G H I J K L M N O P Q R S T U V W X Y Z Numbers: 0 1 2 3 4 5 6 7 8 9 ================================================== PROJECT COMPLETE! ================================================== ``` **Take a screenshot!** Share it with the class. This is a genuine collaborative achievement. --- ## Post-Workshop ### Cleanup (Optional) **Keep the repository for future workshops:** - Delete all feature branches: `git push origin --delete pair-1-bcd` (etc.) - Reset main to initial state - Reuse for next cohort **Archive the session:** - Export final repository state - Take screenshots of successful PRs - Save for portfolio/examples ### Student Takeaways Provide students: - Link to repository (they can clone for reference) - Completion certificate (if applicable) - Next steps: contributing to open source, Git resources --- ## Troubleshooting ### Gitea Server Issues **Problem: Server unreachable** - Check Cloudflare Tunnel is running: `cloudflared tunnel info` - Verify Gitea container is up: `docker ps` - Check firewall rules **Problem: SSH not working** - Verify SSH port is exposed in docker-compose.yml - Check Cloudflare Tunnel config includes SSH - Test: `ssh -T git@git.frod.dk` **Problem: HTTPS clone fails** - Check certificate validity - Try `GIT_SSL_NO_VERIFY=true git clone ...` (temporary workaround) - Configure Gitea to use proper HTTPS certificates ### Authentication Issues **Problem: Students can't log in** - Verify accounts created and active - Reset passwords if needed - Check email verification isn't blocking (disable for workshop) **Problem: Push fails with authentication error** - HTTPS: Ensure students use access token, not password - SSH: Verify keys added to Gitea account - Check repo permissions (must be Write, not Read) ### Git Workflow Issues **Problem: Students create PR but can't merge** - Check branch protection rules - Verify they have Write access - Ensure PR doesn't have conflicts **Problem: Main branch gets messy** - Reset to last good commit: `git reset --hard ` - Force push: `git push --force origin main` (CAREFUL!) - Or start fresh: delete repo, recreate with starter code --- ## Tips for Success ### Before Workshop - Test the entire flow yourself as a student - Prepare credential sheets for each student - Have backup plan if server goes down (local git exercise) - Prepare slides explaining merge conflicts visually ### During Workshop - **Start on time** - respect everyone's schedule - **Pair programming** - ensure both partners engage - **Encourage talking** - best conflicts are resolved by discussion - **Celebrate small wins** - first push, first conflict resolution - **Walk the room** - see screens, answer questions live ### After Workshop - Gather feedback - what worked, what didn't - Note timing - were parts too rushed or too slow? - Archive successful PRs as examples - Plan improvements for next session --- ## Scaling Considerations ### Small Groups (4-8 students, 2-4 pairs) - More hands-on facilitator time - Can review all PRs in detail - Easier to monitor progress ### Medium Groups (10-20 students, 5-10 pairs) - Recommended size - Good mix of collaboration and individual attention - Helps if you have a teaching assistant ### Large Groups (20+ students, 10+ pairs) - Consider multiple repositories (split into groups of 12 pairs max) - Recruit teaching assistants to help monitor - Use breakout rooms (if online) - Automate more (less PR review, more self-merging) --- ## Additional Resources ### For You (Facilitator) - Gitea documentation: https://docs.gitea.io/ - Pro Git book (free): https://git-scm.com/book/en/v2 - Teaching Git: https://git-scm.com/doc ### For Students - Git cheatsheet (included in workshop repo) - Interactive Git tutorial: https://learngitbranching.js.org/ - Oh Shit Git: https://ohshitgit.com/ (recovering from mistakes) --- ## Questions or Issues? This guide should cover most scenarios. If you encounter issues not listed here: 1. Check Gitea logs: `docker logs gitea-container-name` 2. Test with minimal setup (single test student) 3. Consult Gitea documentation 4. Reach out to workshop repository maintainers **Good luck with your workshop! The multiplayer module is where Git skills really come alive.**