airbyte-internal-ops 0.9.1__py3-none-any.whl → 0.10.0__py3-none-any.whl
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.
- {airbyte_internal_ops-0.9.1.dist-info → airbyte_internal_ops-0.10.0.dist-info}/METADATA +1 -1
- {airbyte_internal_ops-0.9.1.dist-info → airbyte_internal_ops-0.10.0.dist-info}/RECORD +13 -11
- airbyte_ops_mcp/airbyte_repo/progressive_rollout.py +279 -0
- airbyte_ops_mcp/cli/local.py +118 -0
- airbyte_ops_mcp/cloud_admin/api_client.py +336 -0
- airbyte_ops_mcp/cloud_admin/models.py +99 -0
- airbyte_ops_mcp/mcp/connector_rollout.py +779 -0
- airbyte_ops_mcp/mcp/prod_db_queries.py +227 -0
- airbyte_ops_mcp/mcp/server.py +2 -0
- airbyte_ops_mcp/prod_db_access/queries.py +144 -0
- airbyte_ops_mcp/prod_db_access/sql.py +298 -0
- {airbyte_internal_ops-0.9.1.dist-info → airbyte_internal_ops-0.10.0.dist-info}/WHEEL +0 -0
- {airbyte_internal_ops-0.9.1.dist-info → airbyte_internal_ops-0.10.0.dist-info}/entry_points.txt +0 -0
|
@@ -220,6 +220,7 @@ airbyte_ops_mcp/airbyte_repo/__init__.py,sha256=3yEpCOop1h33UuCtU7-1UB3kun2Qsxtg
|
|
|
220
220
|
airbyte_ops_mcp/airbyte_repo/bump_version.py,sha256=rtXYv105BhElj7twQmy20VjNsj6vCb0Ulrzmc4Z-1cE,15384
|
|
221
221
|
airbyte_ops_mcp/airbyte_repo/changelog_fix.py,sha256=sT94FkH5YuPc_NZCoMr9IUydcD4CO-i5ifGm8FOuI9g,13890
|
|
222
222
|
airbyte_ops_mcp/airbyte_repo/list_connectors.py,sha256=UI4RKMfFWOXHBtvh7TIw1v0BnV4rQQGuUgh8e9yvpos,19907
|
|
223
|
+
airbyte_ops_mcp/airbyte_repo/progressive_rollout.py,sha256=axBXWDCxfho5hOHIjbnQKWQNrDJR4kKuOdVQwJoqTTs,9459
|
|
223
224
|
airbyte_ops_mcp/airbyte_repo/utils.py,sha256=TXlOAfhiu_hVRNjCxB4PRPVDhTWCU5lYmgqz4QG_-EA,3201
|
|
224
225
|
airbyte_ops_mcp/cli/__init__.py,sha256=XpL7FyVfgabfBF2JR7u7NwJ2krlYqjd_OwLcWf-Xc7s,114
|
|
225
226
|
airbyte_ops_mcp/cli/_base.py,sha256=I8tWnyQf0ks4r3J8N8h-5GZxyn37T-55KsbuHnxYlcg,415
|
|
@@ -227,13 +228,13 @@ airbyte_ops_mcp/cli/_shared.py,sha256=jg-xMyGzTCGPqKd8VTfE_3kGPIyO_3Kx5sQbG4rPc0
|
|
|
227
228
|
airbyte_ops_mcp/cli/app.py,sha256=xxlyJzlFvZuy-qKAhTPPmzj-t0o7MSqQ7aPHonfT1vU,790
|
|
228
229
|
airbyte_ops_mcp/cli/cloud.py,sha256=jac0FcG3UvNNeNNhqZR04uY9BCyVvins1kjO0LRZ86Y,45861
|
|
229
230
|
airbyte_ops_mcp/cli/gh.py,sha256=koJPu0MDB6AW7mJq2z4dZV65ofvsZTkqoeitGF8KJR8,5364
|
|
230
|
-
airbyte_ops_mcp/cli/local.py,sha256=
|
|
231
|
+
airbyte_ops_mcp/cli/local.py,sha256=amxtJ7aY1nrOs36zuWkV7jZVMyHNLT7HDUvyyOXF8mM,44459
|
|
231
232
|
airbyte_ops_mcp/cli/registry.py,sha256=CVm15_6YWpLD99DZ8f8y68npXJw01Ckde7Ty3o89YNE,16631
|
|
232
233
|
airbyte_ops_mcp/cloud_admin/__init__.py,sha256=cqE96Q10Kp6elhH9DAi6TVsIwSUy3sooDLLrxTaktGk,816
|
|
233
|
-
airbyte_ops_mcp/cloud_admin/api_client.py,sha256=
|
|
234
|
+
airbyte_ops_mcp/cloud_admin/api_client.py,sha256=2DNYx-GXOTCuP9-rEkZFTM8MIR3MDnXSaqs_z1DsTwQ,70361
|
|
234
235
|
airbyte_ops_mcp/cloud_admin/auth.py,sha256=qE2Aqe0qbZB755KscL65s54Jz78-F-X5a8fXKsrYEOQ,3749
|
|
235
236
|
airbyte_ops_mcp/cloud_admin/connection_config.py,sha256=9opGQer-cGMJANmm-LFLMwvMCNu3nzxa2n2XHkZj9Fw,4899
|
|
236
|
-
airbyte_ops_mcp/cloud_admin/models.py,sha256=
|
|
237
|
+
airbyte_ops_mcp/cloud_admin/models.py,sha256=Wn6O48Yp2QB3jsknmw-mG-LJ6GdBIyAg06MGLC1kOjM,8299
|
|
237
238
|
airbyte_ops_mcp/connection_config_retriever/__init__.py,sha256=Xoi-YvARrNPhECdpwEDDkdwEpnvj8zuUlwULpf4iRrU,800
|
|
238
239
|
airbyte_ops_mcp/connection_config_retriever/audit_logging.py,sha256=QdOG9984NXeMaKeJnFUZ4oCOmqi37PBRG2NRBBjrZQQ,2753
|
|
239
240
|
airbyte_ops_mcp/connection_config_retriever/retrieval.py,sha256=s6yeCyrboWkUd6KdaheEo87x-rLtQNTL8XeR8O9z2HI,12160
|
|
@@ -268,21 +269,22 @@ airbyte_ops_mcp/mcp/_guidance.py,sha256=n0dLggQXNi2PKZ0eFDqQx5YIjhQpMnI3xcjouub9
|
|
|
268
269
|
airbyte_ops_mcp/mcp/cloud_connector_versions.py,sha256=dRKrgsRGadQieTSvBrc5HYI6TTDzVAT6-4tiOHNcDHU,36244
|
|
269
270
|
airbyte_ops_mcp/mcp/connector_analysis.py,sha256=OC4KrOSkMkKPkOisWnSv96BDDE5TQYHq-Jxa2vtjJpo,298
|
|
270
271
|
airbyte_ops_mcp/mcp/connector_qa.py,sha256=aImpqdnqBPDrz10BS0owsV4kuIU2XdalzgbaGZsbOL0,258
|
|
272
|
+
airbyte_ops_mcp/mcp/connector_rollout.py,sha256=KYQhRCcpJCquhX_aGNjhT9WKT5lqDpNKNA1Wki-7zPU,29020
|
|
271
273
|
airbyte_ops_mcp/mcp/gcp_logs.py,sha256=QCDQHmsxQHJ26BB0sxkBgKXr7Ja9wVFkdpY6423H-xo,2677
|
|
272
274
|
airbyte_ops_mcp/mcp/github_actions.py,sha256=G0NmjNVWpVtLXdQnhX7qJwPFkfEX5gBXf55xt0FpJJ0,11752
|
|
273
275
|
airbyte_ops_mcp/mcp/github_repo_ops.py,sha256=YHeuN7Xc_L3xkJ-F3l1t1TIPW2j2CjecBDbb0DUvZO8,5306
|
|
274
276
|
airbyte_ops_mcp/mcp/metadata.py,sha256=fwGW97WknR5lfKcQnFtK6dU87aA6TmLj1NkKyqDAV9g,270
|
|
275
277
|
airbyte_ops_mcp/mcp/prerelease.py,sha256=jSrAwk95vZLfwYFn5Menb-ziAMTUZnzAMHIJAitd9x8,9553
|
|
276
|
-
airbyte_ops_mcp/mcp/prod_db_queries.py,sha256=
|
|
278
|
+
airbyte_ops_mcp/mcp/prod_db_queries.py,sha256=iesP8H2hCmkdjsmLgYOrwqNQeQwbcScQc4tr4cfs8es,56334
|
|
277
279
|
airbyte_ops_mcp/mcp/prompts.py,sha256=v4bguskw7hSsISkseACzKQm5QwrIXmiwbs27oclXTE8,1591
|
|
278
280
|
airbyte_ops_mcp/mcp/registry.py,sha256=PW-VYUj42qx2pQ_apUkVaoUFq7VgB9zEU7-aGrkSCCw,290
|
|
279
281
|
airbyte_ops_mcp/mcp/regression_tests.py,sha256=zwdQ-ymUhWtVcIjwiNIZAC151GKhuxi55HDi4S91RnI,17046
|
|
280
|
-
airbyte_ops_mcp/mcp/server.py,sha256=
|
|
282
|
+
airbyte_ops_mcp/mcp/server.py,sha256=7VO-awh4gh51EiYCkUvEyQd4r1gl6XRJ4-I-JybkEiA,7405
|
|
281
283
|
airbyte_ops_mcp/prod_db_access/__init__.py,sha256=5pxouMPY1beyWlB0UwPnbaLTKTHqU6X82rbbgKY2vYU,1069
|
|
282
284
|
airbyte_ops_mcp/prod_db_access/db_engine.py,sha256=VUqEWZtharJUR-Cri_pMwtGh1C4Neu4s195mbEXlm-w,9190
|
|
283
285
|
airbyte_ops_mcp/prod_db_access/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
284
|
-
airbyte_ops_mcp/prod_db_access/queries.py,sha256=
|
|
285
|
-
airbyte_ops_mcp/prod_db_access/sql.py,sha256=
|
|
286
|
+
airbyte_ops_mcp/prod_db_access/queries.py,sha256=OMnIejwVoQSaTV1It1btzui6Zmrvihh3d6KNZgyyE7I,27741
|
|
287
|
+
airbyte_ops_mcp/prod_db_access/sql.py,sha256=J89eGlrG_0NPtpAuVVKTBS9tG3LKGj0DK-zTGUEzvFA,49526
|
|
286
288
|
airbyte_ops_mcp/registry/__init__.py,sha256=iEaPlt9GrnlaLbc__98TguNeZG8wuQu7S-_2QkhHcbA,858
|
|
287
289
|
airbyte_ops_mcp/registry/_gcs_util.py,sha256=3dL7iqpyoSPfl2nGBPp73TqrqGWI4Ks6egKpQXDnw24,2838
|
|
288
290
|
airbyte_ops_mcp/registry/connector_stubs.py,sha256=pBzaQIOgCfBvHuy3_N45amU9Do2ALDpU8q5HnZySPTQ,5807
|
|
@@ -308,7 +310,7 @@ airbyte_ops_mcp/regression_tests/regression/comparators.py,sha256=MJkLZEKHivgrG0
|
|
|
308
310
|
airbyte_ops_mcp/regression_tests/validation/__init__.py,sha256=MBEwGOoNuqT4_oCahtoK62OKWIjUCfWa7vZTxNj_0Ek,1532
|
|
309
311
|
airbyte_ops_mcp/regression_tests/validation/catalog_validators.py,sha256=jqqVAMOk0mtdPgwu4d0hA0ZEjtsNh5gapvGydRv3_qk,12553
|
|
310
312
|
airbyte_ops_mcp/regression_tests/validation/record_validators.py,sha256=RjauAhKWNwxMBTu0eNS2hMFNQVs5CLbQU51kp6FOVDk,7432
|
|
311
|
-
airbyte_internal_ops-0.
|
|
312
|
-
airbyte_internal_ops-0.
|
|
313
|
-
airbyte_internal_ops-0.
|
|
314
|
-
airbyte_internal_ops-0.
|
|
313
|
+
airbyte_internal_ops-0.10.0.dist-info/METADATA,sha256=eP4lUCpuijAH7aJIkDW4n3mZOIoMqq8nvkF3IU5EqyM,6002
|
|
314
|
+
airbyte_internal_ops-0.10.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
315
|
+
airbyte_internal_ops-0.10.0.dist-info/entry_points.txt,sha256=WxP0l7bRFss4Cr5uQqVj9mTEKwnRKouNuphXQF0lotA,171
|
|
316
|
+
airbyte_internal_ops-0.10.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
# Copyright (c) 2025 Airbyte, Inc., all rights reserved.
|
|
2
|
+
"""Progressive rollout setup utilities for Airbyte connectors.
|
|
3
|
+
|
|
4
|
+
This module provides pure Python functionality to configure a connector's
|
|
5
|
+
metadata.yaml for progressive rollout of a release candidate (RC) version.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from dataclasses import dataclass
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
|
|
13
|
+
import semver
|
|
14
|
+
import yaml
|
|
15
|
+
|
|
16
|
+
from airbyte_ops_mcp.airbyte_repo.bump_version import (
|
|
17
|
+
InvalidVersionError,
|
|
18
|
+
get_connector_path,
|
|
19
|
+
get_current_version,
|
|
20
|
+
)
|
|
21
|
+
from airbyte_ops_mcp.airbyte_repo.list_connectors import METADATA_FILE_NAME
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@dataclass
|
|
25
|
+
class ProgressiveRolloutSetupResult:
|
|
26
|
+
"""Result of a progressive rollout setup operation."""
|
|
27
|
+
|
|
28
|
+
connector: str
|
|
29
|
+
previous_version: str
|
|
30
|
+
rc_version: str
|
|
31
|
+
pin_version: str
|
|
32
|
+
files_modified: list[str]
|
|
33
|
+
dry_run: bool
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@dataclass
|
|
37
|
+
class ProgressiveRolloutCleanupResult:
|
|
38
|
+
"""Result of a progressive rollout cleanup operation."""
|
|
39
|
+
|
|
40
|
+
connector: str
|
|
41
|
+
previous_version: str
|
|
42
|
+
new_version: str
|
|
43
|
+
files_modified: list[str]
|
|
44
|
+
dry_run: bool
|
|
45
|
+
changes_made: list[str]
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def calculate_rc_version(
|
|
49
|
+
current_version: str,
|
|
50
|
+
rc_version: str | None = None,
|
|
51
|
+
) -> str:
|
|
52
|
+
"""Calculate the RC version for progressive rollout.
|
|
53
|
+
|
|
54
|
+
If rc_version is provided, validates and returns it.
|
|
55
|
+
Otherwise, bumps the minor version and adds -rc.1 suffix.
|
|
56
|
+
|
|
57
|
+
Args:
|
|
58
|
+
current_version: Current version string (e.g., "0.0.46")
|
|
59
|
+
rc_version: Explicit RC version (e.g., "0.1.0-rc.1")
|
|
60
|
+
|
|
61
|
+
Returns:
|
|
62
|
+
RC version string
|
|
63
|
+
|
|
64
|
+
Raises:
|
|
65
|
+
InvalidVersionError: If version format is invalid
|
|
66
|
+
"""
|
|
67
|
+
if rc_version is not None:
|
|
68
|
+
if not rc_version.endswith("-rc.1") and "-rc." not in rc_version:
|
|
69
|
+
raise InvalidVersionError(
|
|
70
|
+
f"RC version must contain '-rc.' suffix, got: {rc_version}"
|
|
71
|
+
)
|
|
72
|
+
return rc_version
|
|
73
|
+
|
|
74
|
+
try:
|
|
75
|
+
version = semver.Version.parse(current_version)
|
|
76
|
+
except ValueError as e:
|
|
77
|
+
raise InvalidVersionError(
|
|
78
|
+
f"Cannot parse current version: {current_version}"
|
|
79
|
+
) from e
|
|
80
|
+
|
|
81
|
+
bumped = version.bump_minor()
|
|
82
|
+
return f"{bumped}-rc.1"
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def setup_progressive_rollout(
|
|
86
|
+
repo_path: str | Path,
|
|
87
|
+
connector_name: str,
|
|
88
|
+
rc_version: str | None = None,
|
|
89
|
+
pin_version: str | None = None,
|
|
90
|
+
dry_run: bool = False,
|
|
91
|
+
) -> ProgressiveRolloutSetupResult:
|
|
92
|
+
"""Configure a connector's metadata.yaml for progressive rollout.
|
|
93
|
+
|
|
94
|
+
This function modifies metadata.yaml to:
|
|
95
|
+
1. Set dockerImageTag to the RC version
|
|
96
|
+
2. Add registryOverrides.cloud.dockerImageTag to pin Cloud users to current version
|
|
97
|
+
3. Add registryOverrides.oss.dockerImageTag to pin OSS users to current version
|
|
98
|
+
4. Add releases.rolloutConfiguration.enableProgressiveRollout: true
|
|
99
|
+
|
|
100
|
+
Args:
|
|
101
|
+
repo_path: Path to the Airbyte monorepo
|
|
102
|
+
connector_name: Technical name of the connector (e.g., "source-github")
|
|
103
|
+
rc_version: Explicit RC version (default: bumps minor and adds -rc.1)
|
|
104
|
+
pin_version: Version to pin Cloud/OSS users to (default: current version)
|
|
105
|
+
dry_run: If True, don't actually modify files
|
|
106
|
+
|
|
107
|
+
Returns:
|
|
108
|
+
ProgressiveRolloutSetupResult with details of the operation
|
|
109
|
+
|
|
110
|
+
Raises:
|
|
111
|
+
ConnectorNotFoundError: If connector doesn't exist
|
|
112
|
+
VersionNotFoundError: If current version cannot be found
|
|
113
|
+
InvalidVersionError: If version format is invalid
|
|
114
|
+
"""
|
|
115
|
+
repo_path = Path(repo_path)
|
|
116
|
+
connector_path = get_connector_path(repo_path, connector_name)
|
|
117
|
+
metadata_file = connector_path / METADATA_FILE_NAME
|
|
118
|
+
|
|
119
|
+
current_version = get_current_version(connector_path)
|
|
120
|
+
calculated_rc_version = calculate_rc_version(current_version, rc_version)
|
|
121
|
+
calculated_pin_version = pin_version if pin_version else current_version
|
|
122
|
+
|
|
123
|
+
with open(metadata_file) as f:
|
|
124
|
+
metadata = yaml.safe_load(f)
|
|
125
|
+
|
|
126
|
+
data = metadata.get("data", {})
|
|
127
|
+
|
|
128
|
+
data["dockerImageTag"] = calculated_rc_version
|
|
129
|
+
|
|
130
|
+
if "registryOverrides" not in data:
|
|
131
|
+
data["registryOverrides"] = {}
|
|
132
|
+
|
|
133
|
+
if "cloud" not in data["registryOverrides"]:
|
|
134
|
+
data["registryOverrides"]["cloud"] = {}
|
|
135
|
+
data["registryOverrides"]["cloud"]["dockerImageTag"] = calculated_pin_version
|
|
136
|
+
|
|
137
|
+
if "oss" not in data["registryOverrides"]:
|
|
138
|
+
data["registryOverrides"]["oss"] = {}
|
|
139
|
+
data["registryOverrides"]["oss"]["dockerImageTag"] = calculated_pin_version
|
|
140
|
+
|
|
141
|
+
if "releases" not in data:
|
|
142
|
+
data["releases"] = {}
|
|
143
|
+
if "rolloutConfiguration" not in data["releases"]:
|
|
144
|
+
data["releases"]["rolloutConfiguration"] = {}
|
|
145
|
+
data["releases"]["rolloutConfiguration"]["enableProgressiveRollout"] = True
|
|
146
|
+
|
|
147
|
+
metadata["data"] = data
|
|
148
|
+
|
|
149
|
+
files_modified: list[str] = []
|
|
150
|
+
|
|
151
|
+
if not dry_run:
|
|
152
|
+
with open(metadata_file, "w") as f:
|
|
153
|
+
yaml.dump(metadata, f, default_flow_style=False, sort_keys=False)
|
|
154
|
+
files_modified.append(str(metadata_file.relative_to(repo_path)))
|
|
155
|
+
else:
|
|
156
|
+
files_modified.append(str(metadata_file.relative_to(repo_path)))
|
|
157
|
+
|
|
158
|
+
return ProgressiveRolloutSetupResult(
|
|
159
|
+
connector=connector_name,
|
|
160
|
+
previous_version=current_version,
|
|
161
|
+
rc_version=calculated_rc_version,
|
|
162
|
+
pin_version=calculated_pin_version,
|
|
163
|
+
files_modified=files_modified,
|
|
164
|
+
dry_run=dry_run,
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
def extract_ga_version(rc_version: str) -> str:
|
|
169
|
+
"""Extract the GA version from an RC version string.
|
|
170
|
+
|
|
171
|
+
Args:
|
|
172
|
+
rc_version: RC version string (e.g., "1.0.0-rc.1")
|
|
173
|
+
|
|
174
|
+
Returns:
|
|
175
|
+
GA version string (e.g., "1.0.0")
|
|
176
|
+
|
|
177
|
+
Raises:
|
|
178
|
+
InvalidVersionError: If version format is invalid
|
|
179
|
+
"""
|
|
180
|
+
if "-rc." in rc_version:
|
|
181
|
+
return rc_version.split("-rc.")[0]
|
|
182
|
+
if "-preview." in rc_version:
|
|
183
|
+
return rc_version.split("-preview.")[0]
|
|
184
|
+
return rc_version
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
def cleanup_progressive_rollout(
|
|
188
|
+
repo_path: str | Path,
|
|
189
|
+
connector_name: str,
|
|
190
|
+
ga_version: str | None = None,
|
|
191
|
+
dry_run: bool = False,
|
|
192
|
+
) -> ProgressiveRolloutCleanupResult:
|
|
193
|
+
"""Clean up a connector's metadata.yaml after progressive rollout completion.
|
|
194
|
+
|
|
195
|
+
This function reverses the changes made by setup_progressive_rollout:
|
|
196
|
+
1. Updates dockerImageTag to the GA version (removes -rc.X suffix)
|
|
197
|
+
2. Removes registryOverrides.cloud.dockerImageTag (if it was a pin)
|
|
198
|
+
3. Removes registryOverrides.oss.dockerImageTag (if it was a pin)
|
|
199
|
+
4. Sets releases.rolloutConfiguration.enableProgressiveRollout to false
|
|
200
|
+
|
|
201
|
+
Args:
|
|
202
|
+
repo_path: Path to the Airbyte monorepo
|
|
203
|
+
connector_name: Technical name of the connector (e.g., "source-github")
|
|
204
|
+
ga_version: Explicit GA version (default: extracts from current RC version)
|
|
205
|
+
dry_run: If True, don't actually modify files
|
|
206
|
+
|
|
207
|
+
Returns:
|
|
208
|
+
ProgressiveRolloutCleanupResult with details of the operation
|
|
209
|
+
|
|
210
|
+
Raises:
|
|
211
|
+
ConnectorNotFoundError: If connector doesn't exist
|
|
212
|
+
VersionNotFoundError: If current version cannot be found
|
|
213
|
+
InvalidVersionError: If version format is invalid
|
|
214
|
+
"""
|
|
215
|
+
repo_path = Path(repo_path)
|
|
216
|
+
connector_path = get_connector_path(repo_path, connector_name)
|
|
217
|
+
metadata_file = connector_path / METADATA_FILE_NAME
|
|
218
|
+
|
|
219
|
+
current_version = get_current_version(connector_path)
|
|
220
|
+
|
|
221
|
+
new_version = ga_version or extract_ga_version(current_version)
|
|
222
|
+
|
|
223
|
+
with open(metadata_file) as f:
|
|
224
|
+
metadata = yaml.safe_load(f)
|
|
225
|
+
|
|
226
|
+
data = metadata.get("data", {})
|
|
227
|
+
changes_made: list[str] = []
|
|
228
|
+
|
|
229
|
+
if data.get("dockerImageTag") != new_version:
|
|
230
|
+
data["dockerImageTag"] = new_version
|
|
231
|
+
changes_made.append(f"Updated dockerImageTag to {new_version}")
|
|
232
|
+
|
|
233
|
+
registry_overrides = data.get("registryOverrides", {})
|
|
234
|
+
cloud_overrides = registry_overrides.get("cloud", {})
|
|
235
|
+
oss_overrides = registry_overrides.get("oss", {})
|
|
236
|
+
|
|
237
|
+
if "dockerImageTag" in cloud_overrides:
|
|
238
|
+
del cloud_overrides["dockerImageTag"]
|
|
239
|
+
changes_made.append("Removed registryOverrides.cloud.dockerImageTag")
|
|
240
|
+
if not cloud_overrides:
|
|
241
|
+
del registry_overrides["cloud"]
|
|
242
|
+
changes_made.append("Removed empty registryOverrides.cloud section")
|
|
243
|
+
|
|
244
|
+
if "dockerImageTag" in oss_overrides:
|
|
245
|
+
del oss_overrides["dockerImageTag"]
|
|
246
|
+
changes_made.append("Removed registryOverrides.oss.dockerImageTag")
|
|
247
|
+
if not oss_overrides:
|
|
248
|
+
del registry_overrides["oss"]
|
|
249
|
+
changes_made.append("Removed empty registryOverrides.oss section")
|
|
250
|
+
|
|
251
|
+
if not registry_overrides and "registryOverrides" in data:
|
|
252
|
+
del data["registryOverrides"]
|
|
253
|
+
changes_made.append("Removed empty registryOverrides section")
|
|
254
|
+
|
|
255
|
+
releases = data.get("releases", {})
|
|
256
|
+
rollout_config = releases.get("rolloutConfiguration", {})
|
|
257
|
+
if rollout_config.get("enableProgressiveRollout"):
|
|
258
|
+
rollout_config["enableProgressiveRollout"] = False
|
|
259
|
+
changes_made.append("Set enableProgressiveRollout to false")
|
|
260
|
+
|
|
261
|
+
metadata["data"] = data
|
|
262
|
+
|
|
263
|
+
files_modified: list[str] = []
|
|
264
|
+
|
|
265
|
+
if not dry_run:
|
|
266
|
+
with open(metadata_file, "w") as f:
|
|
267
|
+
yaml.dump(metadata, f, default_flow_style=False, sort_keys=False)
|
|
268
|
+
files_modified.append(str(metadata_file.relative_to(repo_path)))
|
|
269
|
+
else:
|
|
270
|
+
files_modified.append(str(metadata_file.relative_to(repo_path)))
|
|
271
|
+
|
|
272
|
+
return ProgressiveRolloutCleanupResult(
|
|
273
|
+
connector=connector_name,
|
|
274
|
+
previous_version=current_version,
|
|
275
|
+
new_version=new_version,
|
|
276
|
+
files_modified=files_modified,
|
|
277
|
+
dry_run=dry_run,
|
|
278
|
+
changes_made=changes_made,
|
|
279
|
+
)
|
airbyte_ops_mcp/cli/local.py
CHANGED
|
@@ -44,6 +44,10 @@ from airbyte_ops_mcp.airbyte_repo.list_connectors import (
|
|
|
44
44
|
_detect_connector_language,
|
|
45
45
|
get_connectors_with_local_cdk,
|
|
46
46
|
)
|
|
47
|
+
from airbyte_ops_mcp.airbyte_repo.progressive_rollout import (
|
|
48
|
+
cleanup_progressive_rollout,
|
|
49
|
+
setup_progressive_rollout,
|
|
50
|
+
)
|
|
47
51
|
from airbyte_ops_mcp.cli._base import app
|
|
48
52
|
from airbyte_ops_mcp.cli._shared import error_console, exit_with_error, print_json
|
|
49
53
|
from airbyte_ops_mcp.connector_ops.utils import Connector
|
|
@@ -1187,3 +1191,117 @@ def enterprise_stub_sync(
|
|
|
1187
1191
|
print_json(
|
|
1188
1192
|
synced_stubs if all_connectors else synced_stubs[0] if synced_stubs else {}
|
|
1189
1193
|
)
|
|
1194
|
+
|
|
1195
|
+
|
|
1196
|
+
@connector_app.command(name="setup-progressive-rollout")
|
|
1197
|
+
def setup_progressive_rollout_cmd(
|
|
1198
|
+
name: Annotated[
|
|
1199
|
+
str,
|
|
1200
|
+
Parameter(help="Connector technical name (e.g., source-github)."),
|
|
1201
|
+
],
|
|
1202
|
+
repo_path: Annotated[
|
|
1203
|
+
str,
|
|
1204
|
+
Parameter(help="Absolute path to the Airbyte monorepo."),
|
|
1205
|
+
],
|
|
1206
|
+
rc_version: Annotated[
|
|
1207
|
+
str | None,
|
|
1208
|
+
Parameter(
|
|
1209
|
+
help="Explicit RC version (e.g., 1.0.0-rc.1). Default: bumps minor and adds -rc.1."
|
|
1210
|
+
),
|
|
1211
|
+
] = None,
|
|
1212
|
+
pin_version: Annotated[
|
|
1213
|
+
str | None,
|
|
1214
|
+
Parameter(help="Version to pin Cloud/OSS users to. Default: current version."),
|
|
1215
|
+
] = None,
|
|
1216
|
+
dry_run: Annotated[
|
|
1217
|
+
bool,
|
|
1218
|
+
Parameter(help="Show what would be changed without modifying files."),
|
|
1219
|
+
] = False,
|
|
1220
|
+
) -> None:
|
|
1221
|
+
"""Configure a connector's metadata.yaml for progressive rollout.
|
|
1222
|
+
|
|
1223
|
+
Sets up the connector for progressive rollout by:
|
|
1224
|
+
- Setting dockerImageTag to the RC version
|
|
1225
|
+
- Adding registryOverrides to pin Cloud/OSS users to current stable version
|
|
1226
|
+
- Enabling releases.rolloutConfiguration.enableProgressiveRollout
|
|
1227
|
+
"""
|
|
1228
|
+
result = setup_progressive_rollout(
|
|
1229
|
+
repo_path=repo_path,
|
|
1230
|
+
connector_name=name,
|
|
1231
|
+
rc_version=rc_version,
|
|
1232
|
+
pin_version=pin_version,
|
|
1233
|
+
dry_run=dry_run,
|
|
1234
|
+
)
|
|
1235
|
+
|
|
1236
|
+
output = {
|
|
1237
|
+
"connector": result.connector,
|
|
1238
|
+
"previous_version": result.previous_version,
|
|
1239
|
+
"rc_version": result.rc_version,
|
|
1240
|
+
"pin_version": result.pin_version,
|
|
1241
|
+
"files_modified": result.files_modified,
|
|
1242
|
+
"dry_run": result.dry_run,
|
|
1243
|
+
}
|
|
1244
|
+
print_json(output)
|
|
1245
|
+
|
|
1246
|
+
_write_github_step_outputs(
|
|
1247
|
+
{
|
|
1248
|
+
"connector": result.connector,
|
|
1249
|
+
"previous_version": result.previous_version,
|
|
1250
|
+
"rc_version": result.rc_version,
|
|
1251
|
+
}
|
|
1252
|
+
)
|
|
1253
|
+
|
|
1254
|
+
|
|
1255
|
+
@connector_app.command(name="cleanup-progressive-rollout")
|
|
1256
|
+
def cleanup_progressive_rollout_cmd(
|
|
1257
|
+
name: Annotated[
|
|
1258
|
+
str,
|
|
1259
|
+
Parameter(help="Connector technical name (e.g., source-github)."),
|
|
1260
|
+
],
|
|
1261
|
+
repo_path: Annotated[
|
|
1262
|
+
str,
|
|
1263
|
+
Parameter(help="Absolute path to the Airbyte monorepo."),
|
|
1264
|
+
],
|
|
1265
|
+
ga_version: Annotated[
|
|
1266
|
+
str | None,
|
|
1267
|
+
Parameter(
|
|
1268
|
+
help="Explicit GA version. Default: extracts from current RC version."
|
|
1269
|
+
),
|
|
1270
|
+
] = None,
|
|
1271
|
+
dry_run: Annotated[
|
|
1272
|
+
bool,
|
|
1273
|
+
Parameter(help="Show what would be changed without modifying files."),
|
|
1274
|
+
] = False,
|
|
1275
|
+
) -> None:
|
|
1276
|
+
"""Clean up a connector's metadata.yaml after progressive rollout completion.
|
|
1277
|
+
|
|
1278
|
+
Reverses the changes made by setup-progressive-rollout:
|
|
1279
|
+
- Updates dockerImageTag to the GA version (removes -rc.X suffix)
|
|
1280
|
+
- Removes registryOverrides.cloud.dockerImageTag
|
|
1281
|
+
- Removes registryOverrides.oss.dockerImageTag
|
|
1282
|
+
- Sets enableProgressiveRollout to false
|
|
1283
|
+
"""
|
|
1284
|
+
result = cleanup_progressive_rollout(
|
|
1285
|
+
repo_path=repo_path,
|
|
1286
|
+
connector_name=name,
|
|
1287
|
+
ga_version=ga_version,
|
|
1288
|
+
dry_run=dry_run,
|
|
1289
|
+
)
|
|
1290
|
+
|
|
1291
|
+
output = {
|
|
1292
|
+
"connector": result.connector,
|
|
1293
|
+
"previous_version": result.previous_version,
|
|
1294
|
+
"new_version": result.new_version,
|
|
1295
|
+
"files_modified": result.files_modified,
|
|
1296
|
+
"changes_made": result.changes_made,
|
|
1297
|
+
"dry_run": result.dry_run,
|
|
1298
|
+
}
|
|
1299
|
+
print_json(output)
|
|
1300
|
+
|
|
1301
|
+
_write_github_step_outputs(
|
|
1302
|
+
{
|
|
1303
|
+
"connector": result.connector,
|
|
1304
|
+
"previous_version": result.previous_version,
|
|
1305
|
+
"new_version": result.new_version,
|
|
1306
|
+
}
|
|
1307
|
+
)
|