Start here
Preface: How to Read This Book
Who this book is for, what you'll be able to do after it, and which of the three reading paths fits you.
This book exists for one reason: your first merged pull request should not be a matter of luck. Everything here β the commands, the etiquette, the review workflow, the AI-assisted loop in Chapter 4 β comes from doing it the messy way first and writing down the shortcut.
Who this book is for#
| Reader | You'll get |
|---|---|
| Students & self-taught devs | A repeatable path from zero to a merged PR β no CS degree assumed. |
| Career-switchers | Public proof of skill: merged contributions recruiters can click. |
| Working developers | The unwritten rules of review etiquette and maintaining trust. |
| The AI-curious (Ch 4) | A supervised workflow where an AI agent runs the loop with you. |
Find your path#
- Just curious? Read Chapter 1 and stop β you'll understand what open source is and why it pays.
- Ready to contribute? Chapters 1 β 3: understand, set up, ship your first PR.
- Already contributing? Chapter 4 automates your loop; Chapter 5 builds the reputation.
Prerequisites#
- A laptop with a terminal β every command works on Windows, macOS, and Linux.
- A free GitHub account.
- No prior Git knowledge required; Chapter 2 starts from zero.
- Patience for review comments β Chapter 3 turns them from scary to welcome.
Note
Suggested pace: one chapter per week. Every chapter ends in a concrete outcome β a configured environment, a merged PR, an AI workflow β so progress is visible, not theoretical.Chapter 01
β 5 min read
Introduction to Open Source
What open source platforms actually are, what you gain by contributing, and the GitHub / pull request basics that power every collaboration.
In this chapter you'll learn to
- β Explain what open source platforms are and where they live
- β Name at least five concrete benefits of contributing
- β Describe the fork β PR β merge cycle in your own words
1.1 What Are Open Source Platforms?
Open source means the source code of a program is public. Anyone can read it, learn from it, change it, and share it β legally β under a license chosen by the project's owner.
An open source platform is a place where that code lives and where people collaborate on it. The code itself is stored in a repository (a project folder with full history), and the platform gives contributors the tools to work together: issue trackers, code review, discussions, and automation.
The main platforms#
- GitHub β the largest, where most beginner-friendly projects live. This book uses GitHub.
- GitLab β popular for companies that want built-in hosting and CI/CD.
- Bitbucket β common in teams already using Jira.
- Codeberg & Sourcehut β community-run, non-profit alternatives.
Notice a pattern: every platform above stores Git repositories. Git is the version-control system; the platform is the social layer on top of it.
Open source is already everywhere#
The library you npm install, the browser you're reading this in, the language runtime your app runs on β odds are, all open source. Linux runs most servers and nearly all cloud infrastructure. VS Code, React, Next.js, Python, Firefox β all open source projects with public repositories you can contribute to today.
What "open" really means (and doesn't mean)#
- It means: the code is public, and an open source license (MIT, Apache-2.0, GPLβ¦) grants you rights to use, modify, and distribute it.
- It doesn't mean: anyone can push code directly. Most projects require every change to pass review before it's merged.
- It doesn't mean: unpaid chaos. Many projects are backed by companies (Meta, Microsoft, Google) and maintainers who take the work seriously.
- It doesn't mean: only expert programmers welcome. Documentation, testing, translation, and design are all valid contributions.
Note
Key idea: open source platforms are not just code storage β they're where collaboration happens. The code is public, but the process is disciplined: nothing changes without a reviewed pull request.That process is exactly what the next two sections unpack: what's in it for you, and how a change travels from your laptop into a project everyone uses.
1.2 Benefits of Contributing β What You Get
"Why should I contribute for free?" β the fair question. The honest answer: contributors get far more than they give, especially early in a career.
1. Proof of work that recruiters actually trust#
Anyone can claim skills on a CV. A merged pull request into a project you didn't write cannot be faked β it shows you can read unfamiliar code, follow a process, handle feedback, and deliver. Recruiters and hiring managers increasingly scan GitHub before the interview, and a green contribution graph with real merged PRs stands out far more than a profile full of forked tutorials.
A real example from my own profile: 38 merged pull requests across four major platforms β 21 in google/adk-docs, 7 in openai/openai-agents-python, 3 in openclaw/openclaw, and 1 in n8n-io/n8n-docs. Every one of them is clickable, diffable, and attributed to me β the kind of evidence no resume bullet can match.
2. You learn by reading real production code#
Tutorials show you one person's happy path. Open source shows you how software is built at scale: architecture decisions, edge cases, error handling, testing strategies, and performance work β written by people who ship to millions of users.
- You see how big projects organize files and name things.
- You learn Git workflow the way professionals use it: branches, reviews, reverts, releases.
- You get code review on YOUR code β free mentorship from maintainers who've seen thousands of contributions.
3. A network that compounds#
Every pull request is a conversation with people building things you care about. Consistent contributors get noticed β invited to other projects, recommended for jobs, offered maintainership, or pointed at opportunities before they're posted. Opportunities come from people who've already seen you work.
4. Better habits, automatically#
Projects won't accept vague commits, giant unexplained diffs, or code with no tests. So you learn to write smaller changes, explain your reasoning, and test before shipping β skills that make you stronger in your day job too.
5. You improve tools you depend on#
Hit a bug in a library? Fix it once, and every future user β including you β benefits. That's the closed loop of open source: the tools you rely on get better because the people who rely on them participate.
Contributing isn't charity β it's the fastest on-ramp to being taken seriously as a developer.
Note
Realistic expectation: your first contributions (typos, docs, small fixes) are small. That's normal and valuable. The habit of shipping merged PRs matters more than the size of any single one.1.3 GitHub, Pull Requests & How Code Gets Merged
Before contributing, you need to understand the three core objects and the one workflow that connects them.
Git vs GitHub#
- Git β version control software installed on your computer. It tracks changes to files over time (commits, branches).
- GitHub β a website that hosts Git repositories and adds collaboration tools: issues, pull requests, reviews, CI checks.
- Your workflow: work locally with Git β publish to GitHub β propose changes with a pull request.
The vocabulary in 30 seconds#
- Repository (repo) β one project with its code and history.
- Fork β your personal copy of someone else's repo, under your account.
- Branch β a parallel line of work inside a repo. You never edit
maindirectly. - Commit β a saved snapshot with a message explaining the change.
- Pull Request (PR) β a request asking the project to merge your branch into theirs, with a diff to review.
- Merge β accepting the changes and adding them to the project's history.
How you send a pull request, step by step#
- Fork the repository on GitHub β you now have a copy you can write to.
- Clone it to your machine:
git clone https://github.com/you/repo.git - Create a branch for your change:
git checkout -b fix/typo-in-readme - Make your edits. Keep the change focused on one thing.
- Commit with a clear message:
git commit -m "Fix broken link in README" - Push the branch to your fork:
git push origin fix/typo-in-readme - Open a Pull Request on GitHub β describe what you changed and why, and link the related issue.
How a pull request gets merged#
Once your PR is open, the project's maintainers (and automated checks) take over:
- Automated checks (CI) run your code through tests and linting. Failing checks block the merge.
- A maintainer reviews the diff β the line-by-line comparison of your changes.
- They approve it, or request changes. You push fixes to the same branch and the PR updates automatically.
- Once approved and green, they click Merge β your changes land on the main branch.
- Your branch is deleted, the issue closes, and your name is now part of the project's history.
Note
Most beginner PRs never fail because of code skill β they fail on communication: no description, changes bundled together, or ignoring the project's contributing guidelines. Read the CONTRIBUTING.md before you write a line of code.That's the entire loop: fork β branch β commit β push β pull request β review β merge. Chapter 2 sets up your toolkit, and Chapter 3 walks you through your first real pull request from start to finish.
Chapter 02
β 6 min read
Start Contributing: From Zero to a Working Setup
Get hands-on: fork and clone a real project, configure Git and your dev environment the right way, and find issues that are actually meant for beginners.
In this chapter you'll learn to
- β Fork, clone, and wire up origin/upstream remotes correctly
- β Configure Git identity, authentication, and a project dev environment
- β Find and claim a live good-first-issue the professional way
2.1 Fork and Clone β Getting the Code on Your Machine
Every contribution starts the same way: you need a copy of the project you can edit freely. That's what a fork and a clone give you β in that order.
Why you can't just edit the project directly#
You don't have write access to other people's repositories, and that's by design. Instead of getting permission to push, you make your own copy. The flow is:
- Fork β copy the repo on GitHub's servers, from
their-account/repotoyour-account/repo. Happens in the browser, takes one click. - Clone β download that fork to your computer so you can edit files locally with your own tools.
- You push changes to your fork, then offer them back to the original project with a pull request (Chapter 3).
How to fork a repository#
- Open the project on GitHub (example:
github.com/facebook/react). - Click the Fork button in the top-right.
- Confirm the destination β your own account. Keep the repo name as-is.
- Wait a few seconds. You now have
github.com/your-username/react.
You'll see a note on your fork: *"forked from facebook/react."* That link matters β GitHub uses it to let your pull request target the original project automatically.
How to clone your fork#
On your fork's page, press the green Code button, copy the HTTPS URL, then in your terminal:
git clone https://github.com/your-username/react.gitcd reactβ you're now inside the project.git remote -vβ check your remotes. You should seeoriginpointing at your fork.
Add the original project as upstream#
This is the step beginners skip and regret later. Your fork goes stale β it drifts away from the original as others keep pushing code. Fix it once, upfront:
git remote add upstream https://github.com/facebook/react.gitgit remote -vβ now you have two remotes:origin(your fork) andupstream(the real project).- Sync anytime with
git fetch upstreamthengit merge upstream/main(orgit pull upstream main).
Note
origin = your copy, you push here. upstream = the original, you sync from here. Get these two straight and half of all confusing Git errors disappear.Verify you can run the project#
Before anything else, make sure it works untouched:
- Install dependencies (check the README β usually
npm install,pip install -r requirements.txt, orcargo build). - Run the test suite (
npm test) and the project itself. - If it runs, your setup is correct. If it doesn't, fix that before making changes β otherwise you can't tell your bug from an environment bug.
Never debug your environment and your contribution at the same time. Get the untouched project green first.
2.2 Setting Up Your Git Environment & Dev Setup
Before your first commit, spend ten minutes configuring Git properly. Skip this and you'll fight identity errors, insecure credential prompts, and inconsistent line endings for months.
Step 1 β Install Git#
- Check if it's already there:
git --version - Windows: install Git for Windows β accept defaults, but choose Git Bash as your terminal.
- macOS:
xcode-select --install, orbrew install git. - Linux:
sudo apt install git(Debian/Ubuntu) or your distro's equivalent.
Step 2 β Set your identity#
Every commit is stamped with your name and email. Use the same email as your GitHub account so your commits are linked to your profile (or set up GitHub's noreply email in *Settings β Emails* to keep your address private):
git config --global user.name "Your Name"git config --global user.email "you@example.com"- Verify:
git config --list
Step 3 β Sensible defaults#
git config --global init.defaultBranch mainβ new repos start onmain, matching modern convention.git config --global pull.rebase falseβ safer default for beginners; plain merges instead of surprises.git config --global --editβ open the config file and review everything at once.
Step 4 β Authentication#
You cannot push with your password β GitHub removed that. Pick one:
- HTTPS + Personal Access Token (simplest): create a token in *GitHub β Settings β Developer settings β Tokens*, then use it as your password when Git prompts.
- SSH keys (best long-term): run
ssh-keygen -t ed25519 -C "you@example.com", add the public key to *GitHub β Settings β SSH keys*, test withssh -T git@github.com. - GitHub CLI (`gh`) β installs a credential helper for you; also makes PRs from the terminal later.
Note
Test it now:git push to your fork from a throwaway branch. Fixing authentication on day one beats discovering it mid-contribution.Step 5 β Your editor & tooling#
- Editor: VS Code is the common choice β install it plus the language extension(s) for the project you picked.
- Terminal: Git Bash (Windows), zsh/bash (macOS/Linux), or the VS Code integrated terminal.
- Diff viewer: VS Code's Source Control tab, or
gitk/lazygit for a visual history. - Optional GUI: GitHub Desktop or GitKraken if CLI Git still feels abstract β totally acceptable.
Step 6 β Project dev setup ("it works on my machine")#
- Open
CONTRIBUTING.md/README.mdβ they list required tool versions and commands. Follow them exactly. - Check for a version pin:
.nvmrc,.node-version,.python-version,mise.toml. Match it (nvm installreads.nvmrcautomatically). - Install dependencies in the project folder, not globally.
- Run the project's checks: lint (
npm run lint), tests (npm test), and the dev server. - If the repo uses devcontainers/Docker, prefer that β it gives you the same environment the maintainers use.
A branch-per-change habit from day one#
From now on, never work on main. For every issue you pick:
git checkout mainthengit pullβ start from current code.git checkout -b fix/issue-42-broken-linkβ descriptive branch: type/what.- Make the change, commit, push the branch.
mainstays clean for the next task.
Ten minutes of setup saves ten hours of confused debugging. Configure once, contribute smoothly forever.
2.3 How to Find Issues Meant for You
The fastest way to stall is picking the wrong task. Choose an issue that's wanted, small, and scoped for newcomers β here's how to find one.
Start with the labels maintainers set for you#
Projects mark beginner-friendly work on purpose. Open the repo's Issues β Labels and look for:
- good first issue β the universal newcomer label (also:
first-timers-only,beginner,starter). - help wanted β maintainers explicitly want outside help here.
- documentation / typo β low-risk, high-confidence first PRs.
- bug + small scope β after you've done one or two easier ones.
GitHub search, done properly#
The search bar is more powerful than it looks. Useful patterns:
label:"good first issue" is:issue is:openβ open beginner issues.label:"good first issue" is:open no:assigneeβ not already taken.repo:owner/name label:"help wanted"β scoped to one project.org:facebook label:"good first issue"β beginner issues across an organization.
You can also browse aggregated lists: goodfirstissues.com, up-for-grabs.net, or GitHub's own *Explore β Good first issues*.
Check the issue is actually alive before you invest#
- Look at the last comment date β anything older than ~6 months may be abandoned or already fixed.
- Look for an assignee β if someone's on it, move on. Unassigned = yours to claim.
- Look for maintainer signals:
bug confirmed,ready for PR, or a π on a volunteer's comment. - Read linked PRs β a closed/merged PR might mean the work is already done even if the issue stays open.
Claim it the right way#
Comment before you start β respect the project's convention (many ask for a short statement, others want a full plan):
- Comment: *"Hi, I'd like to work on this. Is it still available?"*
- Wait for a maintainer's OK before writing code β the issue may be complicated, or reserved for a reason.
- If the project uses an assignment flow, ask them to
/assignyou.
Note
The most common waste of a beginner's weekend: building something nobody asked for. Comment first, code second.No good first issues available?#
- Improve the docs β find something confusing and fix it. Docs PRs are always welcome. This is exactly how most of my own merges started: for example, google/adk-docs #2311 β "fix: correct typos in docs prose", found simply by reading pages I was already using.
- Report a good bug β a clear, reproducible issue with steps and screenshots is a real contribution.
- Fix something you hit while running the project locally.
- Widen your net β check other repos of the same organization, or projects in your actual stack.
Red flags β skip these issues#
- Vague description: "something doesn't work" with no steps to reproduce.
- Dozens of comments with no maintainer response β likely unmaintained.
- Someone already pushed a PR that solves it.
- The issue demands weeks of work as a "first" contribution.
A great first issue is small, wanted, and confirmed. Check all three before you open your editor.
With the code cloned, your environment configured, and an issue claimed β you're ready for the main event: your first pull request, start to finish, in Chapter 3.
Chapter 03
β 7 min read
Your First Pull Request
The full walkthrough: read the issue properly, make the smallest change that solves it, write a PR reviewers enjoy, handle feedback like a professional, and finish strong after the merge.
In this chapter you'll learn to
- β Interrogate an issue and reproduce a bug before coding
- β Ship a small, tested, well-described pull request
- β Respond to code review calmly and get it merged
3.1 Read Before You Code: Understanding the Issue
The most expensive mistake in open source happens *before* any code is written: building the wrong thing. Ten minutes of reading saves a week of rework.
Interrogate the issue#
Before you touch the editor, answer these questions β from the issue text, the code, or the maintainers in a comment:
- What exactly is broken (or missing)? Reproduce the bug yourself. If you can't reproduce it, ask β don't guess.
- What does "done" look like? The acceptance criteria. If the issue doesn't state one, propose one in a comment.
- Is there a linked discussion, prior PR, or design doc? Read them β old decisions usually have reasons attached.
- What's out of scope? Good issues have edges. Respecting them is what keeps your PR reviewable.
Stalk the area of code you'll change#
- Find the file(s) mentioned in the issue β search for error messages or function names from the report.
- Read the surrounding code, not just the broken line. Note the style, naming, and patterns in that module.
- Check
git logfor that file β recent commits show who cares about this area and how it's evolving. - Look for existing tests near the code. Your fix will likely extend them.
Reproduce the bug first (for bug fixes)#
Write down the exact steps that show the wrong behavior. This is gold:
- It proves the issue is real β and that *you* understand it.
- Your new test starts from a red state, then your fix turns it green β the cleanest possible PR story.
- If you can't reproduce it, say so publicly. "I tried X, Y, Z on the latest main and couldn't repro β here's my output" is a legitimate, respected comment.
A real example from my work: in google/adk-docs #1996 β "Fix route key mismatch in conditional-routing.py", the example's route_weekend function yielded route names (cheap_ideas, fancy_ideas) that didn't exist in the edges dictionary β so the workflow failed at runtime. Running the example *was* the reproduction; the PR body simply showed the failing routes beside the valid ones.
Note
Rule of thumb: if you can't explain the bug in two sentences to a teammate, you don't understand it yet β and your patch will show it.3.2 Make the Change: Small, Focused, Tested
You have a branch from Chapter 2 and an understood issue. Now write the fix β with *restraint*.
The smallest change that truly solves it#
- Resist fixing the four other things you noticed. They're separate PRs β note them in a comment or open new issues.
- Match the existing style of the module, even if you'd write it differently. Consistency inside a codebase beats personal taste.
- No drive-by refactors, no renaming, no reformatting unrelated lines β every extra line is another line a reviewer must defend.
- If the fix feels too big, it probably is: split it into stacked PRs (a small foundation PR, then the real change on top).
Tests: the difference between "looks fixed" and "is fixed"#
- Write (or extend) a test that fails without your change β this is the proof.
- Apply the fix, watch it pass.
- Run the full suite β your change may break something two directories away.
- Run lint/format exactly as
CONTRIBUTING.mdspecifies (CI will reject you otherwise).
Commit messages that reviewers appreciate#
- Imperative mood, summary line: "Fix crash when parsing empty config" β not "Fixed" or "Fixes issue #42".
- Explain why in the body when it isn't obvious; wrap at ~72 characters if the project does.
- Reference the issue:
Closes #42in the message or PR description so it auto-closes on merge. - Follow any convention the project documents (Conventional Commits, etc.). Look at the last 20 commits β the truth is in the history, not the docs.
A good PR is boring: a handful of lines, a clear message, and a test that proves the point.
Note
Before every push:git diff main β read your own change as a stranger would. Catching your own mistake costs nothing; a reviewer catching it costs goodwill.3.3 Write the Pull Request
The PR is a sales document for a code change. Reviewers are busy volunteers β your job is to make approving you easy.
The title#
- One line, imperative, specific: "Fix null crash in search when query is empty".
- Include the area if the repo is large: "docs: add Windows setup steps to README".
- Never: "Fixes", "Update", "Changes", "First contribution" β they describe nothing.
The description template#
- What & why β what does this change, and which issue does it close (
Closes #42). - How to test β exact commands or steps a reviewer can follow in 30 seconds.
- Before/after β for UI or output changes, screenshots or terminal diffs. They end half the questions.
- Trade-offs β anything you considered and rejected, and why. This shows judgment, not doubt.
A real description that got merged: n8n-io/n8n-docs #5080 used exactly this shape β a What section, a Changes list broken down file by file ("Cmmon issues" β "Common issues", items.length β len(items)β¦), and a Verification section stating *how* each fix was checked. Three sections, zero questions from the reviewer, merged in eight days.
Use Draft PRs when you want early feedback#
Uncertain about the approach? Open a Draft pull request: it signals "not ready to merge" while inviting direction. Comment: *"Draft approach β before I finish, is this the right direction?"* Ten minutes of early feedback saves a full PR rewrite.
The checklist before you click Create#
- Branch is up to date with
main(rebase or merge upstream first). - CI is green locally: tests + lint pass on your machine.
- Diff contains only the intended files β no
.env, nonode_modules, no debugconsole.log. - Description reads like a stranger wrote it β because a stranger will review it.
- You've disclosed AI assistance if the project's policy asks for it.
Note
First PR? Say so proudly in the description: *"My first contribution to this project β happy to follow any conventions I missed."* Maintainers mentor people who signal they're coachable.3.4 Handle Code Review Without Losing Your Nerve
Review comments are not criticism of you. They're how a project protects code that thousands of people depend on. Every contributor gets them β the difference between a good and a bad contributor is how they respond.
Reading a comment properly#
- Read it fully, then re-read it. Review comments are often shorter than intended.
- Classify it: must change (correctness, style rules, scope) vs. suggestion (preference, alternative) vs. question (they want to understand your choice).
- If anything is ambiguous β ask. *"Just to confirm: do you want X, or is Y acceptable if I add a test?"* is a perfectly good reply.
- If you disagree β respond with reasoning, not resistance. *"I avoided that approach because of A; happy to switch if the edge case matters."* You can lose a small battle and win respect.
Pushing fixes the right way#
- Push new commits to the same branch β the PR updates itself; never open a second PR.
- Reply to each comment thread after fixing it: *"Done β moved the validation into the handler and added a test for the empty case."*
- If a comment sparked several changes, one grouped reply per thread is fine β just don't leave threads hanging.
- Always answer questions, even with just *"Good catch β fixed in abc123."*
When review stings#
- "This is all wrong" β if truly so, the reviewer usually explains why. Extract the lesson; the PR is still worth finishing.
- Silence for days β polite one-line bump after a week; then find another issue to keep momentum while waiting.
- A nitpick storm β often means the project wants a different direction. Ask directly: *"Should I restructure this, or is this a preference I can note for next time?"*
- Never argue publicly while emotional. Draft the reply, wait an hour, send a shorter, kinder version.
Note
Maintainers remember contributors who take feedback well far longer than they remember contributors who take feedback badly. Grace under review *is* the reputation.Where to watch this happen for real: open any of my 38 merged PRs and read the review threads β e.g. the discussion on google/adk-docs #1996 or the maintainer exchange on openclaw/openclaw #112691. Real comments, real revisions, real merges.
3.5 After the Merge: Finish the Loop
The merge notification lands. Here's how to close the loop properly β most contributors skip this, and it's free credit.
- Thank the reviewer β one short comment: *"Thanks for the careful review, @maintainer β merged!"* Takes five seconds, remembered for years.
- Sync your fork β
git checkout main && git pull upstream main && git push origin mainso your next branch starts clean. - Delete the branch (GitHub prompts this) β local and remote. No leftover debris.
- Verify the fix in the wild β check the released version or live site if applicable. Nothing beats seeing your name in a changelog.
- Close the loop on the issue β if
Closes #Ndidn't auto-close it, close it yourself with a link to the PR. - Pick the next issue within 48 hours β while the workflow, the repo, and your confidence are warm. One contribution is luck; three is a habit.
Capture what you learned#
- Write down the project's quirks you discovered (branch naming, test commands, review preferences) for your next PR.
- Add the merged PR to your portfolio/profile β link it, don't just screenshot it.
- Note the humans: which reviewer was helpful? Some projects have more good-first-issue work coming; people remember returning faces.
The first merged PR changes how you see yourself. The third one changes how others see you.
You've now done it end to end: issue β code β PR β review β merge. Chapter 4 shows how to run this entire loop with an AI pair contributor β and Chapter 5 turns single PRs into a reputation.
Chapter 04
β 9 min read
Contribute with OpenCode: Your AI Pair Contributor
Install OpenCode, teach it your forked-and-cloned workflow with a system prompt, grant it GitHub access so it can open PRs β then command it to read maintainer review comments and fix them until your PR gets merged.
In this chapter you'll learn to
- β Install OpenCode and connect it to a model provider
- β Grant safe, permission-limited GitHub access (gh CLI / MCP)
- β Write an AGENTS.md system prompt that runs your contribution workflow
- β Command the review loop: fetch comments β fix β push β merge
4.1 Why Let an AI Do the Busywork?
By now you know the loop: find an issue, fix it, open a PR, wait for review, address comments, repeat. The loop is simple β but it's repetitive. A tool like OpenCode (an open source AI coding agent that runs in your terminal) can run most of it for you.
The right mental model: OpenCode is a junior developer with perfect Git manners and no memory of your project. You give it the repository, the rules, and the approval β it does the typing, you keep the judgment.
What OpenCode will do for you#
- Scan open issues and propose ones matching your skill level.
- Read the codebase, implement the fix, run the tests.
- Create the branch, commit, push to your fork, and open the pull request.
- Later β on your command β fetch every maintainer comment, explain it, fix the code, and push updates until it's merged.
What you still own#
Manual loop
Ch 1β3- Β· You find the issue
- Β· You type every line
- Β· You run every command
- Β· You fetch review comments
AI-assisted loop
This chapter- β Agent proposes issues
- β Agent writes from your direction
- β Agent runs tests & commits
- β Agent fetches + summarizes comments
- Every push and PR β you approve each step (Chapter shows you how to enforce this with permissions).
- Understanding your own diff β if you can't explain the change, don't send it. This is a book about *you* contributing, not about shipping code you've never read.
- The relationship β replying to maintainers, answering questions on the PR, and being honest that you used AI assistance.
Note
Many projects welcome AI-assisted contributions; some restrict them or require you to disclose. Always read the project's CONTRIBUTING.md and AI policy first β and never paste a generated PR description that hides how the work was done.4.2 Installing OpenCode
OpenCode runs in your terminal, with a desktop app and web app also available. Pick your install method:
Step 1 β Install the CLI#
- macOS / Linux:
curl -fsSL https://opencode.ai/v2/install | bash - Homebrew:
brew install anomalyco/tap/opencode-v2 - npm (any OS):
npm install -g @opencode/cli - Windows: use the npm method or download the standalone Windows binary from opencode.ai β Windows *package managers* (winget/scoop/choco) are not supported.
Step 2 β Verify#
- Open a new terminal, then
opencode --versionβ a version number means it's on your PATH. - Also confirm your earlier setup:
git --versionandgh auth status(you'll need GitHub CLI in the next section).
Step 3 β Connect a model#
OpenCode supports many LLM providers. On first launch it will walk you through connecting one:
- Run
opencodeinside your cloned repository. - Use
/connectin the interface to sign in to a provider (API key or OAuth). - Alternatives: OpenCode Console for easy access to top coding models, or OpenCode Go β a $10/month subscription that unlocks the best coding models.
Step 4 β Learn the two modes you'll use#
opencodeβ the interactive terminal UI, for conversations, reviews, and approvals.opencode run "Fix the broken link in the README"β one-shot mode: submit a prompt, get the work done, no interface. Perfect for scripts and quick tasks.
Note
Always launchopencode from inside the repository folder β the agent works on the files in the directory you open it in. Wrong folder = wrong project.One command to install, one command to run. The setup cost of an AI pair contributor is about five minutes.
4.3 Giving OpenCode Access to Your GitHub
OpenCode writes code locally out of the box. To let it push branches and open pull requests, it needs authenticated GitHub access on your machine β which it can then use through its shell tool.
Option A β GitHub CLI (gh): the simple, reliable way β#
- Install the GitHub CLI:
winget install GitHub.cli(Windows),brew install gh(macOS), orsudo apt install gh(Linux). - Authenticate:
gh auth loginβ choose GitHub.com β HTTPS β Login with a web browser β paste the one-time code. - Verify:
gh auth statusβ you should see "Logged in to github.com as your-username". - Smoke-test from inside your fork:
gh pr create --fill --dry-runβ it should recognize the repo and your identity.
That's it. OpenCode can now run commands like gh issue list, gh pr create, and gh pr view β and every request GitHub receives is as you, on your fork, exactly like doing it manually.
Option B β GitHub MCP server: richer GitHub tools#
For deeper integration (searching issues, reading review threads through dedicated tools instead of shell commands), add GitHub's remote MCP server:
opencode mcp add github --global --url <GitHub's remote MCP URL>(grab the current URL from GitHub's official MCP docs β it may change).- Inside OpenCode, run
/mcps, select the server, and sign in when it asks to authenticate. opencode mcp listshould showβ github connected.
Option C β The Git credential helper you already set up#
If you configured SSH keys or a personal access token in Chapter 2, plain git push from OpenCode already works β the gh CLI simply adds issue/PR commands on top of that. Option A + your existing credentials is the setup this book uses.
Lock it down: permissions for safe PR-sending#
Give OpenCode the *minimum* power it needs. In your project's opencode.jsonc:
- Read-only commands (
git status,git diff,git log,gh issue list,gh pr view) β allow, so it can explore without nagging you. - Dangerous commands (
git push,gh pr create,git commit) β ask, so you approve every outbound action. - Destructive commands (
git push --force, pushing tomain) β deny, hard-blocked no matter what.
Note
Rules are checked in order and the last matching rule wins, so specific exceptions go *after* the broad "ask" rule. Adeny can never be overridden by an allow.When a command resolves to *ask*, you get three choices: Allow once, Allow always (saves that command pattern for this project), or Reject. Choose *Allow always* only for commands you've seen and trust.
4.4 The System Prompt: Forked, Cloned, Fix, PR
An AI performs well when the rules are written down once instead of retyped every session. OpenCode reads an `AGENTS.md` file in your repository as persistent project instructions β that's where your contribution workflow lives.
Create AGENTS.md in your fork's root#
- OpenCode loads a global
~/.config/opencode/AGENTS.mdfirst, then everyAGENTS.mdfrom your workspace up to the project root. - Keep universal rules globally; put the per-repository workflow in the project's file.
- Instructions from
AGENTS.mdare combined with your configinstructionsarray β you can also listCONTRIBUTING.mdthere so the project's own rules are always loaded.
The workflow prompt (copy and adapt)#
- State of the repo: "This is my fork of
upstream(the original).origin= my fork,upstream= original project. Never push directly tomain." - The mission: "When I ask you to work on an issue: list open
good first issuecandidates withgh issue list, propose 3 with why each fits, and wait for my pick before coding." - The fix: "Create branch
fix/<issue-number>-<short-description>, make the smallest change that solves the issue, run the project's lint and tests. Do not proceed if checks fail." - The PR: "Commit with a clear message that references the issue (e.g.
Closes #42), push the branch toorigin, then open a PR withgh pr createβ title summarizing the fix, description explaining what/why, linking the issue. Show me the diff and wait for my approval before pushing."
What a session looks like#
- You:
cd your-fork && opencode - You: *"Find me a good first issue to work on."*
- OpenCode: lists candidates with reasoning. You pick one.
- You: *"Work on issue #42. Follow AGENTS.md."*
- OpenCode: implements the fix, runs tests, shows the diff, asks to push.
- You: approve β it pushes and opens the PR. You read the final PR on GitHub before considering it done.
Note
The"wait for my approval" line is the heart of the system prompt. Without it, an eager agent may push before you've read a single line of the diff.4.5 Watching It Send Your First AI-Assisted PR
Everything from Chapter 2 and 3 now happens in one sitting. Here's the full sequence with real commands.
One-time preparation#
- Fork + clone the target repo, and
git remote add upstream <original-url>(Chapter 2). - Confirm your environment runs the project: install deps, tests pass untouched.
gh auth statusβ GitHub access confirmed.- Write
AGENTS.mdwith the workflow prompt above. - Add your
permissionsrules toopencode.jsonc.
The contribution session#
- Run
opencodein the repo folder. - Prompt: *"Find good first issues and suggest ones I could take."* β pick one together.
- Prompt: *"Implement the fix on a new branch and show me the diff."*
- You read every line. Ask questions about anything you don't understand β this is free mentorship, use it.
- Approve the push. OpenCode commits, pushes to
origin, and runsgh pr create. - Open the PR URL on GitHub. Read what was actually published β title, description, files changed.
Before you post, sanity-check the PR yourself#
- Does the diff touch only files related to the issue?
- Is the PR description honest and clear? Rewrite it in your own words if needed β you own it.
- Does it link/close the issue? (
Closes #42) - Are CI checks green within the first few minutes?
- Any secrets, build artifacts, or debug logs accidentally included? Never push those.
Note
Treat the AI's PR like a PR from a teammate: you review it before the maintainer does. The reviewer who catches their own mistakes first earns trust; the one who doesn't burns it.The agent types the code. The accountability is 100% yours.
4.6 The Review Loop: Fix What the Maintainers Ask Until It Merges
PR opened is not "done." Real PRs come back with comments β and this is where an AI pair contributor quietly saves you the most time.
Round 1 β Pull the review on your command#
Come back to the session (or start a new one in the repo) and say exactly what you described in the plan:
- You: *"Check my PR #12 for review comments from the maintainers and address them."*
- OpenCode fetches them (
gh pr view 12 --comments, plus the inline review threads viagh api repos/<owner>/<repo>/pulls/12/comments). - It summarizes each comment and its planned fix, then waits for your approval β your permissions config forces this.
- You approve each fix β it edits the code, re-runs lint and tests, commits, and pushes the update to the same branch (the PR refreshes automatically).
- Then ask it to *"reply to each comment explaining what changed"* β a short, human reply to every reviewer is what gets PRs moving.
Round 2+ β Repeat until green#
- Maintainers review in waves β expect 1β3 rounds on a first contribution. That's healthy, not rejection.
- Each round: pull comments β summarize β you approve β fix β test β push β reply.
- If a request is unclear or you disagree, say so β have OpenCode draft a clarifying reply, but you decide what to post. Professional tone, no defensiveness.
- Never mark a comment "resolved" without actually changing the code β reviewers notice.
The merge#
- All checks green, all threads resolved, maintainer approves.
- They merge (or give you merge rights on your own PR β you'll see it in the comments).
- Ask OpenCode: *"Clean up: sync my fork with upstream and delete the local branch."* β
git fetch upstream && git merge upstream/main, pushmain, delete the branch. - Your name is on the contribution history. Post the PR link in your portfolio and roll straight into the next issue β repetition is what builds the reputation Chapter 5 is about.
Troubleshooting the loop#
- CI failed after push β *"Check the failing workflow run on PR #12 and fix it."* OpenCode reads the logs and patches the issue.
- Comment conflicts with another comment β reply asking the maintainers which preference wins; don't guess.
- Stale PR (no response for weeks) β a polite one-line bump comment works; ask OpenCode to check whether the code has moved on (
git fetch upstream) and rebased first. - The AI misunderstood the review β quote the comment back and correct it. The summarizing step exists so *you* catch misunderstandings before they're pushed.
Note
The human-in-the-loop rhythm that works: AI fetches β summarizes β you decide β AI executes β you verify. Skip the "you decide" step often enough and you'll eventually push something you can't defend in review.Chapter 05
β 6 min read
Beyond the First PR: Building a Reputation
Turn one merged PR into a lasting presence: contribute consistently, communicate so maintainers trust you, take on bigger work, and grow into your first maintainer responsibilities.
In this chapter you'll learn to
- β Build a sustainable contribution rhythm and portfolio
- β Communicate in a way that earns maintainer trust
- β Escalate from fixes to features using discussion-first work
- β Take on your first maintainer duties gracefully
5.1 Consistency Beats Heroics
One merged PR is an event. Regular merged PRs are a reputation. The contributors who get invited to interesting work aren't the most talented β they're the most *reliably present*.
The sustainable rhythm#
- Small and frequent beats big and rare. Two focused hours weekly ships more than a vanished-then-bursting weekend.
- Work a queue, not a single issue. Keep 2β3 candidate issues warm: one being worked, one waiting for review, one waiting for maintainer confirmation.
- Follow up before starting. A PR waiting on review deserves a check-in; a merged PR deserves a sync. Untracked PRs are where contributions go to die.
- Ride the roadmap. After one good PR, look for
help wantedon the same area β familiarity makes you 3Γ faster next time.
Track your contributions like a portfolio#
- Keep a simple list (a note file or spreadsheet): project, PR link, status, lesson learned.
- Review it monthly β you'll spot patterns: which projects respond, which maintainers are kind, which types of work suit you.
- Consolidate: after a few merged PRs in one project, that's your *home* project. Depth in one community outweighs breadth across ten.
Why projects reward regulars#
From a maintainer's seat: reviewing strangers is expensive β every unknown contributor needs full scrutiny. A returning contributor with a track record gets faster reviews, bigger assignments, and the benefit of the doubt. Your past merged PRs are your interview for the next one.
Note
A quiet month is fine; a silent exit is not. If you'll be busy, say so in the project's discussion. Reputation survives absence β disappearing without a word doesn't.What that looks like in practice: I built most of my 38 merged PRs the same way β one focused fix at a time, project by project. Twenty-one of them landed in google/adk-docs because after the first merge I already knew the repo's conventions; each PR after it was faster to write and smoother to review. Familiarity *is* the compounding interest.
5.2 Communication That Makes Maintainers Trust You
At the contributor level, code skill is the price of entry. Trust β the thing that unlocks bigger work β is built almost entirely in text.
The traits of a trusted contributor#
- Predictable. Does what they said, when they said it β or communicates early when plans change.
- Scoped. PRs that do one thing. Issues that aren't vague hand-grenades.
- Responsive. Replies within a day or two, even if just *"on it this weekend."*
- Curious, not defensive. Asks *why* the project does something a certain way instead of assuming their way is better.
- Credit-sharing. Links the prior art they built on, thanks reviewers by name, never claims someone else's idea.
Write comments reviewers want to read#
- Lead with the decision needed: *"Should I keep option A or switch to B? A is faster, B matches the existing utils."*
- Show, don't wall. Code snippets, screenshots, reproducible steps β never three paragraphs where a diff belongs.
- Disagree with reasons and an off-ramp: *"I went with X because Y breaks on Windows (link). Happy to revisit if portability isn't a goal here."*
- Close loops. When a conversation ends, one line confirms it: *"Resolved in abc123 β thanks!"*
Navigating disagreement and rejection#
- Your PR may be closed unmerged after real work. It happens to everyone β sometimes the approach was wrong, sometimes the timing was, sometimes the maintainer misjudged.
- Ask for the takeaway once, graciously: *"Understood. For next time β would a smaller fix around X have been the right shape?"*
- Never: guilt-tripping, comparing yourself to other contributors, or re-opening the same debate across five comments.
- Do: extract the lesson, keep the branch history, and bring that knowledge to your next PR *somewhere else*.
Maintainers don't remember your cleverest code. They remember whether working with you was easy.
5.3 Leveling Up: Features, Discussions & Bigger Changes
Bug fixes and docs were your training wheels. Now graduate to changes that shape the project β where the skill isn't writing code, but *aligning before writing*.
The escalation ladder#
| Tier | Work | Review speed | Discuss first? |
|---|---|---|---|
| 1 | Fixes & docs | Fastest | No |
| 2 | Small improvements (tests, errors, perf) | Fast | Rarely |
| 3 | Features with precedent | Normal | Yes β prove demand |
| 4 | Net-new behavior | Slowest | Always β design issue first |
The "discussion before code" rule#
For anything Tier 3+, open an issue (or the project's RFC/discussions channel) before investing days:
- State the problem you're solving and who it affects β not your solution first.
- Offer 2 options with trade-offs. Maintainers pick; builders propose.
- Reference prior issues/PRs so nobody re-litigates old decisions.
- Wait for a maintainer signal before implementing. Silence is not approval.
Splitting big work so it actually ships#
- Large PRs don't get reviewed β they get parked. Break work into stacked, individually-mergeable PRs.
- Ship the boring foundation first (types, plumbing, tests); the visible change second.
- Keep each PR mergeable *without* the next one β maintainers merge whenever they're ready.
- Post a checklist issue linking each stack piece so progress stays visible.
Note
The promotion signal: a maintainer replies *"feel free to take a look at issue #X too"* without being asked. That's organic trust β chase the work that produces these moments.My own ladder, rung by rung: I started at Tier 1 β typos and dead links in google/adk-docs. Once maintainers saw I followed instructions, I moved to Tier 2 *code* fixes in openai/openai-agents-python β like consolidating same-exception re-raises into bare `raise` and breaking out of the voice audio dispatch loop on session end. Docs first, real code second β exactly the escalation order above.
5.4 Your First Maintainer Duties
Reputation compounds into responsibility. One day a maintainer asks: *"Want to help review incoming PRs?"* β congratulations, you've crossed from consumer to steward.
Reviewing others' PRs#
- Understand intent first, implementation second β read the description before the diff.
- Categorize every comment so the author knows what's blocking: "must" vs "nit", and use Request changes / Comment / Approve properly.
- Ask before prescribing: *"What happens if the list is empty?"* teaches more than *"This is wrong."*
- Praise specifics. *"Clean error handling here β nice"* costs seconds and builds a culture people want to work in.
- Be fast on small PRs. First-time contributors who wait a week rarely return β speed of first response is a maintainer metric.
Triaging issues#
- Reproduce bugs before labeling β then label (
needs-repro,bug,good first issue) so the next contributor inherits a clean queue. - Close stale or duplicate issues with kindness and a link β triage is maintenance, not rejection.
- Improve issue templates so reports arrive better than you found them.
Keeping the project alive#
- Green CI and a working release process matter more than new features β protect them.
- Answer questions about the project in discussions and forums; you become the person who *knows*.
- Write the docs you needed when you started β still the highest-leverage file in any repo.
Knowing your limits#
Maintainership is a duty, not a badge: unanswered review queues and ghosted issues actively hurt projects. Accept only the responsibility you can sustain, delegate what you can't, and step back openly if you need to β communities respect honest capacity far more than silent overload.
Contributing gets your code merged. Becoming a steward gets your name in the project's story.
This is the arc's final stop: you came in wondering what open source was, and you're leaving as someone who shapes it. Where you go from here β deeper craft, or a career built on this reputation β is exactly what the paths ahead are for.

You've reached the end of Volume 1.
β M. Ali Adnan, Karachi Β· thanks for reading every line.
Next issues in the roadmap: debugging real codebases Β· open source as a career.