Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 29 additions & 2 deletions backend/infrahub/core/merge.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

from typing import TYPE_CHECKING

from infrahub.core.constants import RepositoryInternalStatus
from infrahub.core.constants import InfrahubKind, RepositoryInternalStatus
from infrahub.core.diff.model.path import BranchTrackingId
from infrahub.core.manager import NodeManager
from infrahub.core.models import SchemaUpdateValidationResult
from infrahub.core.protocols import CoreRepository
from infrahub.core.protocols import CoreReadOnlyRepository, CoreRepository
from infrahub.core.registry import registry
from infrahub.core.timestamp import Timestamp
from infrahub.exceptions import MergeFailedError, ValidationError
Expand Down Expand Up @@ -223,6 +223,32 @@ async def rollback(self) -> None:
await self.diff_merger.rollback(at=self._merge_at)

async def merge_repositories(self) -> None:
await self.merge_core_read_only_repositories()
await self.merge_core_repositories()

async def merge_core_read_only_repositories(self) -> None:
repos_in_main_list = await NodeManager.query(schema=CoreReadOnlyRepository, db=self.db)
repos_in_main = {repo.id: repo for repo in repos_in_main_list}

repos_in_branch_list = await NodeManager.query(
schema=CoreReadOnlyRepository, db=self.db, branch=self.source_branch
)
for repo in repos_in_branch_list:
if repo.id not in repos_in_main:
continue

model = GitRepositoryMerge(
repository_id=repo.id,
repository_name=repo.name.value,
source_branch=self.source_branch.name,
destination_branch=self.destination_branch.name,
destination_branch_id=str(self.destination_branch.get_uuid()),
internal_status=repo.internal_status.value,
repository_kind=InfrahubKind.READONLYREPOSITORY,
)
await self.workflow.submit_workflow(workflow=GIT_REPOSITORIES_MERGE, parameters={"model": model})

async def merge_core_repositories(self) -> None:
# Collect all Repositories in Main because we'll need the commit in Main for each one.
repos_in_main_list = await NodeManager.query(schema=CoreRepository, db=self.db)
repos_in_main = {repo.id: repo for repo in repos_in_main_list}
Expand All @@ -245,5 +271,6 @@ async def merge_repositories(self) -> None:
destination_branch=self.destination_branch.name,
destination_branch_id=str(self.destination_branch.get_uuid()),
default_branch=repo.default_branch.value,
repository_kind=InfrahubKind.REPOSITORY,
)
await self.workflow.submit_workflow(workflow=GIT_REPOSITORIES_MERGE, parameters={"model": model})
3 changes: 2 additions & 1 deletion backend/infrahub/git/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ class GitRepositoryMerge(BaseModel):
source_branch: str = Field(..., description="The source branch")
destination_branch: str = Field(..., description="The destination branch")
destination_branch_id: str = Field(..., description="The ID of the destination branch")
default_branch: str = Field(..., description="The default branch in Git")
default_branch: str | None = Field(default=None, description="The default branch in Git")
repository_kind: str = Field(..., description="The kind of the repository.")


class GitRepositoryImportObjects(BaseModel):
Expand Down
29 changes: 28 additions & 1 deletion backend/infrahub/git/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,7 @@ async def pull_read_only(model: GitRepositoryPullReadOnly) -> None:
flow_run_name="Merge {model.source_branch} > {model.destination_branch} in git repository",
)
async def merge_git_repository(model: GitRepositoryMerge) -> None:
log = get_run_logger()
await add_tags(branches=[model.source_branch, model.destination_branch], nodes=[model.repository_id])

client = get_client()
Expand All @@ -510,7 +511,11 @@ async def merge_git_repository(model: GitRepositoryMerge) -> None:
id=model.repository_id, name=model.repository_name, client=client, default_branch_name=model.default_branch
)

if model.internal_status == RepositoryInternalStatus.STAGING.value:
if (
model.internal_status == RepositoryInternalStatus.STAGING.value
and model.repository_kind == InfrahubKind.REPOSITORY
):
log.info(f"Merging {model.repository_kind}")
repo_source = await client.get(
kind=InfrahubKind.GENERICREPOSITORY, id=model.repository_id, branch=model.source_branch
)
Expand All @@ -522,6 +527,28 @@ async def merge_git_repository(model: GitRepositoryMerge) -> None:
repo_main.commit.value = commit

await repo_main.save()
log.info(f"Finished merging {model.repository_kind}")

elif model.repository_kind == InfrahubKind.READONLYREPOSITORY:
repo_source = await client.get(
kind=InfrahubKind.READONLYREPOSITORY, id=model.repository_id, branch=model.source_branch
)
repo_destination = await client.get(
kind=InfrahubKind.READONLYREPOSITORY, id=model.repository_id, branch=model.destination_branch
)

if (
repo_destination.ref.value != repo_source.ref.value
or repo_destination.commit.value != repo_source.commit.value
):
log.info(f"Merging {model.repository_kind}")

repo_destination.ref.value = repo_source.ref.value
repo_destination.commit.value = repo_source.commit.value
await repo_destination.save()

log.info(f"Finished merging {model.repository_kind}")

else:
async with lock.registry.get(name=model.repository_name, namespace="repository"):
await repo.merge(source_branch=model.source_branch, dest_branch=model.destination_branch)
Expand Down
11 changes: 10 additions & 1 deletion backend/tests/unit/core/diff/test_coordinator_lock.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from infrahub.core.merge import BranchMerger
from infrahub.core.node import Node
from infrahub.core.schema import SchemaRoot
from infrahub.core.schema.definitions.core.repository import core_repository
from infrahub.core.schema.definitions.core.repository import core_read_only_repository, core_repository
from infrahub.core.schema.node_schema import NodeSchema
from infrahub.core.timestamp import Timestamp
from infrahub.database import InfrahubDatabase, get_db
Expand Down Expand Up @@ -55,6 +55,15 @@ async def dummy_repository_schema(self, db: InfrahubDatabase, default_branch: Br
default_branch.update_schema_hash()
await default_branch.save(db=db)

dummy_repository = NodeSchema(
name=core_read_only_repository.name,
namespace=core_read_only_repository.namespace,
)
schema = SchemaRoot(nodes=[dummy_repository])
registry.schema.register_schema(schema=schema, branch=default_branch.name)
default_branch.update_schema_hash()
await default_branch.save(db=db)

async def get_diff_coordinator(self, db: InfrahubDatabase, diff_branch: Branch) -> DiffCoordinator:
config.SETTINGS.database.max_depth_search_hierarchy = 10
component_registry = get_component_registry()
Expand Down
1 change: 1 addition & 0 deletions backend/tests/unit/git/test_git_rpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ async def test_git_rpc_merge(
destination_branch_id="469cd407-0a8f-4d4e-9629-84fa435cf5ad",
internal_status=RepositoryInternalStatus.ACTIVE.value,
default_branch="main",
repository_kind=InfrahubKind.REPOSITORY,
)

client = InfrahubClient(config=Config(requester=dummy_async_request))
Expand Down
1 change: 1 addition & 0 deletions changelog/5978.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Merge core read only repositories on branch merge
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 | 🟡 Minor

Use hyphenation for compound adjective.

The phrase "read only" should be hyphenated as "read-only" when used as a compound adjective.

Apply this diff:

-Merge core read only repositories on branch merge
+Merge core read-only repositories on branch merge
📝 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
Merge core read only repositories on branch merge
Merge core read-only repositories on branch merge
🧰 Tools
🪛 LanguageTool

[grammar] ~1-~1: Use a hyphen to join words.
Context: Merge core read only repositories on branch merge

(QB_NEW_EN_HYPHEN)

🤖 Prompt for AI Agents
In changelog/5978.added.md around lines 1 to 1 the phrase "read only" is used as
a compound adjective; update it to "read-only" so the line reads "Merge core
read-only repositories on branch merge".

Loading