Learning Platform
Глоссарий Troubleshooting
Урок 15.02 · 30 мин
Продвинутый
dbt-coreopen sourcecontributeGitHub PR

Путь A: Contribute в dbt-core

Если вы выбрали этот путь — поздравляем, это самый коммьюнити-visible из трёх. Цель — open и merge real Pull Request в dbt-core. Это даст вам:

  • Commit с вашим именем в dbt-core/main branch forever.
  • Mention в release notes (e.g., “Fixed by @yourusername in #12345”).
  • Portfolio piece для resume.
  • Networking с dbt Labs maintainers.

Реалистичная timeline: 15-30 часов, distributed over 2-6 недель (включая review iterations).


conftest.py, project layouts, pyproject.toml — discovery configuration

Step 1: Setup development environment

dbt-core uses hatch для project management. Setup:

# 1. Fork dbt-core на GitHub
# Через github.com/dbt-labs/dbt-core -> Fork button

# 2. Clone ваш fork
git clone https://github.com/YOUR_USERNAME/dbt-core.git
cd dbt-core

# 3. Add upstream remote (для syncing changes)
git remote add upstream https://github.com/dbt-labs/dbt-core.git

# 4. Install hatch
pip install hatch

# 5. Create development environment
hatch env create

# 6. Activate
hatch shell

# 7. Verify
dbt --version
# Должно показать локально установленный dbt-core (development version)

dbt-core поддерживает Python 3.10, 3.11, 3.12, 3.13 (по состоянию 2026). Используйте 3.11 или 3.12 для best compatibility:

hatch env create --python 3.11
NOTE

hatch — современный Python project manager (alternative к Poetry, pipenv). dbt Labs migrated на него в 2024. Если впервые видите — это OK, основные команды стандартные: hatch shell (activate env), hatch run (execute commands), hatch test (run tests).

Verify setup

# Run some unit tests
hatch run pytest tests/unit/test_partial_parser.py -v

# Should pass all green.

# Run linting
hatch run dev:lint

# Should pass.

Если что-то fails — check requirements (Python version, dependencies). Issue trackers на GitHub имеют solutions для known setup problems.


Step 2: Найти good first issue

GitHub Issue Filtering:

URL: https://github.com/dbt-labs/dbt-core/issues
Filters: 
  label:good_first_issue
  label:triage:accepted
  is:open

Это даёт current list good first issues, которые maintainers verified.

Что искать

Хороший good_first_issue

Process выбора

  1. Open 5-10 candidates.
  2. Read each issue carefully.
  3. Eliminate те, которые seem too complex.
  4. Pick top 2-3 candidates.
  5. Comment на каждом: “Hi, I’d like to work on this. Can I take it?”
  6. Wait for maintainer response (typically 1-3 days).
  7. Once approved -> start working.

Pro tip: на этом шаге легко procrastinate выбирая “perfect” issue. Don’t. Pick reasonable one, start working. Worst case — switch to another.


Step 3: Reproduce the issue

Don’t write code yet. First reproduce.

# Read the issue carefully.
# Identify reproduction steps.
# Run them locally.

# Example: issue says "dbt parse fails on YAML with X"
mkdir test_project && cd test_project
dbt init
# Create YAML with X
# Run: dbt parse
# Observe failure

If reproduction succeeds — you have failing test scenario. If fails (can’t reproduce) — either issue is stale (post comment, ask for clarification) or you’re missing something.

Common reasons fail to reproduce:

  • dbt-core version mismatch (try main vs latest release).
  • Environment difference (Python version, dependencies).
  • Specific config not mentioned в issue.
  • Issue already partially fixed.

Step 4: Write failing test

dbt-core uses pytest. Tests organized:

tests/
├── unit/                # unit tests, no DB
│   ├── parser/
│   ├── adapter/
│   └── ...
├── functional/           # integration с DBs (Postgres usually)
└── e2e/                 # full CLI tests

For most good_first_issues — unit test is enough.

Example: Issue says “error message wrong on missing source”

Find related test file:

grep -r "missing source" tests/unit/

Likely finds tests/unit/parser/test_parse_sources.py. Read it:

import pytest

class TestParseMissingSources:
    def test_missing_source_error_message(self):
        # ... existing test scenarios ...
        pass

    def test_my_new_scenario(self):
        """
        Test that missing source gives clear error message с file location.
        """
        # arrange: project with reference to non-existent source
        ...
        
        # act: run parser
        with pytest.raises(MissingSourceError) as exc_info:
            parse_project(project_with_missing_source)
        
        # assert: error message contains file:line:column
        error_message = str(exc_info.value)
        assert "models/staging/stg_orders.sql" in error_message
        assert "line 5" in error_message
        assert "source('jaffle_shop', 'missing_source')" in error_message

Run the test:

hatch run pytest tests/unit/parser/test_parse_sources.py::TestParseMissingSources::test_my_new_scenario -v

Test should FAIL (red). Это ваш starting point.


Step 5: Implement the fix

Now find где fix должен быть.

# Where is MissingSourceError raised?
grep -r "MissingSourceError" core/dbt/

Read that code. Understand currently raised. Add file:line:column information.

# core/dbt/parser/sources.py (hypothetical)
class SourceParser:
    def parse_source_reference(self, node, source_ref):
        if source_ref.name not in self.known_sources:
            raise MissingSourceError(
                source_name=source_ref.name,
                # BEFORE: just source name
                # AFTER: include node file location
                location=f"{node.original_file_path}:{node.line}:{node.column}",
            )

Run test again:

hatch run pytest tests/unit/parser/test_parse_sources.py::TestParseMissingSources::test_my_new_scenario -v

Test passes? Excellent.

Make sure existing tests still pass:

hatch run pytest tests/unit/parser/

All green? Implementation done.


Step 6: Quality checks

Before opening PR:

# Linting
hatch run dev:lint

# Type checking
hatch run dev:typecheck

# All tests на your area
hatch run pytest tests/unit/parser/ -v

# (Optional) Run functional tests for affected area
hatch run pytest tests/functional/parser/ -v

Fix any failures. Lint должен быть clean.


Step 7: Write CHANGELOG entry

dbt-core uses changie для changelog management:

# Install changie если not yet
brew install miniscruff/changie/changie   # macOS
# Or download from https://github.com/miniscruff/changie/releases

# Generate changelog entry
changie new

Interactive prompts:

Kind: Fix
Body: Include file location in MissingSourceError message
Custom:
  Issue: 12345
  PR:

This creates .changes/unreleased/Fix-...yaml. Commit it.


Step 8: Commit and push

dbt-core uses commit message conventions:

git add core/dbt/parser/sources.py tests/unit/parser/test_parse_sources.py .changes/unreleased/Fix-*.yaml

git commit -m "fix: include file location in MissingSourceError message

Issue: #12345

The error message previously showed only the source name without
indicating where in the project file the reference was made.
This change adds file:line:column to make debugging easier.
"

# Push to your fork
git push origin your-branch-name

Commit conventions (dbt-core uses these prefixes):

  • fix: — bug fix
  • feat: — new feature
  • docs: — documentation
  • test: — tests only
  • refactor: — code refactoring без behavior change
  • chore: — maintenance, dependencies

Step 9: Open Pull Request

On GitHub:

  1. Navigate to your fork.
  2. Click “Pull Request” button.
  3. Base: dbt-labs/dbt-core:main. Compare: YOUR_USERNAME/dbt-core:your-branch.
  4. Title: fix: include file location in MissingSourceError message
  5. Description (use the dbt-core PR template):
## Resolves

Fixes #12345.

## Problem

The `MissingSourceError` error message previously contained only the source name. Users had difficulty locating where in the project the bad reference was made.

## Solution

Added `original_file_path:line:column` to the error message. Now users see exactly where the bad reference is.

## Checklist

- [x] I have read the [contributing guide](https://github.com/dbt-labs/dbt-core/blob/main/CONTRIBUTING.md).
- [x] I have run the test suite.
- [x] I have added new tests for my change.
- [x] I have updated documentation if needed.
- [x] I have added a CHANGELOG entry.

## Testing

```bash
hatch run pytest tests/unit/parser/test_parse_sources.py

All passing.


6. Submit.

---

## Step 10: Iterate on review

Within 1-3 days, dbt-core maintainer will review. Common feedback:

### Feedback 1: "Add more test cases"

> "Could you also test the case where source is in nested folder?"

Action: add the test case, commit, push.

### Feedback 2: "Use existing pattern"

> "dbt-core has a `format_location()` helper for this. Use that instead of manually concatenating."

Action: refactor to use the helper, commit, push.

### Feedback 3: "Update docs"

> "This changes the error format. Please update docs/migration_guide.md."

Action: update docs, commit, push.

### Feedback 4: Style nits

> "Use single quotes here. Consistent с file style."

Action: trivial change, commit, push.

### How to interact с maintainers

- **Respond promptly** (1-2 days). Maintainers have limited time.
- **Disagree politely** if you think feedback is wrong. Explain reasoning.
- **Ask if unsure** — better to clarify than guess.
- **Be patient** — review cycles can take weeks.
- **Be grateful** — maintainers volunteer their time.

---

## Step 11: Merged!

Eventually (1-4 weeks typically), maintainer says:

> "Looks great! Merging now. Thanks for the contribution!"

PR merged. Your contribution живёт в dbt-core forever.

You can:

- Add to your resume: "Contributed bug fix to dbt-core (PR #XXXXX, merged May 2026)."
- LinkedIn post: "Excited to share my first dbt-core contribution merged today!"
- Twitter/dev.to blog post.

---

## Common pitfalls

<DiagramContainer title="Чего избегать" color="red">
  <Grid columns={2}>
    <FlowColumn>
      <DataBox variant="warning" size="sm" title="Не выбирайте сложный issue">
        {'Refactoring issues, parsing engine, performance — слишком много для first PR. Pick error messages, doc improvements, edge cases. Save complex для после first merged PR.'}
      </DataBox>
      <DataBox variant="warning" size="sm" title="Не игнорируйте linting">
        {'Failed lint в CI = "fix and re-push" cycles. Run lint locally before commit. Single most common rejected-pull-request reason.'}
      </DataBox>
      <DataBox variant="warning" size="sm" title="Не пропускайте tests">
        {'Tests are mandatory. Maintainers require both new test (proving fix works) и existing tests pass. No tests = PR closed.'}
      </DataBox>
    </FlowColumn>
    <FlowColumn>
      <DataBox variant="warning" size="sm" title="Не быть упрямым в reviews">
        {'Если maintainer says "use this pattern" — usually they right (more dbt-core context). Argue только если у вас strong technical reasoning. Otherwise — accept feedback.'}
      </DataBox>
      <DataBox variant="warning" size="sm" title="Не ghost после opening PR">
        {'Open PR + disappear = abandoned. If you commit к contribute, follow through. Respond к reviews. Если life happens, comment "I will get back в X days" — show commitment.'}
      </DataBox>
      <DataBox variant="warning" size="sm" title="Не забывайте CHANGELOG entry">
        {'CHANGELOG required для merge. Easy to forget. Maintainers will remind, но showing care from start makes good impression.'}
      </DataBox>
    </FlowColumn>
  </Grid>
</DiagramContainer>

---

## Что считается "good capstone PR"

For purposes of this course:

- **Minimum**: Fix a `good_first_issue`. PR opened, ready for review.
- **Target**: Fix the issue, PR merged.
- **Stretch**: Multiple commits showing iteration на review feedback, merged. Optional second PR for related issue.

Even **opened but not yet merged** is excellent capstone — shows ability to work in real OSS.

---

## Realistic timeline expectations

```text
Day 1-2:    Setup environment, fork, browse issues.
Day 3-5:    Pick issue, comment, get approval.
Day 6-10:   Reproduce, write test, implement fix.
Day 11-14:  Quality checks, CHANGELOG, open PR.

Week 2-4:   Review iterations (1-3 cycles).

Week 4-6:   Merged.

Total: ~6 weeks elapsed time, 15-30 hours actual work. Distributed over time because of review delays.


Проверка знанийKnowledge check
После opening PR на dbt-core, неделю никаких reviews. Что делать?
ОтветAnswer
Это normal scenario в open source — maintainer time limited, не все PRs get immediate review. Понимание best practice — important for OSS contribution success. **Step 1: Wait reasonable time.** For dbt-core specifically: - Initial review: 3-7 рабочих дней typical. - Follow-up reviews: 2-5 рабочих дней each. - Holidays (Christmas, year-end): can be 2-3 weeks delay. - Conference time (Coalesce): review delays. Иногда maintainers triage сначала (label, assign reviewer), потом actual review. Triage = 1-2 days. Review = 1-2 weeks. Для **первой недели после PR open**: just wait. Это normal. **Step 2: Check PR status.** Go to your PR на GitHub. Check: 1. **Labels**: Has triage label been added? `triage:in-review` или similar means it's в queue. 2. **Assignees**: Has maintainer been assigned? Means it's in their personal queue. 3. **Comments**: Any messages в comments? Sometimes maintainer says "I'll look this week" or similar. 4. **CI status**: All checks passing? Если CI failing — maintainer may be waiting for you to fix. Если CI failing — **fix it**. Don't wait for review pointing it out. **Step 3: Politely ping after week.** If 5-7 business days passed без any movement — gentle nudge OK. Comment на PR: ``` Hi @maintainer-team! Just bumping this. Let me know if there are any changes needed. Happy to wait — just wanted to check it's not lost in the queue. ``` Key points: - **Polite**, not demanding. - **Self-aware** — "if it's lost", не "why no review". - **Patient** — "happy to wait". - **Specific** — "Just bumping this" is clear context. **What NOT to do:** Don't: - Tag random maintainers indiscriminately (@everyone). - Spam с multiple comments. - Show frustration ("why is this taking so long"). - Email maintainers privately demanding review. - Open new PR with same fix (creates noise). - Close в раздражении. These alienate maintainers и hurt OSS reputation. **Step 4: Check community channels.** If 2+ weeks passed and ping unanswered: - dbt Slack `#contributors` channel. - Ask: "Hey, I have a PR open #12345 для week. Any guidance on когда review might happen?" - Often community members могут help triangulate. Maintainers sometimes respond faster в Slack vs GitHub. **Step 5: Check related issues.** Open issue page. See: - Status changed? (e.g., issue labeled "blocked"). - Linked alternative PRs (someone else fixing it). - Maintainer comments в issue. If другой PR already in review — your PR may be deprecated. Comment to clarify situation. **Step 6: Use time productively.** While waiting: 1. **Browse other good_first_issues** — start preliminary work на secondary PR. 2. **Improve your PR** — better tests, more edge cases, clearer documentation. Show effort. 3. **Engage в community** — comment on others' issues, help newcomers. Build reputation. 4. **Learn dbt-core deeper** — read source code, get familiar. Waiting time isn't wasted if used wisely. **Step 7: Worst case — escalation paths.** Very rare, but if month passed без any response: - Reach out to dbt Labs through formal channels (jobs или contact pages). - Twitter mention to dbt-labs official account. - Comment on Discourse community forum. These are **last resorts**. Most PRs reviewed within reasonable time. **Step 8: Manage expectations.** Not all PRs accepted. Reasons: - Scope не fits dbt-core direction. - Better approach found by maintainer. - Approach is correct, но needs significant refactor (long iteration cycle). - Project priorities shifted. If PR closed without merge — это not failure. You still: - Learned dbt-core internals. - Built OSS skills. - Have visible work на GitHub. - Can transfer learnings к other projects. Frame closed PR positively: "Explored fix для dbt-core issue, learned approach is suboptimal, took different solution approach forward." **Step 9: For this course capstone specifically.** Don't wait for merge как mandatory for capstone completion. For capstone purposes: - **Excellent**: PR opened, well-tested, good description. - **Excellent +**: PR merged. - **Excellent +++**: Multiple PRs merged. If PR opened and waiting — **document это в portfolio:** "Opened PR в dbt-core (https://github.com/dbt-labs/dbt-core/pull/XXXXX) implementing fix for [issue]. Currently awaiting review by maintainers. Includes: failing test, implementation, CHANGELOG entry, всё в style guide. Process demonstrates OSS contribution workflow." Это credible portfolio piece even before merge. **Главный урок:** OSS contribution = patience + politeness + persistence. Maintainers are humans, volunteer time (или divided time at job). One week delay = normal. Two weeks = mild concern, polite ping. Month = community channel escalation. Manage your expectations, use waiting time productively, и не take silence personally. Your PR будет reviewed eventually — может не be merged, но reviewed.

Проверка знанийKnowledge check
Maintainer оставил feedback: 'I think your approach is fundamentally wrong. We should solve this differently через X mechanism.' Что делать?
ОтветAnswer
Это classical OSS scenario — your approach challenged. Reaction matters profundamente. **Avoid these reactions:** [X] **Defensive:** "But my approach works!" [X] **Personal:** "Why are you criticizing me?" [X] **Sulking:** Close PR без response. [X] **Stubborn:** Push back without understanding their reasoning. [X] **Surrender:** "OK, I'll close" without understanding. None of these helpful, и harm your reputation в community. **Proper response sequence:** **Step 1: Pause and breathe.** Receiving "your approach is wrong" stings. Это feels personal. Не respond immediately. Take **24 hours**. Why: emotional response = bad response. Cool head needed. **Step 2: Read feedback carefully и understand.** Re-read several times. Specifically: - What does maintainer think is wrong? - What alternative do they suggest? - Why do they prefer alternative? - Are there technical reasons или style preferences? Note: maintainer wasn't trying to be hurtful. They reviewing dozens of PRs weekly. Their feedback is **technical**, not personal. **Step 3: Investigate alternative.** If maintainer suggested **X mechanism** instead, dig: - Find X в codebase. Read its implementation. - Understand how X works. - See where X is used elsewhere. - Compare to your approach. Questions to answer для self: - Is X cleaner architecturally? - Does X scale better? - Is X more consistent с rest of codebase? - Does X have advantages I missed? Often: maintainer right because they have **broader context** of codebase you don't have. **Step 4: Acknowledge and explore (in comment).** Reply на PR: ``` Thanks для feedback! Let me make sure I understand: You suggest using X mechanism instead. Looking at: - core/dbt/X.py for example usage - The advantages в [specific scenario] A few questions: 1. For [specific case], how does X handle [specific scenario]? 2. Should the test from my PR be migrated, or rewritten entirely? 3. Is there a doc или ADR explaining preferred patterns? I'll look into это more и report back. ``` This demonstrates: - **Acknowledgement** — you heard them. - **Investigation** — you're trying to understand, not argue. - **Curiosity** — you want learn. - **Specific questions** — you've actually looked. Good maintainers love this. They'll explain more, help you grow. **Step 5: Decide path forward.** After investigation, three options: **Option A: Refactor к their approach.** If X is better — change approach. Replace your implementation, update tests. ``` Thanks для feedback! I've refactored to use X mechanism. New commit pushed. Let me know if this matches what you had in mind. ``` Maintainer often grateful for receptivity. Future reviews easier. **Option B: Discuss tradeoff if convinced your approach has merit.** If после investigation вы still think your approach is reasonable (rare, but happens): ``` I looked into X mechanism, and I see how it would work для this case. However, я concerned about [specific issue]: [explain]. Would this scenario work in X approach? If yes, я'll refactor. If это limitation, perhaps мы should explore further? I'm open to either path — wanted to surface concern first. ``` Polite, technical, открытый. Maintainer respects this — shows you thought carefully. **Option C: Ask для design discussion.** If scope is large (refactor would change much): ``` Before I refactor, would it make sense to draft an ADR (Architecture Decision Record) или design doc для this? I want to make sure we agree on approach before significant code change. Would @maintainer be available for short async discussion? ``` This prevents wasted effort на wrong direction. **Step 6: Reciprocity и engagement.** During iteration, maintain warmth: - "Thanks for taking the time на review." - "I learned something from this — never seen X used like that." - "Good catch, I missed that edge case." This builds relationship. Maintainer remembers next time, gives faster reviews. **Step 7: Avoid these mistakes.** Don't: - Add many "But why?" комментариев. One question — fine. Three back-to-back — annoying. - Block on maintainer answering questions. They're not your personal teacher. - Take changes personally. They reviewing **code**, не **you**. - Get political ("everyone else does это"). dbt-core has its own style. **Step 8: When maintainer is wrong.** Rare, but happens. Maintainers make mistakes. If you have strong technical reason, polite pushback OK: ``` I understand the preference, but consider: [specific scenario] doesn't seem covered by X. In case [example], X would [fail / not handle / be unclear]. My approach handles it because [reason]. Would you have suggestions для adapting X к cover this? Otherwise, я think my approach might be more robust here. ``` Key: **technical reasoning**, **specific example**, **alternative suggestion**. Not emotional. If maintainer convinced — refactor X to handle the case. If maintainer maintains preference — accept their judgment (they have context). **Step 9: After resolution.** Once PR merged (either way) — thank maintainer publicly: ``` Thanks для thorough review @maintainer! The X approach is definitely cleaner. Learning opportunity. Looking forward to next contribution. ``` This cements positive impression. Future PRs reviewed faster. **Step 10: For this course capstone.** Receiving feedback и handling well is **excellent capstone material**. Document в portfolio: "Submitted PR к dbt-core fixing [issue]. Maintainer suggested alternative approach using X mechanism — refactored to use X, learning new pattern в dbt-core architecture. PR merged after iteration." This shows: - Reception к feedback (collaboration skill). - Ability to learn (growth mindset). - Code adaptability (technical skill). - Professional communication (soft skill). All **highly valued senior skills**. **Главный урок:** OSS PR feedback = opportunity to learn и build relationships, не attack on your skills. Reception matters more than initial code quality. Senior engineers who handle critical feedback gracefully — promoted и invited back. Those who get defensive или quit — burnt out of OSS community. React like senior, regardless of how it feels in moment.

Итого

  1. Path A capstone = opened or merged PR в dbt-core.
  2. Setup: fork, clone, install hatch, create env.
  3. Find good first issue with care: triage:accepted, recent, scope-limited.
  4. Reproduce the issue before writing code.
  5. Write failing test first (TDD approach).
  6. Implement fix in source code.
  7. Quality checks: lint, typecheck, tests pass.
  8. CHANGELOG entry через changie.
  9. Commit с conventional message format.
  10. PR description uses dbt-core template.
  11. Iterate review feedback politely и promptly.
  12. Timeline: ~6 weeks elapsed, 15-30 hours actual.
  13. Common pitfalls: complex issues, ignoring linting, no tests, stubbornness in review, ghosting.
  14. Even unmerged PR is excellent portfolio piece if well-crafted.

Next: урок 03 для path B (adapter), или урок 05 если path A complete и ready for portfolio packaging.

Проверьте понимание

Результат: 0 из 0
Концептуальный
Вопрос 1 из 5. Какие шаги в Path A capstone?

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 5