fix: convert branches and users child streams to INCREMENTAL replication - #56
fix: convert branches and users child streams to INCREMENTAL replication#56atttiwari wants to merge 10 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR updates the branches and users child streams to use INCREMENTAL replication (via ChildBaseStream) by propagating the parent project’s updated_at into each emitted record, along with schema/test updates and a version bump.
Changes:
- Convert
BranchesandUsersstreams fromFullTableStreamtoChildBaseStreamand switch replication method toINCREMENTALwithreplication_keys = ["updated_at"]. - Add
updated_atto thebranchesandusersJSON schemas and add unit tests covering the new behavior. - Bump package version from
1.1.2to1.2.0.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/unittests/test_projects_stream.py | Adds unit tests asserting Branches/Users are ChildBaseStream, INCREMENTAL, and set project_id + updated_at from the parent. |
| tap_gitlab/streams/users.py | Converts Users stream to INCREMENTAL and sets updated_at from the parent project in modify_object. |
| tap_gitlab/streams/branches.py | Converts Branches stream to INCREMENTAL and sets updated_at from the parent project in modify_object. |
| tap_gitlab/schemas/users.json | Adds updated_at field to support incremental replication key on emitted user records. |
| tap_gitlab/schemas/branches.json | Adds updated_at field to support incremental replication key on emitted branch records. |
| setup.py | Updates package version to 1.2.0. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| def modify_object(self, record, parent_record=None): | ||
| """Adding project_id and last_committed_date to the record""" | ||
| if isinstance(record, dict): | ||
| if parent_record and isinstance(parent_record, dict): | ||
| record["project_id"] = parent_record.get("id") | ||
| """Add project_id and parent project's updated_at (used as replication key) to each record.""" | ||
| if isinstance(record, dict) and parent_record and isinstance(parent_record, dict): | ||
| record["project_id"] = parent_record.get("id") | ||
| record["updated_at"] = parent_record.get("updated_at") | ||
|
|
| def modify_object(self, record, parent_record=None): | ||
| """Add project_id and parent project's updated_at (used as replication key) to each record.""" | ||
| if isinstance(record, dict) and parent_record and isinstance(parent_record, dict): | ||
| record["project_id"] = parent_record.get("id") | ||
| record["updated_at"] = parent_record.get("updated_at") | ||
|
|
193938b to
93d9c54
Compare
| "updated_at": { | ||
| "type": [ | ||
| "null", | ||
| "string" | ||
| ], | ||
| "format": "date-time" | ||
| }, |
There was a problem hiding this comment.
Why do we need to add this field? If it to bookmark then ideally we should bookmark child stream on parent bookmark.
There was a problem hiding this comment.
IMO we don't need to add it.
…eplication-method-for-child-streams
477c7e3 to
3f03384
Compare
| setup( | ||
| name='tap-gitlab', | ||
| version='1.1.2', | ||
| version='1.2.0', |
There was a problem hiding this comment.
Please make this a major release.
e6bc2ea to
5c2b872
Compare
There was a problem hiding this comment.
branches and users now obey start_date, contrary to the integration contract.
IncrementalStream.sync() gets the parent bookmark, defaults it to start_date, and only emits records whose projects_updated_at is at or after that value (abstracts.py:171-208). The new child streams use that path and populate projects_updated_at from the parent project (branches.py:32-37, users.py:32-37).
However, the integration expectations still explicitly mark both streams as OBEYS_START_DATE: False (base.py:40-48, base.py:75-83). A project whose updated_at is before the configured start date will therefore produce neither its branches nor users, even though the tests still expect those child streams not to obey the start date.
Update the integration contract to OBEYS_START_DATE: True and verify the intended behavior
There was a problem hiding this comment.
updated_since is sent to endpoints that do not use the parent timestamp as a child filter.
Every incremental stream adds updated_since to self.params before calling get_records() (abstracts.py:173-182). For the new streams, that means requests such as:
GET /projects/{id}/repository/branches?updated_since=...
GET /projects/{id}/users?updated_since=...
The GitLab branches and project-users endpoints are list endpoints whose filtering parameters do not include updated_since. If GitLab ignores unknown parameters this is harmless, but if it rejects or changes behavior for unknown query parameters, every incremental child sync can fail or return incorrect data.
More importantly, the actual filtering is performed against the parent project timestamp in Python, so sending updated_since to the child endpoint provides no benefit. The child implementation should either avoid adding this parameter for these endpoints or explicitly document and test that GitLab ignores it.
There was a problem hiding this comment.
Before this PR, child extraction was already parent-driven because only incrementally eligible projects invoked the child streams. The proposed change correctly labels branches and users as incremental only if projects.updated_at is a valid change cursor for their child data. Since the new projects_updated_at field is copied unchanged onto every child record, this remains parent-driven replication rather than true child-level incremental replication. Please confirm that GitLab advances the parent project’s updated_at for every branch/user mutation; otherwise the PR mainly changes metadata, state, and duplicate suppression without improving child change detection.
There was a problem hiding this comment.
As per the guidelines, if the child does not have a replication key available in the API response, we should use the parent-driven replication key.
Description of change
This PR updates the branches and users child streams to use INCREMENTAL replication (via ChildBaseStream) by propagating the parent project’s updated_at into each emitted record, along with schema/test updates and a version bump. SAC-31625
Changes:
Manual QA steps
Risks
Rollback steps
AI generated code
https://internal.qlik.dev/general/ways-of-working/code-reviews/#guidelines-for-ai-generated-code