Skip to content

Commit 4936737

Browse files
authored
Merge pull request #4788 from opsmill/lgu-migrate-git-repository-add
Migrate GitRepositoryAdd to prefect
2 parents 320529e + ae35bf1 commit 4936737

File tree

12 files changed

+125
-134
lines changed

12 files changed

+125
-134
lines changed

backend/infrahub/git/models.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,18 @@ class RequestArtifactGenerate(BaseModel):
3535
variables: dict = Field(..., description="Input variables when generating the artifact")
3636

3737

38+
class GitRepositoryAdd(BaseModel):
39+
"""Clone and sync an external repository after creation."""
40+
41+
location: str = Field(..., description="The external URL of the repository")
42+
repository_id: str = Field(..., description="The unique ID of the Repository")
43+
repository_name: str = Field(..., description="The name of the repository")
44+
created_by: Optional[str] = Field(default=None, description="The user ID of the user that created the repository")
45+
default_branch_name: Optional[str] = Field(None, description="Default branch for this repository")
46+
infrahub_branch_name: str = Field(..., description="Infrahub branch on which to sync the remote repository")
47+
internal_status: str = Field(..., description="Administrative status of the repository")
48+
49+
3850
class GitRepositoryPullReadOnly(BaseModel):
3951
"""Update a read-only repository to the latest commit for its ref"""
4052

backend/infrahub/git/tasks.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from ..workflows.catalogue import REQUEST_ARTIFACT_DEFINITION_GENERATE, REQUEST_ARTIFACT_GENERATE
1414
from ..workflows.utils import add_branch_tag
1515
from .models import (
16+
GitRepositoryAdd,
1617
GitRepositoryMerge,
1718
GitRepositoryPullReadOnly,
1819
RequestArtifactDefinitionGenerate,
@@ -23,6 +24,32 @@
2324
log = get_logger()
2425

2526

27+
@flow(name="git-repository-add-read-write")
28+
async def add_git_repository(model: GitRepositoryAdd) -> None:
29+
service = services.service
30+
async with service.git_report(
31+
related_node=model.repository_id,
32+
title=f"Initial import of the repository in branch: {model.infrahub_branch_name}",
33+
created_by=model.created_by,
34+
) as git_report:
35+
async with lock.registry.get(name=model.repository_name, namespace="repository"):
36+
repo = await InfrahubRepository.new(
37+
id=model.repository_id,
38+
name=model.repository_name,
39+
location=model.location,
40+
client=service.client,
41+
task_report=git_report,
42+
infrahub_branch_name=model.infrahub_branch_name,
43+
internal_status=model.internal_status,
44+
default_branch_name=model.default_branch_name,
45+
)
46+
await repo.import_objects_from_files(
47+
infrahub_branch_name=model.infrahub_branch_name, git_branch_name=model.default_branch_name
48+
)
49+
if model.internal_status == RepositoryInternalStatus.ACTIVE.value:
50+
await repo.sync()
51+
52+
2653
@flow(name="git_repositories_create_branch")
2754
async def create_branch(branch: str, branch_id: str) -> None:
2855
"""Request to the creation of git branches in available repositories."""

backend/infrahub/graphql/mutations/repository.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@
1010
from infrahub.core.protocols import CoreGenericRepository, CoreReadOnlyRepository, CoreRepository
1111
from infrahub.core.schema import NodeSchema
1212
from infrahub.exceptions import ValidationError
13-
from infrahub.git.models import GitRepositoryPullReadOnly
13+
from infrahub.git.models import GitRepositoryAdd, GitRepositoryPullReadOnly
1414
from infrahub.graphql.types.common import IdentifierInput
1515
from infrahub.log import get_logger
1616
from infrahub.message_bus import messages
1717
from infrahub.message_bus.messages.git_repository_connectivity import GitRepositoryConnectivityResponse
18-
from infrahub.workflows.catalogue import GIT_REPOSITORIES_PULL_READ_ONLY
18+
from infrahub.workflows.catalogue import GIT_REPOSITORIES_PULL_READ_ONLY, GIT_REPOSITORY_ADD
1919

2020
from .main import InfrahubMutationMixin, InfrahubMutationOptions
2121

@@ -99,9 +99,12 @@ async def mutate_create(
9999
internal_status=obj.internal_status.value,
100100
created_by=authenticated_user,
101101
)
102+
if context.service:
103+
await context.service.send(message=message)
104+
102105
else:
103106
obj = cast(CoreRepository, obj)
104-
message = messages.GitRepositoryAdd(
107+
git_repo_add_model = GitRepositoryAdd(
105108
repository_id=obj.id,
106109
repository_name=obj.name.value,
107110
location=obj.location.value,
@@ -111,8 +114,10 @@ async def mutate_create(
111114
created_by=authenticated_user,
112115
)
113116

114-
if context.service:
115-
await context.service.send(message=message)
117+
if context.service:
118+
await context.service.workflow.submit_workflow(
119+
workflow=GIT_REPOSITORY_ADD, parameters={"model": git_repo_add_model}
120+
)
116121

117122
# TODO Validate that the creation of the repository went as expected
118123

backend/infrahub/message_bus/messages/__init__.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
from .finalize_validator_execution import FinalizeValidatorExecution
1616
from .git_diff_namesonly import GitDiffNamesOnly, GitDiffNamesOnlyResponse
1717
from .git_file_get import GitFileGet, GitFileGetResponse
18-
from .git_repository_add import GitRepositoryAdd
1918
from .git_repository_connectivity import GitRepositoryConnectivity
2019
from .git_repository_importobjects import GitRepositoryImportObjects
2120
from .git_repository_read_only_add import GitRepositoryAddReadOnly
@@ -54,7 +53,6 @@
5453
"finalize.validator.execution": FinalizeValidatorExecution,
5554
"git.diff.names_only": GitDiffNamesOnly,
5655
"git.file.get": GitFileGet,
57-
"git.repository.add": GitRepositoryAdd,
5856
"git.repository.connectivity": GitRepositoryConnectivity,
5957
"git.repository.add_read_only": GitRepositoryAddReadOnly,
6058
"git.repository.import_objects": GitRepositoryImportObjects,

backend/infrahub/message_bus/messages/git_repository_add.py

Lines changed: 0 additions & 17 deletions
This file was deleted.

backend/infrahub/message_bus/operations/__init__.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
"finalize.validator.execution": finalize.validator.execution,
3535
"git.diff.names_only": git.diff.names_only,
3636
"git.file.get": git.file.get,
37-
"git.repository.add": git.repository.add,
3837
"git.repository.add_read_only": git.repository.add_read_only,
3938
"git.repository.connectivity": git.repository.connectivity,
4039
"git.repository.import_objects": git.repository.import_objects,

backend/infrahub/message_bus/operations/git/repository.py

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -15,37 +15,6 @@
1515
log = get_logger()
1616

1717

18-
@flow(name="git-repository-add-read-write")
19-
async def add(message: messages.GitRepositoryAdd, service: InfrahubServices) -> None:
20-
log.info(
21-
"Cloning and importing repository",
22-
repository=message.repository_name,
23-
location=message.location,
24-
internal_status=message.internal_status,
25-
)
26-
async with service.git_report(
27-
related_node=message.repository_id,
28-
title=f"Initial import of the repository in branch: {message.infrahub_branch_name}",
29-
created_by=message.created_by,
30-
) as git_report:
31-
async with lock.registry.get(name=message.repository_name, namespace="repository"):
32-
repo = await InfrahubRepository.new(
33-
id=message.repository_id,
34-
name=message.repository_name,
35-
location=message.location,
36-
client=service.client,
37-
task_report=git_report,
38-
infrahub_branch_name=message.infrahub_branch_name,
39-
internal_status=message.internal_status,
40-
default_branch_name=message.default_branch_name,
41-
)
42-
await repo.import_objects_from_files(
43-
infrahub_branch_name=message.infrahub_branch_name, git_branch_name=message.default_branch_name
44-
)
45-
if message.internal_status == RepositoryInternalStatus.ACTIVE.value:
46-
await repo.sync()
47-
48-
4918
@flow(name="git-repository-add-read-only")
5019
async def add_read_only(message: messages.GitRepositoryAddReadOnly, service: InfrahubServices) -> None:
5120
log.info(

backend/infrahub/workflows/catalogue.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,15 @@
138138
tags=[WorkflowTag.DATABASE_CHANGE],
139139
)
140140

141+
GIT_REPOSITORY_ADD = WorkflowDefinition(
142+
name="git-repository-add-read-write",
143+
type=WorkflowType.INTERNAL,
144+
module="infrahub.git.tasks",
145+
function="add_git_repository",
146+
branch_support=BranchSupportType.AWARE,
147+
tags=[WorkflowTag.DATABASE_CHANGE],
148+
)
149+
141150
GIT_REPOSITORIES_PULL_READ_ONLY = WorkflowDefinition(
142151
name="git-repository-pull-read-only",
143152
type=WorkflowType.INTERNAL,
@@ -222,4 +231,5 @@
222231
BRANCH_CANCEL_PROPOSED_CHANGES,
223232
REQUEST_GENERATOR_DEFINITION_RUN,
224233
UPDATE_GRAPHQL_QUERY_GROUP,
234+
GIT_REPOSITORY_ADD,
225235
]

backend/tests/helpers/file_repo.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@
1515
class FileRepo:
1616
name: str
1717
sources_directory: Path
18+
19+
# Some tests make a prior copy of fixtures/repos/car-dealership folder in a temp folder,
20+
# in which case we need to use that temp folder instead of fixture dir. This could probably be removed
21+
# when https://github.com/opsmill/infrahub/issues/4296 is fixed.
22+
local_repo_base_path: Path = get_fixtures_dir() / "repos"
23+
1824
_repo: Optional[Repo] = None
1925
_initial_branch: Optional[str] = None
2026
_branches: list[str] = field(default_factory=list)
@@ -48,7 +54,7 @@ def _apply_pull_requests(self, repo_base: Path) -> None:
4854
self.repo.git.commit("-m", pull_request)
4955

5056
def __post_init__(self) -> None:
51-
repo_base = Path(get_fixtures_dir(), "repos", self.name)
57+
repo_base = Path(self.local_repo_base_path, self.name)
5258
initial_directory = self._initial_directory(repo_base=repo_base)
5359
shutil.copytree(repo_base / initial_directory, self.sources_directory / self.name)
5460
self._repo = Repo.init(self.sources_directory / self.name, initial_branch=self._initial_branch)

backend/tests/integration/proposed_change/test_proposed_change_conflict.py

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
from __future__ import annotations
22

3+
import shutil
4+
import tempfile
5+
from pathlib import Path
36
from typing import TYPE_CHECKING
47

58
import pytest
@@ -10,21 +13,37 @@
1013
from infrahub.core.manager import NodeManager
1114
from infrahub.core.node import Node
1215
from infrahub.services.adapters.cache.redis import RedisCache
16+
from infrahub.utils import get_fixtures_dir
1317
from tests.constants import TestKind
1418
from tests.helpers.file_repo import FileRepo
1519
from tests.helpers.schema import CAR_SCHEMA, load_schema
1620
from tests.helpers.test_app import TestInfrahubApp
1721

1822
if TYPE_CHECKING:
19-
from pathlib import Path
20-
2123
from infrahub_sdk import InfrahubClient
2224

2325
from infrahub.database import InfrahubDatabase
2426
from tests.adapters.message_bus import BusSimulator
2527

2628

2729
class TestProposedChangePipelineConflict(TestInfrahubApp):
30+
@pytest.fixture(scope="class")
31+
def car_dealership_copy(self):
32+
"""
33+
Copies car-dealership local repository to a temporary folder, with a new name.
34+
This is needed for this test as using car-dealership folder leads to issues most probably
35+
related to https://github.com/opsmill/infrahub/issues/4296 as some other tests use this same repository.
36+
"""
37+
38+
source_folder = Path(get_fixtures_dir(), "repos", "car-dealership")
39+
new_folder_name = "car-dealership-copy"
40+
41+
with tempfile.TemporaryDirectory() as temp_dir:
42+
temp_path = Path(temp_dir)
43+
destination_folder = temp_path / new_folder_name
44+
shutil.copytree(source_folder, destination_folder)
45+
yield temp_path, new_folder_name
46+
2847
@pytest.fixture(scope="class")
2948
async def initial_dataset(
3049
self,
@@ -33,6 +52,7 @@ async def initial_dataset(
3352
git_repos_source_dir_module_scope: Path,
3453
client: InfrahubClient,
3554
bus_simulator: BusSimulator,
55+
car_dealership_copy: tuple[Path, str],
3656
) -> str:
3757
await load_schema(db, schema=CAR_SCHEMA)
3858
john = await Node.init(schema=TestKind.PERSON, db=db)
@@ -57,10 +77,11 @@ async def initial_dataset(
5777
await jesko.save(db=db)
5878

5979
bus_simulator.service.cache = RedisCache()
60-
FileRepo(name="car-dealership", sources_directory=git_repos_source_dir_module_scope)
80+
repo_path, repo_name = car_dealership_copy
81+
FileRepo(name=repo_name, local_repo_base_path=repo_path, sources_directory=git_repos_source_dir_module_scope)
6182
client_repository = await client.create(
6283
kind=InfrahubKind.REPOSITORY,
63-
data={"name": "car-dealership", "location": f"{git_repos_source_dir_module_scope}/car-dealership"},
84+
data={"name": "dealership-car", "location": f"{git_repos_source_dir_module_scope}/{repo_name}"},
6485
)
6586
await client_repository.save()
6687
return client_repository.id

0 commit comments

Comments
 (0)