Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@solababs
Copy link
Contributor

@solababs solababs commented Oct 27, 2025

This PR adds sync_branch_names parameter to git settings so that users can add branches that they want to be synced with git instead of syncing all branches like we currently do. This parameter can also be a regex so that we can match branch names when syncing

Summary by CodeRabbit

  • New Features
    • Branch synchronization now accepts configurable branch-name patterns (plain names or regex) with validation and clear errors for invalid patterns.
  • Documentation
    • Added documentation and examples for the Git branch sync configuration option.
  • Tests
    • Added unit tests covering valid and invalid branch-pattern configurations.

This PR adds `sync_branch_names` parameter to git settings so that users can add branches that they want to be synced with git
instead of syncing all branches like we currently do.
This parameter can also be a regex so that we can match branch names when syncing
@solababs solababs requested a review from a team as a code owner October 27, 2025 15:51
@github-actions github-actions bot added the group/backend Issue related to the backend (API Server, Git Agent) label Oct 27, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 27, 2025

Walkthrough

Added a new public field sync_branch_names: list[str] to GitSettings and a post-processing validator @model_validator(mode="after") def validate_sync_branch_names that compiles each entry in sync_branch_names with re.compile, raising ValueError on invalid patterns. Unit tests were added to check valid and invalid regex patterns. Documentation for INFRAHUB_GIT_SYNC_BRANCH_NAMES was added.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The pull request title "IFC-1983: Add config parameter for selective git sync" accurately and clearly summarizes the main change in the changeset. The changes introduce a new sync_branch_names configuration parameter to GitSettings that allows users to specify which branches to sync with git using explicit names or regex patterns, along with corresponding validation logic, tests, and documentation. The title is specific, concise, and avoids vague terminology or unnecessary noise while remaining informative enough for a developer scanning the history to understand the primary change.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch sb-20251027-config-for-selective-git-sync-ifc-1983

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 261196e and 080b64b.

📒 Files selected for processing (1)
  • backend/infrahub/config.py (2 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
backend/**/*

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Run backend tests with pytest or via invoke tasks

Files:

  • backend/infrahub/config.py
**/*.py

📄 CodeRabbit inference engine (.github/instructions/python-docstring.instructions.md)

**/*.py: Use triple double quotes (""") for all Python docstrings
Write docstrings in Google-style format
Include a brief one-line description at the top of each docstring
Add a detailed description section when additional context is needed
Document function/method parameters under an Args/Parameters section without typing information
Include a Returns section describing the return value
Include a Raises section listing possible exceptions
Provide an Examples section demonstrating usage when helpful

Use ruff and mypy to validate and lint Python files

**/*.py: Use type hints for all Python function parameters and return values
Prefer asynchronous code in Python when feasible
Define asynchronous Python functions with async def
Use await for asynchronous calls in Python
Use Pydantic models instead of standard dataclasses
Use ruff and mypy for linting and type checking

**/*.py: Use type hints for all Python function parameters and return values
Use async/await whenever possible in Python code
Define asynchronous functions with async def
Await asynchronous calls with await
Use Pydantic models instead of standard dataclasses for data modeling
Use triple quotes (""") for all Python docstrings
Write docstrings in Google-style format
Include docstring sections when applicable: one-line summary, optional details, Args (without types), Returns, Raises, Examples
Validate and lint Python with ruff and mypy

Files:

  • backend/infrahub/config.py
🧬 Code graph analysis (1)
backend/infrahub/config.py (1)
backend/tests/integration/schema_lifecycle/test_generic_migrations.py (1)
  • branch_name (114-116)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: documentation
  • GitHub Check: validate-generated-documentation
  • GitHub Check: backend-tests-functional
  • GitHub Check: backend-tests-integration
🔇 Additional comments (2)
backend/infrahub/config.py (2)

4-4: LGTM!

The re module import is necessary for the validator and is correctly placed with other standard library imports.


448-451: LGTM!

The field definition is well-structured with proper type hints, a sensible default, and a clear description. The examples effectively demonstrate that both plain branch names (like 'main') and regex patterns (like 'infrahub/.*') are supported.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 77d439f and a7fd3ee.

📒 Files selected for processing (2)
  • backend/infrahub/config.py (2 hunks)
  • backend/tests/unit/test_config.py (2 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
backend/tests/**/*

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Place backend tests in backend/tests/

Files:

  • backend/tests/unit/test_config.py
backend/**/*

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Run backend tests with pytest or via invoke tasks

Files:

  • backend/tests/unit/test_config.py
  • backend/infrahub/config.py
**/*.py

📄 CodeRabbit inference engine (.github/instructions/python-docstring.instructions.md)

**/*.py: Use triple double quotes (""") for all Python docstrings
Write docstrings in Google-style format
Include a brief one-line description at the top of each docstring
Add a detailed description section when additional context is needed
Document function/method parameters under an Args/Parameters section without typing information
Include a Returns section describing the return value
Include a Raises section listing possible exceptions
Provide an Examples section demonstrating usage when helpful

Use ruff and mypy to validate and lint Python files

**/*.py: Use type hints for all Python function parameters and return values
Prefer asynchronous code in Python when feasible
Define asynchronous Python functions with async def
Use await for asynchronous calls in Python
Use Pydantic models instead of standard dataclasses
Use ruff and mypy for linting and type checking

**/*.py: Use type hints for all Python function parameters and return values
Use async/await whenever possible in Python code
Define asynchronous functions with async def
Await asynchronous calls with await
Use Pydantic models instead of standard dataclasses for data modeling
Use triple quotes (""") for all Python docstrings
Write docstrings in Google-style format
Include docstring sections when applicable: one-line summary, optional details, Args (without types), Returns, Raises, Examples
Validate and lint Python with ruff and mypy

Files:

  • backend/tests/unit/test_config.py
  • backend/infrahub/config.py
🧬 Code graph analysis (1)
backend/tests/unit/test_config.py (1)
backend/infrahub/config.py (2)
  • GitSettings (435-469)
  • UserInfoMethod (57-59)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
  • GitHub Check: E2E-testing-version-upgrade / From 1.3.0
  • GitHub Check: backend-benchmark
  • GitHub Check: E2E-testing-playwright
  • GitHub Check: validate-generated-documentation
  • GitHub Check: graphql-schema
  • GitHub Check: backend-tests-unit
  • GitHub Check: backend-docker-integration
  • GitHub Check: backend-tests-functional
  • GitHub Check: backend-tests-integration
🔇 Additional comments (3)
backend/tests/unit/test_config.py (1)

1-3: LGTM!

The imports are correct and necessary for the new test functions.

backend/infrahub/config.py (2)

4-4: LGTM!

The re module import is necessary for regex compilation in the validator.


448-452: LGTM!

The field definitions follow Pydantic best practices with appropriate types, defaults, and descriptions.

Comment on lines 454 to 469
@model_validator(mode="after")
def validate_sync_branch_names(self) -> Self:
compiled_branch_names = []
for branch_name in self.sync_branch_names:
if not branch_name.startswith("/") and not branch_name.endswith("/"):
compiled_branch_names.append(branch_name)
continue

pattern = branch_name.strip("/")
try:
re.compile(pattern)
compiled_branch_names.append(pattern)
except re.error as exc:
raise ValueError(f"Invalid regex pattern for sync_branch_names: '{branch_name}' — {exc}") from exc
self._compiled_branch_names = compiled_branch_names
return self
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Add docstring for the validator method.

The validator is missing a docstring, which is required by the coding guidelines. The docstring should explain the validation logic, parameters, return value, and exceptions.

As per coding guidelines.

Apply this diff:

 @model_validator(mode="after")
 def validate_sync_branch_names(self) -> Self:
+    """Validate and compile sync_branch_names patterns.
+    
+    Processes each entry in sync_branch_names: plain branch names are
+    preserved as-is, while regex patterns (delimited by forward slashes)
+    are extracted, validated, and stored in _compiled_branch_names.
+    
+    Returns:
+        The GitSettings instance with populated _compiled_branch_names.
+    
+    Raises:
+        ValueError: If a regex pattern is invalid or cannot be compiled.
+    """
     compiled_branch_names = []
🤖 Prompt for AI Agents
In backend/infrahub/config.py around lines 454 to 469, the model_validator
method validate_sync_branch_names lacks a docstring; add a concise docstring
immediately below the decorator and above the def that explains the purpose
(validates and compiles sync_branch_names into _compiled_branch_names),
describes parameters (self containing sync_branch_names), the return value
(returns self), and the exceptions raised (ValueError for invalid regex
patterns), and briefly outlines the validation logic (preserve plain names,
strip slashes and compile regexes, storing compiled patterns), keeping it short
and following project docstring style.

Comment on lines 458 to 462
if not branch_name.startswith("/") and not branch_name.endswith("/"):
compiled_branch_names.append(branch_name)
continue

pattern = branch_name.strip("/")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Fix the regex detection logic to require both leading and trailing slashes.

The current condition on line 458 treats any branch name with a leading OR trailing slash as a regex pattern. Per the PR description stating "regex patterns wrapped in forward slashes," the logic should require BOTH slashes to indicate a regex pattern. Otherwise, legitimate branch names like /feature or feature/ could be misinterpreted.

Additionally, consider using slice notation [1:-1] instead of strip("/") for clarity and to remove exactly one slash from each end rather than all leading/trailing slashes.

Apply this diff:

     compiled_branch_names = []
     for branch_name in self.sync_branch_names:
-        if not branch_name.startswith("/") and not branch_name.endswith("/"):
+        if not (branch_name.startswith("/") and branch_name.endswith("/")):
             compiled_branch_names.append(branch_name)
             continue
 
-        pattern = branch_name.strip("/")
+        if len(branch_name) <= 2:
+            raise ValueError(f"Invalid regex pattern for sync_branch_names: '{branch_name}' — pattern cannot be empty")
+        pattern = branch_name[1:-1]
         try:
             re.compile(pattern)

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In backend/infrahub/config.py around lines 458 to 462, change the detection so a
branch name is treated as a regex only when it has BOTH a leading and trailing
slash: replace the current condition that uses "not startswith('/') and not
endswith('/')" with a check like "if not (branch_name.startswith('/') and
branch_name.endswith('/')): compiled_branch_names.append(branch_name);
continue". Then extract the pattern using slice notation to remove exactly one
slash from each end (pattern = branch_name[1:-1]) and optionally guard against
too-short values (e.g., ensure len(branch_name) > 1) before slicing.

Comment on lines 26 to 30
def test_valid_git_settings__sync_branch_names():
sync_branch_names = ["main", "/infrahub/.*/", "/release/.*/"]
git_settings = GitSettings(sync_branch_names=sync_branch_names)
assert git_settings.sync_branch_names == sync_branch_names
assert git_settings._compiled_branch_names == ["main", "infrahub/.*", "release/.*"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Add docstring and return type hint.

The test function is missing a docstring and return type hint, which are required by the coding guidelines.

As per coding guidelines.

Apply this diff:

 def test_valid_git_settings__sync_branch_names():
+    """Test that GitSettings correctly processes valid sync_branch_names.
+    
+    Verifies that plain branch names are preserved and regex patterns
+    (wrapped in forward slashes) are correctly compiled.
+    """

Additionally, add the return type hint:

-def test_valid_git_settings__sync_branch_names():
+def test_valid_git_settings__sync_branch_names() -> None:
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def test_valid_git_settings__sync_branch_names():
sync_branch_names = ["main", "/infrahub/.*/", "/release/.*/"]
git_settings = GitSettings(sync_branch_names=sync_branch_names)
assert git_settings.sync_branch_names == sync_branch_names
assert git_settings._compiled_branch_names == ["main", "infrahub/.*", "release/.*"]
def test_valid_git_settings__sync_branch_names() -> None:
"""Test that GitSettings correctly processes valid sync_branch_names.
Verifies that plain branch names are preserved and regex patterns
(wrapped in forward slashes) are correctly compiled.
"""
sync_branch_names = ["main", "/infrahub/.*/", "/release/.*/"]
git_settings = GitSettings(sync_branch_names=sync_branch_names)
assert git_settings.sync_branch_names == sync_branch_names
assert git_settings._compiled_branch_names == ["main", "infrahub/.*", "release/.*"]
🤖 Prompt for AI Agents
In backend/tests/unit/test_config.py around lines 26 to 30, the test function
test_valid_git_settings__sync_branch_names is missing a docstring and a return
type hint; add a brief docstring describing the purpose of the test (e.g.,
"Ensure sync_branch_names are stored and compiled correctly") and add a return
type hint of -> None to the function signature so it reads def
test_valid_git_settings__sync_branch_names() -> None:, keeping the existing
assertions unchanged.

Comment on lines 33 to 35
def test_invalid_git_settings__sync_branch_names():
with pytest.raises(ValueError):
GitSettings(sync_branch_names=["main", "/infrahub/.*/", "/release/.*/", "/a[b/"])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Add docstring and return type hint.

The test function is missing a docstring and return type hint, which are required by the coding guidelines.

As per coding guidelines.

Apply this diff:

-def test_invalid_git_settings__sync_branch_names():
+def test_invalid_git_settings__sync_branch_names() -> None:
+    """Test that GitSettings raises ValueError for invalid regex patterns.
+    
+    Verifies that malformed regex patterns in sync_branch_names are
+    properly rejected during validation.
+    """
     with pytest.raises(ValueError):
🤖 Prompt for AI Agents
In backend/tests/unit/test_config.py around lines 33 to 35, the test function
test_invalid_git_settings__sync_branch_names is missing a docstring and a return
type hint; add a one-line docstring directly under the def explaining the test
purpose (e.g., "Ensure invalid sync branch name patterns raise ValueError") and
add the return type hint "-> None" to the function signature so it reads def
test_invalid_git_settings__sync_branch_names() -> None:.

@codspeed-hq
Copy link

codspeed-hq bot commented Oct 27, 2025

CodSpeed Performance Report

Merging #7482 will not alter performance

Comparing sb-20251027-config-for-selective-git-sync-ifc-1983 (080b64b) with develop (bbe96ae)

Summary

✅ 10 untouched

@solababs solababs requested review from a team as code owners October 27, 2025 16:32
@github-actions github-actions bot added the type/documentation Improvements or additions to documentation label Oct 27, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
docs/docs/reference/configuration.mdx (1)

55-55: Clarify the regex syntax and default behavior in the description.

The description "Names or regex of branches to sync with git" is too vague. Based on the backend implementation, users need to know:

  1. Regex syntax: How to specify regex patterns (e.g., wrapped in /pattern/ delimiters)
  2. Default behavior: What happens when the value is None (e.g., "syncs all branches" or "disables selective filtering")
  3. Examples: Concrete usage examples (e.g., ["main", "/release/.*/"])

Consider revising the description to something like: "Specify branches to sync with git using explicit names or regular expressions (wrapped in /pattern/). When unset, all branches are synced."

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a7fd3ee and bc48883.

📒 Files selected for processing (1)
  • docs/docs/reference/configuration.mdx (1 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
docs/docs/reference/**/*.{md,mdx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Write reference documentation in docs/docs/reference/

Files:

  • docs/docs/reference/configuration.mdx
docs/**/*.mdx

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use Docusaurus markdown/MDX features in documentation

docs/**/*.mdx: How-to guides should begin title with "How to..." and follow the Diataxis How-to structure (intro, prerequisites, step-by-step, validation, advanced, related)
Use imperative, task-focused instructions in guides; avoid digressions
Topics should use titles like "About..." or "Understanding..." and follow the Diataxis Topics structure (concepts, background, architecture, mental models, connections, alternatives, further reading)
Define new terms on first use; prefer domain-relevant terminology; keep naming consistent with Infrahub UI/data model

Files:

  • docs/docs/reference/configuration.mdx
docs/**/*

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Develop documentation in docs/, preview with invoke docs.build docs.serve, and validate with invoke docs.validate

Files:

  • docs/docs/reference/configuration.mdx
**/*.mdx

📄 CodeRabbit inference engine (.github/instructions/documentation.instructions.md)

**/*.mdx: Structure documentation primarily as How-to Guides and Topics (explanations) following the Diataxis framework
Use a professional, approachable tone; avoid jargon unless defined; use plain language with technical precision
Write concise, direct, active sentences
Be informative over promotional; focus on explaining how and why
Maintain consistent, predictable structure across sections and documents
For Guides: use conditional imperatives (e.g., "If you want X, do Y")
For Guides: focus on practical tasks and problems, not tools
For Guides: address the user directly with imperative verbs (e.g., "Configure...", "Create...")
For Guides: keep focus on the specific goal; avoid digressions into explanations
For Guides: title in YAML frontmatter should clearly state the problem and begin with "How to..."
For Guides: include an Introduction stating the problem/goal, context, and what the user will achieve
For Guides: include a Prerequisites/Assumptions section listing requirements and prior knowledge
For Guides: provide step-by-step instructions with numbered steps; include code snippets/screenshots/tabs/callouts as needed
For Guides: include a Validation/Verification section with checks, example outputs, and potential failure points
For Guides: include a Related Resources section linking to relevant guides/topics/reference
For Topics: title in YAML frontmatter should clearly indicate the topic; consider starting with "About..." or "Understanding..."
For Topics: include an Introduction with overview, why it matters, and questions answered
For Topics: include sections for Concepts & Definitions
For Topics: include Background & Context (history, design rationale, constraints)
For Topics: include Architecture & Design details/diagrams when applicable
For Topics: include Mental Models (analogies/comparisons)
For Topics: connect to other concepts and integration points
For Topics: include Alternative Approaches with pros/cons where relevant
For Topics: include a Further...

Files:

  • docs/docs/reference/configuration.mdx
**/*.{md,mdx}

📄 CodeRabbit inference engine (CLAUDE.md)

Lint Markdown/MDX files with markdownlint using .markdownlint.yaml

Files:

  • docs/docs/reference/configuration.mdx
docs/!(node_modules)/**/*.{md,mdx}

📄 CodeRabbit inference engine (CLAUDE.md)

docs/!(node_modules)/**/*.{md,mdx}: Lint documentation prose with Vale
Ensure Vale style checks pass for documentation

Files:

  • docs/docs/reference/configuration.mdx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
  • GitHub Check: E2E-testing-version-upgrade / From 1.3.0
  • GitHub Check: E2E-testing-playwright
  • GitHub Check: backend-benchmark
  • GitHub Check: validate-generated-documentation
  • GitHub Check: documentation
  • GitHub Check: graphql-schema
  • GitHub Check: backend-docker-integration
  • GitHub Check: backend-tests-functional
  • GitHub Check: backend-tests-unit
  • GitHub Check: backend-tests-integration
🔇 Additional comments (1)
docs/docs/reference/configuration.mdx (1)

6-7: Update the template file (infrahub_config.j2) instead of editing this auto-generated reference.

This file is generated from a Jinja2 template. Ensure your changes are applied to the template file referenced in lines 6-7, and then regenerate this documentation using invoke docs.generate-config.

Also applies to: 55-55

def validate_sync_branch_names(self) -> Self:
compiled_branch_names = []
for branch_name in self.sync_branch_names:
if not branch_name.startswith("/") and not branch_name.endswith("/"):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can assume that any of the entries should be compiled to regex that way we could treat them all the same. I.e. if we have a branch called "my-branch1" it would work just the same to do a re.compile("my-branch1") and use regex to validate that name. Or people could write regular expressions using a different format such as "^branch-".

@solababs solababs requested a review from ogenstad October 29, 2025 04:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

group/backend Issue related to the backend (API Server, Git Agent) type/documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants