This document provides a step-by-step guide for new contributors to make their first contribution to the free-programming-books repository. It covers the basic workflow, understanding the automated validation system, and resolving common issues.
For detailed formatting rules and quality standards, see Contribution Guidelines and Standards. For community conduct expectations, see Community Code of Conduct. For understanding the automated systems that validate your contribution, see Automated Validation Systems.
| Contribution Type | Description | Target Files |
|---|---|---|
| Add Resource | New books, courses, tutorials, podcasts | books/*.md, courses/*.md, more/*.md, casts/*.md |
| Fix Broken Link | Update dead or redirected URLs | Any .md file |
| Add Translation | Translate contribution docs to your language | docs/CONTRIBUTING-*.md, docs/CODE_OF_CONDUCT-*.md |
| Fix Formatting | Correct alphabetical order or formatting issues | Any .md file |
Sources: .github/PULL_REQUEST_TEMPLATE.md1-23 docs/README.md1-149
Sources: .github/workflows/fpb-lint.yml1-37 .github/workflows/check-urls.yml1-133 .github/workflows/comment-pr.yml1-56
Before contributing, ensure:
Sources: docs/CONTRIBUTING-ml.md36-38 .github/PULL_REQUEST_TEMPLATE.md18
| If the resource is... | Use this file |
|---|---|
| Book about Python, Java, C++, etc. | books/free-programming-books-langs.md |
| Book about Algorithms, Databases, Security | books/free-programming-books-subjects.md |
| Online course in English | courses/free-courses-en.md |
| Online course in Hindi | courses/free-courses-hi.md |
| Interactive coding tutorial | more/free-programming-interactive-tutorials-en.md |
| Coding playground/sandbox | more/free-programming-playgrounds.md |
| Podcast or screencast series | casts/free-podcasts-screencasts-en.md |
| LeetCode-style problems | more/problem-sets-competitive-programming.md |
| Cheat sheets/quick reference | more/free-programming-cheatsheets.md |
Sources: docs/CONTRIBUTING-ml.md19-27
Basic format for most entries:
Examples:
Spacing rules:
] before (- (dash)(FORMAT)Sources: docs/CONTRIBUTING-ml.md89-116
If the linter reports incorrect ordering, it will specify which lines need to be swapped.
Sources: docs/CONTRIBUTING-ml.md187-193
Commit Message Best Practices:
Use descriptive commit messages that explain the change:
Using the Pull Request Template:
When creating a PR, GitHub displays .github/PULL_REQUEST_TEMPLATE.md. Key sections to complete:
Template Structure:
| Section | What to Include | Example |
|---|---|---|
| What does this PR do? | Select one: Add resource(s) | Remove resource(s) | Add info | Improve repo | Add resource(s) |
| IMPORTANT | Checklist: Read guidelines, not revising previous PR | Check both boxes |
| Description | Brief description of the resource | "Python Crash Course - comprehensive intro to Python programming" |
| Why is this valuable? | Explain usefulness to learners | "Covers fundamentals through practical projects, regularly updated" |
| How do we know it's really free? | Explain free access | "Fully accessible at author's website with no registration" |
| Resource type check | Confirm it matches the list type | "Yes, this is a complete book in PDF and HTML formats" |
| Checklist | Items from template lines 18-22 | Search duplicates, check order, add format notes |
| Follow-up | Commit to monitoring checks | "Will watch GitHub Actions and fix any linter errors" |
Example Completed PR:
Sources: .github/PULL_REQUEST_TEMPLATE.md1-26
When you submit a PR, three GitHub Actions workflows run in parallel:
Sources: .github/workflows/fpb-lint.yml1-37 .github/workflows/comment-pr.yml1-56
| Workflow File | Trigger Event | Primary Tool/Command | What It Validates | Artifact Output |
|---|---|---|---|---|
.github/workflows/fpb-lint.yml | on: [pull_request] | fpb-lint books casts courses more | Alphabetical order, spacing, markdown syntax, entry structure | pr/ artifact containing error.log and PRurl |
.github/workflows/check-urls.yml | on: [pull_request] | awesome_bot (Ruby gem) | HTTP status codes, link accessibility, domain validity | ab-results-*.json per changed file |
.github/workflows/comment-pr.yml | workflow_run from fpb-lint.yml | gh pr comment, gh pr edit (GitHub CLI) | Processes lint results | Posts comment and applies/removes linter error label |
Sources: .github/workflows/fpb-lint.yml1-37 .github/workflows/comment-pr.yml1-56
Linter output:
books/free-programming-books-langs.md
Line 234: "Python for Beginners" should come after "Python Crash Course"
Swap lines 234 and 231
How to fix:
Sources: docs/CONTRIBUTING-ml.md187-193
Linter output:
courses/free-courses-en.md
Line 456: Missing space after ']' before '('
Expected: * <FileRef file-url="https://github.com/EbookFoundation/free-programming-books/blob/6a7d2f47/Title" undefined file-path="Title">Hii</FileRef>
Found: * [Title] (URL)
How to fix:
Sources: docs/CONTRIBUTING-ml.md89-94
Linter output:
books/free-programming-books-langs.md
Line 789: Incorrect author separator
Expected: space-dash-space ( - )
Found: dash only (-)
How to fix:
Sources: docs/CONTRIBUTING-ml.md96-101
awesome_bot output:
Issues with 1 link(s):
1. 404 https://old-site.com/tutorial
└── courses/free-courses-en.md:123
How to fix:
* [Title](https://web.archive.org/web/.../url) - Author (HTML) *(:card_file_box: archived)*Sources: docs/CONTRIBUTING-ml.md46-49 docs/CONTRIBUTING-ml.md138-142
For files with Right-to-Left languages (*-ar.md, *-he.md, *-fa.md, *-ur.md), special markers are required when mixing RTL and LTR text.
Common RTL linter errors:
books/free-programming-books-ar.md:45
WARNING: LTR text "JavaScript" in RTL context needs ‏ marker
Found: * <FileRef file-url="https://github.com/EbookFoundation/free-programming-books/blob/6a7d2f47/كتاب JavaScript" undefined file-path="كتاب JavaScript">Hii</FileRef>
Expected: * <FileRef file-url="https://github.com/EbookFoundation/free-programming-books/blob/6a7d2f47/كتاب JavaScript‏" undefined file-path="كتاب JavaScript‏">Hii</FileRef>
How to fix:
Rules:
‏ (Right-to-Left Mark) immediately after each Latin-script word (e.g., "HTML", "JavaScript", "Python")‎ (Left-to-Right Mark) after symbols containing LTR characters (e.g., "C#", "C++")Sources: docs/CONTRIBUTING-ta.md318-363
GitHub Actions Check Results Navigation:
Finding specific validation errors:
| Step | Action | What to Look For |
|---|---|---|
| 1 | Navigate to your PR page | URL: github.com/EbookFoundation/free-programming-books/pull/[NUMBER] |
| 2 | Click "Checks" tab | Near "Conversation", "Commits", "Files changed" tabs |
| 3 | Click "free-programming-books-lint" | Workflow name in left sidebar |
| 4 | Click "build" job | Job name under workflow |
| 5 | Expand "Pull Request" step | Contains fpb-lint command output |
| 6 | Read error messages | Format: filename.md Line X: [error description] |
| 7 (optional) | Download "pr" artifact | Contains error.log with full output |
Sources: .github/workflows/fpb-lint.yml14-36 .github/workflows/comment-pr.yml18-55
The comment-pr.yml workflow automatically comments on PRs when validation fails.
Comment Format:
Linter failed, fix the error(s):
books/free-programming-books-langs.md Line 234: Entry not in alphabetical order Line 456: Missing space after ']' courses/free-courses-en.md Line 789: Incorrect author format
Implementation Details:
workflow_run event from free-programming-books-lint workflow (comment-pr.yml3-7)pr using actions/github-script@v8 (comment-pr.yml18-37)error.log file has content: [ -s error.log ] (comment-pr.yml46)gh pr comment $(<PRurl) -b "Linter failed..." (comment-pr.yml48-51)gh pr edit $(<PRurl) --add-label "linter error" (comment-pr.yml52)gh pr edit $(<PRurl) --remove-label "linter error" (comment-pr.yml54)Once you fix the errors and push, the fpb-lint.yml workflow runs again and comment-pr.yml removes the label if validation passes.
Sources: .github/workflows/comment-pr.yml1-56
The contribution guidelines are available in 43+ languages. Use these if English is not your primary language:
| Language | Files |
|---|---|
| English | docs/CONTRIBUTING.md, docs/HOWTO.md |
| Hindi | docs/CONTRIBUTING-hi.md, docs/HOWTO-hi.md |
| Bengali | docs/CONTRIBUTING-bn.md, docs/HOWTO-bn.md |
| Chinese | docs/CONTRIBUTING-zh.md, docs/HOWTO-zh.md |
| Spanish | docs/CONTRIBUTING-es.md, docs/HOWTO-es.md |
| French | docs/CONTRIBUTING-fr.md, docs/HOWTO-fr.md |
| German | docs/CONTRIBUTING-de.md, docs/HOWTO-de.md |
| Portuguese (Brazil) | docs/CONTRIBUTING-pt_BR.md, docs/HOWTO-pt_BR.md |
| Tamil | docs/CONTRIBUTING-ta.md, docs/HOWTO-ta.md |
| Malayalam | docs/CONTRIBUTING-ml.md, docs/HOWTO-ml.md |
Full list available at docs/README.md1-149
Sources: docs/README.md1-149
| Resource Type | Primary File(s) | Notes |
|---|---|---|
| Books - By Language | books/free-programming-books-langs.md | Python, Java, C++, JavaScript, etc. |
| Books - By Subject | books/free-programming-books-subjects.md | Algorithms, Databases, Security, etc. |
| Books - Translated | books/free-programming-books-{LANG}.md | 40+ language editions |
| Courses - English | courses/free-courses-en.md | Primary course index |
| Courses - Other Languages | courses/free-courses-{LANG}.md | Hindi: -hi, Bengali: -bn, Spanish: -es, etc. |
| Interactive Tutorials | more/free-programming-interactive-tutorials-en.md | Try Haskell, Try Git style |
| Playgrounds | more/free-programming-playgrounds.md | Online code sandboxes |
| Cheat Sheets | more/free-programming-cheatsheets.md | Quick reference guides |
| Problem Sets | more/problem-sets-competitive-programming.md | LeetCode, Codeforces, etc. |
| Podcasts | casts/free-podcasts-screencasts-en.md | Audio/video learning |
Sources: docs/CONTRIBUTING-ml.md19-27
Solution: Use the decision tree in Step 2 above, or search the repository for similar resources.
Solution:
Possible causes:
Solution:
Sources: .github/workflows/check-urls.yml106-113
Solution:
docs/HOWTO.md or its translation in your languageSources: docs/CONTRIBUTING-ml.md15-17
After your PR is merged:
For detailed formatting rules, quality standards, and best practices, continue to Contribution Guidelines and Standards.
Refresh this wiki