Skip to content

Commit b061726

Browse files
authored
IFC-1361: Merge core read only repositories on branch merge (#7459)
* IFC-1361: Merge core read only repositories on branch merge * move logs * fix tests, fix mypy * add repository type to git merge repository * replace repository_type with repository_kind
1 parent f340ef7 commit b061726

File tree

6 files changed

+71
-5
lines changed

6 files changed

+71
-5
lines changed

backend/infrahub/core/merge.py

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22

33
from typing import TYPE_CHECKING
44

5-
from infrahub.core.constants import RepositoryInternalStatus
5+
from infrahub.core.constants import InfrahubKind, RepositoryInternalStatus
66
from infrahub.core.diff.model.path import BranchTrackingId
77
from infrahub.core.manager import NodeManager
88
from infrahub.core.models import SchemaUpdateValidationResult
9-
from infrahub.core.protocols import CoreRepository
9+
from infrahub.core.protocols import CoreReadOnlyRepository, CoreRepository
1010
from infrahub.core.registry import registry
1111
from infrahub.core.timestamp import Timestamp
1212
from infrahub.exceptions import MergeFailedError, ValidationError
@@ -223,6 +223,32 @@ async def rollback(self) -> None:
223223
await self.diff_merger.rollback(at=self._merge_at)
224224

225225
async def merge_repositories(self) -> None:
226+
await self.merge_core_read_only_repositories()
227+
await self.merge_core_repositories()
228+
229+
async def merge_core_read_only_repositories(self) -> None:
230+
repos_in_main_list = await NodeManager.query(schema=CoreReadOnlyRepository, db=self.db)
231+
repos_in_main = {repo.id: repo for repo in repos_in_main_list}
232+
233+
repos_in_branch_list = await NodeManager.query(
234+
schema=CoreReadOnlyRepository, db=self.db, branch=self.source_branch
235+
)
236+
for repo in repos_in_branch_list:
237+
if repo.id not in repos_in_main:
238+
continue
239+
240+
model = GitRepositoryMerge(
241+
repository_id=repo.id,
242+
repository_name=repo.name.value,
243+
source_branch=self.source_branch.name,
244+
destination_branch=self.destination_branch.name,
245+
destination_branch_id=str(self.destination_branch.get_uuid()),
246+
internal_status=repo.internal_status.value,
247+
repository_kind=InfrahubKind.READONLYREPOSITORY,
248+
)
249+
await self.workflow.submit_workflow(workflow=GIT_REPOSITORIES_MERGE, parameters={"model": model})
250+
251+
async def merge_core_repositories(self) -> None:
226252
# Collect all Repositories in Main because we'll need the commit in Main for each one.
227253
repos_in_main_list = await NodeManager.query(schema=CoreRepository, db=self.db)
228254
repos_in_main = {repo.id: repo for repo in repos_in_main_list}
@@ -245,5 +271,6 @@ async def merge_repositories(self) -> None:
245271
destination_branch=self.destination_branch.name,
246272
destination_branch_id=str(self.destination_branch.get_uuid()),
247273
default_branch=repo.default_branch.value,
274+
repository_kind=InfrahubKind.REPOSITORY,
248275
)
249276
await self.workflow.submit_workflow(workflow=GIT_REPOSITORIES_MERGE, parameters={"model": model})

backend/infrahub/git/models.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,8 @@ class GitRepositoryMerge(BaseModel):
9292
source_branch: str = Field(..., description="The source branch")
9393
destination_branch: str = Field(..., description="The destination branch")
9494
destination_branch_id: str = Field(..., description="The ID of the destination branch")
95-
default_branch: str = Field(..., description="The default branch in Git")
95+
default_branch: str | None = Field(default=None, description="The default branch in Git")
96+
repository_kind: str = Field(..., description="The kind of the repository.")
9697

9798

9899
class GitRepositoryImportObjects(BaseModel):

backend/infrahub/git/tasks.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,7 @@ async def pull_read_only(model: GitRepositoryPullReadOnly) -> None:
502502
flow_run_name="Merge {model.source_branch} > {model.destination_branch} in git repository",
503503
)
504504
async def merge_git_repository(model: GitRepositoryMerge) -> None:
505+
log = get_run_logger()
505506
await add_tags(branches=[model.source_branch, model.destination_branch], nodes=[model.repository_id])
506507

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

513-
if model.internal_status == RepositoryInternalStatus.STAGING.value:
514+
if (
515+
model.internal_status == RepositoryInternalStatus.STAGING.value
516+
and model.repository_kind == InfrahubKind.REPOSITORY
517+
):
518+
log.info(f"Merging {model.repository_kind}")
514519
repo_source = await client.get(
515520
kind=InfrahubKind.GENERICREPOSITORY, id=model.repository_id, branch=model.source_branch
516521
)
@@ -522,6 +527,28 @@ async def merge_git_repository(model: GitRepositoryMerge) -> None:
522527
repo_main.commit.value = commit
523528

524529
await repo_main.save()
530+
log.info(f"Finished merging {model.repository_kind}")
531+
532+
elif model.repository_kind == InfrahubKind.READONLYREPOSITORY:
533+
repo_source = await client.get(
534+
kind=InfrahubKind.READONLYREPOSITORY, id=model.repository_id, branch=model.source_branch
535+
)
536+
repo_destination = await client.get(
537+
kind=InfrahubKind.READONLYREPOSITORY, id=model.repository_id, branch=model.destination_branch
538+
)
539+
540+
if (
541+
repo_destination.ref.value != repo_source.ref.value
542+
or repo_destination.commit.value != repo_source.commit.value
543+
):
544+
log.info(f"Merging {model.repository_kind}")
545+
546+
repo_destination.ref.value = repo_source.ref.value
547+
repo_destination.commit.value = repo_source.commit.value
548+
await repo_destination.save()
549+
550+
log.info(f"Finished merging {model.repository_kind}")
551+
525552
else:
526553
async with lock.registry.get(name=model.repository_name, namespace="repository"):
527554
await repo.merge(source_branch=model.source_branch, dest_branch=model.destination_branch)

backend/tests/unit/core/diff/test_coordinator_lock.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
from infrahub.core.merge import BranchMerger
1717
from infrahub.core.node import Node
1818
from infrahub.core.schema import SchemaRoot
19-
from infrahub.core.schema.definitions.core.repository import core_repository
19+
from infrahub.core.schema.definitions.core.repository import core_read_only_repository, core_repository
2020
from infrahub.core.schema.node_schema import NodeSchema
2121
from infrahub.core.timestamp import Timestamp
2222
from infrahub.database import InfrahubDatabase, get_db
@@ -55,6 +55,15 @@ async def dummy_repository_schema(self, db: InfrahubDatabase, default_branch: Br
5555
default_branch.update_schema_hash()
5656
await default_branch.save(db=db)
5757

58+
dummy_repository = NodeSchema(
59+
name=core_read_only_repository.name,
60+
namespace=core_read_only_repository.namespace,
61+
)
62+
schema = SchemaRoot(nodes=[dummy_repository])
63+
registry.schema.register_schema(schema=schema, branch=default_branch.name)
64+
default_branch.update_schema_hash()
65+
await default_branch.save(db=db)
66+
5867
async def get_diff_coordinator(self, db: InfrahubDatabase, diff_branch: Branch) -> DiffCoordinator:
5968
config.SETTINGS.database.max_depth_search_hierarchy = 10
6069
component_registry = get_component_registry()

backend/tests/unit/git/test_git_rpc.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ async def test_git_rpc_merge(
143143
destination_branch_id="469cd407-0a8f-4d4e-9629-84fa435cf5ad",
144144
internal_status=RepositoryInternalStatus.ACTIVE.value,
145145
default_branch="main",
146+
repository_kind=InfrahubKind.REPOSITORY,
146147
)
147148

148149
client = InfrahubClient(config=Config(requester=dummy_async_request))

changelog/5978.added.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Merge core read only repositories on branch merge

0 commit comments

Comments
 (0)