15
15
16
16
import github
17
17
import github3
18
+ import github3 .repos
18
19
import networkx as nx
19
20
import tqdm
20
21
from conda .models .version import VersionOrder
29
30
from conda_forge_tick .deploy import deploy
30
31
from conda_forge_tick .feedstock_parser import BOOTSTRAP_MAPPINGS
31
32
from conda_forge_tick .git_utils import (
33
+ DryRunBackend ,
34
+ GitPlatformBackend ,
35
+ RepositoryNotFoundError ,
32
36
comment_on_pr ,
33
- get_repo ,
37
+ github3_client ,
34
38
github_backend ,
35
39
is_github_api_limit_reached ,
36
40
push_repo ,
@@ -140,9 +144,55 @@ def _get_pre_pr_migrator_attempts(attrs, migrator_name, *, is_version):
140
144
return pri .get ("pre_pr_migrator_attempts" , {}).get (migrator_name , 0 )
141
145
142
146
147
+ def _prepare_feedstock_repository (
148
+ backend : GitPlatformBackend ,
149
+ context : ClonedFeedstockContext ,
150
+ branch : str ,
151
+ base_branch : str ,
152
+ ) -> bool :
153
+ """
154
+ Prepare a feedstock repository for migration by forking and cloning it. The local clone will be present in
155
+ context.local_clone_dir.
156
+
157
+ Any errors are written to the pr_info attribute of the feedstock context and logged.
158
+
159
+ :param backend: The GitPlatformBackend instance to use.
160
+ :param context: The current context
161
+ :param branch: The branch to create in the forked repository.
162
+ :param base_branch: The base branch to branch from.
163
+ :return: True if the repository was successfully prepared, False otherwise.
164
+ """
165
+ try :
166
+ backend .fork (context .git_repo_owner , context .git_repo_name )
167
+ except RepositoryNotFoundError :
168
+ logger .warning (
169
+ f"Could not fork { context .git_repo_owner } /{ context .git_repo_name } : Not Found"
170
+ )
171
+
172
+ error_message = f"{ context .feedstock_name } : Git repository not found."
173
+ logger .critical (
174
+ f"Failed to migrate { context .feedstock_name } , { error_message } " ,
175
+ )
176
+
177
+ with context .attrs ["pr_info" ] as pri :
178
+ pri ["bad" ] = error_message
179
+
180
+ return False
181
+
182
+ backend .clone_fork_and_branch (
183
+ upstream_owner = context .git_repo_owner ,
184
+ repo_name = context .git_repo_name ,
185
+ target_dir = context .local_clone_dir ,
186
+ new_branch = branch ,
187
+ base_branch = base_branch ,
188
+ )
189
+ return True
190
+
191
+
143
192
def run_with_tmpdir (
144
193
context : FeedstockContext ,
145
194
migrator : Migrator ,
195
+ git_backend : GitPlatformBackend ,
146
196
rerender : bool = True ,
147
197
base_branch : str = "main" ,
148
198
dry_run : bool = False ,
@@ -161,6 +211,7 @@ def run_with_tmpdir(
161
211
return run (
162
212
context = cloned_context ,
163
213
migrator = migrator ,
214
+ git_backend = git_backend ,
164
215
rerender = rerender ,
165
216
base_branch = base_branch ,
166
217
dry_run = dry_run ,
@@ -171,6 +222,7 @@ def run_with_tmpdir(
171
222
def run (
172
223
context : ClonedFeedstockContext ,
173
224
migrator : Migrator ,
225
+ git_backend : GitPlatformBackend ,
174
226
rerender : bool = True ,
175
227
base_branch : str = "main" ,
176
228
dry_run : bool = False ,
@@ -184,6 +236,8 @@ def run(
184
236
The current feedstock context, already containing information about a temporary directory for the feedstock.
185
237
migrator: Migrator instance
186
238
The migrator to run on the feedstock
239
+ git_backend: GitPlatformBackend
240
+ The git backend to use. Use the DryRunBackend for testing.
187
241
rerender : bool
188
242
Whether to rerender
189
243
base_branch : str, optional
@@ -202,9 +256,6 @@ def run(
202
256
# sometimes we get weird directory issues so make sure we reset
203
257
os .chdir (BOT_HOME_DIR )
204
258
205
- # get the repo
206
- branch_name = migrator .remote_branch (context ) + "_h" + uuid4 ().hex [0 :6 ]
207
-
208
259
migrator_name = get_migrator_name (migrator )
209
260
is_version_migration = isinstance (migrator , Version )
210
261
_increment_pre_pr_migrator_attempt (
@@ -213,20 +264,25 @@ def run(
213
264
is_version = is_version_migration ,
214
265
)
215
266
216
- # TODO: run this in parallel
217
- repo = get_repo (context = context , branch = branch_name , base_branch = base_branch )
218
-
219
- feedstock_dir = str (context .local_clone_dir )
220
- if not feedstock_dir or not repo :
221
- logger .critical (
222
- "Failed to migrate %s, %s" ,
223
- context .feedstock_name ,
224
- context .attrs .get ("pr_info" , {}).get ("bad" ),
225
- )
267
+ branch_name = migrator .remote_branch (context ) + "_h" + uuid4 ().hex [0 :6 ]
268
+ if not _prepare_feedstock_repository (
269
+ git_backend ,
270
+ context ,
271
+ branch_name ,
272
+ base_branch ,
273
+ ):
274
+ # something went wrong during forking or cloning
226
275
return False , False
227
276
228
277
# need to use an absolute path here
229
- feedstock_dir = os .path .abspath (feedstock_dir )
278
+ feedstock_dir = str (context .local_clone_dir .resolve ())
279
+
280
+ # This is needed because we want to migrate to the new backend step-by-step
281
+ repo : github3 .repos .Repository | None = github3_client ().repository (
282
+ context .git_repo_owner , context .git_repo_name
283
+ )
284
+
285
+ assert repo is not None
230
286
231
287
migration_run_data = run_migration (
232
288
migrator = migrator ,
@@ -566,7 +622,8 @@ def _run_migrator_on_feedstock_branch(
566
622
attrs ,
567
623
base_branch ,
568
624
migrator ,
569
- fctx ,
625
+ fctx : FeedstockContext ,
626
+ git_backend : GitPlatformBackend ,
570
627
dry_run ,
571
628
mctx ,
572
629
migrator_name ,
@@ -581,6 +638,7 @@ def _run_migrator_on_feedstock_branch(
581
638
migrator_uid , pr_json = run_with_tmpdir (
582
639
context = fctx ,
583
640
migrator = migrator ,
641
+ git_backend = git_backend ,
584
642
rerender = migrator .rerender ,
585
643
hash_type = attrs .get ("hash_type" , "sha256" ),
586
644
base_branch = base_branch ,
@@ -745,7 +803,9 @@ def _is_migrator_done(_mg_start, good_prs, time_per, pr_limit):
745
803
return False
746
804
747
805
748
- def _run_migrator (migrator , mctx , temp , time_per , dry_run ):
806
+ def _run_migrator (
807
+ migrator , mctx , temp , time_per , dry_run , git_backend : GitPlatformBackend
808
+ ):
749
809
_mg_start = time .time ()
750
810
751
811
migrator_name = get_migrator_name (migrator )
@@ -863,14 +923,15 @@ def _run_migrator(migrator, mctx, temp, time_per, dry_run):
863
923
)
864
924
):
865
925
good_prs , break_loop = _run_migrator_on_feedstock_branch (
866
- attrs ,
867
- base_branch ,
868
- migrator ,
869
- fctx ,
870
- dry_run ,
871
- mctx ,
872
- migrator_name ,
873
- good_prs ,
926
+ attrs = attrs ,
927
+ base_branch = base_branch ,
928
+ migrator = migrator ,
929
+ fctx = fctx ,
930
+ git_backend = git_backend ,
931
+ dry_run = dry_run ,
932
+ mctx = mctx ,
933
+ migrator_name = migrator_name ,
934
+ good_prs = good_prs ,
874
935
)
875
936
if break_loop :
876
937
break
@@ -1119,14 +1180,11 @@ def main(ctx: CliContext) -> None:
1119
1180
),
1120
1181
flush = True ,
1121
1182
)
1183
+ git_backend = github_backend () if not ctx .dry_run else DryRunBackend ()
1122
1184
1123
1185
for mg_ind , migrator in enumerate (migrators ):
1124
1186
good_prs = _run_migrator (
1125
- migrator ,
1126
- mctx ,
1127
- temp ,
1128
- time_per_migrator [mg_ind ],
1129
- ctx .dry_run ,
1187
+ migrator , mctx , temp , time_per_migrator [mg_ind ], ctx .dry_run , git_backend
1130
1188
)
1131
1189
if good_prs > 0 :
1132
1190
pass
0 commit comments