Working Code
Walk through the entire GitHub Flow in one go.
Step 1: Create an issue
gh issue create \
--title "Add about page" \
--body "The site has no about page. Please add one."
Output:
https://github.com/username/my-project/issues/1
Step 2: Create a branch
git checkout main
git pull # Always start from an up-to-date main
git checkout -b feature/1-about-page
Including the issue number in the branch name makes tracking easy: feature/1-about-page
Step 3: Work + commit
echo "<h1>About</h1><p>Welcome!</p>" > about.html
git add about.html
git commit -m "feat: add about page (closes #1)"
Try It Yourself
Step 4: Push + create PR
git push -u origin feature/1-about-page
gh pr create \
--title "feat: add about page" \
--body "## Changes
- Added about.html
## Related Issue
closes #1
## Checklist
- [x] Feature implemented
- [x] HTML validated
- [ ] Mobile tested"
Step 5: Receive code review feedback
Suppose a reviewer comments:
"Please make the about page intro more specific."
Step 6: Address the feedback
# Make changes
echo "<h1>About</h1><p>Welcome to DaleSchool!</p>" > about.html
git add about.html
git commit -m "fix: update about page intro (review feedback)"
git push
# Automatically reflected in the PR
Request re-review after addressing feedback:
gh pr review --request-review @reviewer-username
Step 7: Merge + clean up
After PR approval:
gh pr merge --squash # Squash feature commits into one
git checkout main
git pull # Pull the merged changes
git branch -d feature/1-about-page # Delete local branch
Second PR: more review cycle practice
# When CI fails
gh pr checks 1 # Check CI status
Output:
Some checks were not successful
✗ CI / test (1m 30s)
✓ CI / lint (45s)
# Fix the failing test
vim about.test.js
git add about.test.js
git commit -m "test: add about page test"
git push
gh pr checks 1 # Check again
"Why?" -- Why GitHub Flow is widely adopted
GitHub Flow is simple. The core rule is:
The main branch must always be deployable.
Therefore:
- Never push directly to main
- All work happens on feature branches
- Only merge into main through PRs
main ------------------------------------------------> (always stable, deployable anytime)
^ merge PR ^ merge PR
feature-1 --------> feature-2 -------->
Conventional Commits
type(scope): description
Types:
feat New feature
fix Bug fix
docs Documentation change
style Code formatting (no behavior change)
refactor Refactoring (no behavior change)
perf Performance improvement
test Add/update tests
chore Build system, packages, etc.
ci CI/CD configuration
# Good commit message examples
git commit -m "feat(auth): add Google OAuth login"
git commit -m "fix(cart): fix cart item count update bug"
git commit -m "docs(api): add authentication endpoint docs"
git commit -m "refactor(user): extract UserService class"
git commit -m "test(login): add login form validation tests"
Branch protection rules
Protect the main branch in GitHub (Settings -> Branches):
- Require pull request reviews: Minimum N approvals required
- Require status checks: CI must pass (block merge on failure)
- Restrict pushes: Block direct pushes
With these settings, git push origin main will be rejected.
Common Mistakes
Mistake 1: Creating a branch from stale main
# Bad habit: branching from outdated main
git checkout main
git checkout -b feature/new # Didn't check if main is up-to-date
# Good habit
git checkout main
git pull # Always update before branching
git checkout -b feature/new
Mistake 2: Creating a PR without a description
# Reviewer has no context
gh pr create --title "update"
# Reviewer can understand what's going on
gh pr create \
--title "feat: add search autocomplete" \
--body "## Changes
Implemented autocomplete dropdown
## Related Issue
closes #45
## How to Test
1. Type in the search box
2. Check the dropdown"
Mistake 3: PRs that are too large
# Avoid: 50 files changed
# Hard to review and high conflict risk
# Recommended: one purpose, small scope
# feature/login-ui -> login UI only
# feature/login-api -> login API only
# Submit separate PRs
Mistake 4: Not requesting re-review after fixes
If you push fixes without notifying the reviewer, they won't know. Click "Re-request review" on GitHub, or:
gh pr review --request-review @reviewer
Deep Dive
Git Flow vs GitHub Flow vs Trunk-based
Three major workflows:
| | Git Flow | GitHub Flow | Trunk-based | | ---------------- | ---------------------------------------------- | -------------------- | -------------------- | | Branches | Many (main, develop, feature, release, hotfix) | Few (main + feature) | Minimal (main only) | | Complexity | High | Medium | Low | | Deploy frequency | Low (release cycles) | High | Very high | | Best for | Versioned software | Web services | Advanced CI/CD teams |
GitHub Flow suits most web service teams.
PR automation: GitHub Actions
Automatically run tests when a PR is opened:
# .github/workflows/ci.yml
name: CI
on:
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: "20"
- run: npm install
- run: npm test
This runs tests automatically on PR creation/update and shows results on the PR.
PR review culture
Principles of good code reviews:
Reviewer:
- Review logic and patterns, not just code
- Give specific, constructive feedback
- Ask "Why?" questions to deepen understanding
- Don't hold back on praise
Author:
- Don't take feedback personally
- Explain the reasoning behind your decisions
- Request re-review after making changes
- Resolve discussions through comments
- Create a GitHub repository and open an issue.
- Create a branch named with the issue number and commit your work (e.g.,
feature/1-about-page). - Write commit messages in Conventional Commits format and create a PR.
- Include changes, related issue, and a checklist in the PR body.
- Merge with
gh pr merge --squashand pull main to update.
Q1. Which statement about the main branch in GitHub Flow is correct?
- A) Developers push directly to keep it up-to-date
- B) It must always be in a stable, deployable state
- C) Features can be merged even if tests fail
- D) Only one PR can be open at a time