orchestra-cli 0.5.1__tar.gz → 0.5.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/PKG-INFO +1 -1
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli/src/migrate_pipeline.py +3 -1
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli/tests/test_import_pipeline.py +2 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli/tests/utils/test_git.py +43 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli/utils/git.py +25 -2
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli.egg-info/PKG-INFO +1 -1
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/pyproject.toml +1 -1
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/README.md +0 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli/src/__init__.py +0 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli/src/build_pipeline.py +0 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli/src/cli.py +0 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli/src/create_pipeline.py +0 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli/src/delete_pipeline.py +0 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli/src/fetch_pipelines.py +0 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli/src/get_pipeline.py +0 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli/src/import_pipeline.py +0 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli/src/list_accounts.py +0 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli/src/login.py +0 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli/src/login_page.html +0 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli/src/pipeline_upsert.py +0 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli/src/run_pipeline.py +0 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli/src/task_logs.py +0 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli/src/update_pipeline.py +0 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli/src/use_account.py +0 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli/src/validate_pipeline.py +0 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli/tests/__init__.py +0 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli/tests/conftest.py +0 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli/tests/test_build_pipeline.py +0 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli/tests/test_cli.py +0 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli/tests/test_create_pipeline.py +0 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli/tests/test_delete_pipeline.py +0 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli/tests/test_fetch_pipelines.py +0 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli/tests/test_get_pipeline.py +0 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli/tests/test_list_accounts.py +0 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli/tests/test_login.py +0 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli/tests/test_migrate_pipeline.py +0 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli/tests/test_pipeline_selector.py +0 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli/tests/test_run_pipeline.py +0 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli/tests/test_task_logs.py +0 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli/tests/test_update_pipeline.py +0 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli/tests/test_use_account.py +0 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli/tests/test_validate_pipeline.py +0 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli/tests/utils/__init__.py +0 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli/tests/utils/test_api.py +0 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli/tests/utils/test_picker.py +0 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli/utils/accounts.py +0 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli/utils/api.py +0 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli/utils/constants.py +0 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli/utils/credentials.py +0 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli/utils/picker.py +0 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli/utils/pipeline_lookup.py +0 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli/utils/pipeline_selector.py +0 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli/utils/pipeline_update.py +0 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli/utils/styling.py +0 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli/utils/yaml_loader.py +0 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli.egg-info/SOURCES.txt +0 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli.egg-info/dependency_links.txt +0 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli.egg-info/entry_points.txt +0 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli.egg-info/requires.txt +0 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/orchestra_cli.egg-info/top_level.txt +0 -0
- {orchestra_cli-0.5.1 → orchestra_cli-0.5.2}/setup.cfg +0 -0
|
@@ -364,7 +364,8 @@ def migrate_pipeline(
|
|
|
364
364
|
typer.echo(red("Could not detect repository URL from git"))
|
|
365
365
|
raise typer.Exit(code=1)
|
|
366
366
|
|
|
367
|
-
|
|
367
|
+
remote_url = get_remote_url(repo_root)
|
|
368
|
+
storage_provider_value = detect_storage_provider(remote_url)
|
|
368
369
|
if not storage_provider_value:
|
|
369
370
|
typer.echo(red("Could not detect storage provider - no matching host"))
|
|
370
371
|
raise typer.Exit(code=1)
|
|
@@ -437,6 +438,7 @@ def migrate_pipeline(
|
|
|
437
438
|
repository_slug,
|
|
438
439
|
default_branch,
|
|
439
440
|
pushed_branch,
|
|
441
|
+
remote_url,
|
|
440
442
|
)
|
|
441
443
|
if compare_link:
|
|
442
444
|
typer.echo(yellow(f"Open PR / compare link: {compare_link}"))
|
|
@@ -36,6 +36,8 @@ def mock_env(monkeypatch):
|
|
|
36
36
|
[
|
|
37
37
|
("https://github.com/org/repo.git", "GITHUB", "org/repo"),
|
|
38
38
|
("git@github.com:org/repo.git", "GITHUB", "org/repo"),
|
|
39
|
+
("https://acme.ghe.com/org/repo.git", "GITHUB", "org/repo"),
|
|
40
|
+
("git@acme.ghe.com:org/repo.git", "GITHUB", "org/repo"),
|
|
39
41
|
("https://gitlab.com/org/repo.git", "GITLAB", "org/repo"),
|
|
40
42
|
("git@gitlab.com:org/repo.git", "GITLAB", "org/repo"),
|
|
41
43
|
("https://dev.azure.com/org/project/_git/repo", "AZURE_DEVOPS", "project/repo"),
|
|
@@ -114,3 +114,46 @@ def test_require_repo_root_walks_up_from_nonexistent_parent(monkeypatch, tmp_pat
|
|
|
114
114
|
monkeypatch.setattr(subprocess, "run", make_git_subprocess_mock(mapping))
|
|
115
115
|
|
|
116
116
|
assert git_module.require_repo_root(target_file, git_module.GitAction.MIGRATE) == tmp_path
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
@pytest.mark.parametrize(
|
|
120
|
+
"remote_url, expected",
|
|
121
|
+
[
|
|
122
|
+
("https://github.com/org/repo.git", "GITHUB"),
|
|
123
|
+
("git@github.com:org/repo.git", "GITHUB"),
|
|
124
|
+
("https://acme.ghe.com/org/repo.git", "GITHUB"),
|
|
125
|
+
("https://user:token@acme.ghe.com/org/repo.git", "GITHUB"),
|
|
126
|
+
("git@acme.ghe.com:org/repo.git", "GITHUB"),
|
|
127
|
+
("ssh://git@acme.ghe.com/org/repo.git", "GITHUB"),
|
|
128
|
+
("https://gitlab.com/org/repo.git", "GITLAB"),
|
|
129
|
+
("https://git.example.com/org/repo.git", None),
|
|
130
|
+
("https://example.com/ghe.com/repo.git", None),
|
|
131
|
+
("https://[malformed/org/repo.git", None),
|
|
132
|
+
(None, None),
|
|
133
|
+
],
|
|
134
|
+
)
|
|
135
|
+
def test_detect_storage_provider(remote_url: str | None, expected: str | None):
|
|
136
|
+
assert git_module.detect_storage_provider(remote_url) == expected
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
@pytest.mark.parametrize(
|
|
140
|
+
"remote_url, expected",
|
|
141
|
+
[
|
|
142
|
+
(
|
|
143
|
+
"git@github.com:org/repo.git",
|
|
144
|
+
"https://github.com/org/repo/compare/main...feature?expand=1",
|
|
145
|
+
),
|
|
146
|
+
(
|
|
147
|
+
"git@acme.ghe.com:org/repo.git",
|
|
148
|
+
"https://acme.ghe.com/org/repo/compare/main...feature?expand=1",
|
|
149
|
+
),
|
|
150
|
+
(
|
|
151
|
+
"https://user:token@acme.ghe.com/org/repo.git",
|
|
152
|
+
"https://acme.ghe.com/org/repo/compare/main...feature?expand=1",
|
|
153
|
+
),
|
|
154
|
+
(None, "https://github.com/org/repo/compare/main...feature?expand=1"),
|
|
155
|
+
],
|
|
156
|
+
)
|
|
157
|
+
def test_build_compare_link_github(remote_url: str | None, expected: str):
|
|
158
|
+
link = git_module.build_compare_link("GITHUB", "org/repo", "main", "feature", remote_url)
|
|
159
|
+
assert link == expected
|
|
@@ -4,11 +4,14 @@ import string
|
|
|
4
4
|
import subprocess
|
|
5
5
|
from enum import StrEnum
|
|
6
6
|
from pathlib import Path
|
|
7
|
+
from urllib.parse import urlsplit
|
|
7
8
|
|
|
8
9
|
import typer
|
|
9
10
|
|
|
10
11
|
from .styling import bold, red, yellow
|
|
11
12
|
|
|
13
|
+
GHE_COM_HOST_SUFFIX = ".ghe.com"
|
|
14
|
+
|
|
12
15
|
|
|
13
16
|
class GitAction(StrEnum):
|
|
14
17
|
BUILD = "Build"
|
|
@@ -84,12 +87,30 @@ def detect_current_branch(repo_root: Path, allow_detached: bool = True) -> str |
|
|
|
84
87
|
return out
|
|
85
88
|
|
|
86
89
|
|
|
90
|
+
def _remote_host(remote_url: str) -> str | None:
|
|
91
|
+
"""The host of a URL remote, or of the SSH shorthand ``[user@]host:path``."""
|
|
92
|
+
remote_url = remote_url.strip()
|
|
93
|
+
if "://" in remote_url:
|
|
94
|
+
try:
|
|
95
|
+
return urlsplit(remote_url).hostname
|
|
96
|
+
except ValueError:
|
|
97
|
+
return None
|
|
98
|
+
user_and_host, separator, _ = remote_url.partition(":")
|
|
99
|
+
return user_and_host.rpartition("@")[2].lower() if separator else None
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def _ghe_com_host(remote_url: str | None) -> str | None:
|
|
103
|
+
"""The remote's host if it's on GitHub Enterprise Cloud with data residency."""
|
|
104
|
+
host = _remote_host(remote_url) if remote_url else None
|
|
105
|
+
return host if host and host.endswith(GHE_COM_HOST_SUFFIX) else None
|
|
106
|
+
|
|
107
|
+
|
|
87
108
|
def detect_storage_provider(repository_url: str | None) -> str | None:
|
|
88
109
|
if not repository_url:
|
|
89
110
|
return None
|
|
90
111
|
|
|
91
112
|
url = repository_url.lower()
|
|
92
|
-
if "github.com" in url:
|
|
113
|
+
if "github.com" in url or _ghe_com_host(repository_url):
|
|
93
114
|
return "GITHUB"
|
|
94
115
|
if "gitlab.com" in url:
|
|
95
116
|
return "GITLAB"
|
|
@@ -103,10 +124,12 @@ def build_compare_link(
|
|
|
103
124
|
repository_slug: str,
|
|
104
125
|
default_branch: str,
|
|
105
126
|
branch_name: str,
|
|
127
|
+
remote_url: str | None,
|
|
106
128
|
) -> str | None:
|
|
107
129
|
provider = storage_provider.upper()
|
|
108
130
|
if provider == "GITHUB":
|
|
109
|
-
|
|
131
|
+
host = _ghe_com_host(remote_url) or "github.com"
|
|
132
|
+
return f"https://{host}/{repository_slug}/compare/{default_branch}...{branch_name}?expand=1"
|
|
110
133
|
if provider == "GITLAB":
|
|
111
134
|
return f"https://gitlab.com/{repository_slug}/-/compare/{default_branch}...{branch_name}"
|
|
112
135
|
return None
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|