9
9
import traceback
10
10
import typing
11
11
from dataclasses import dataclass
12
- from typing import Literal , cast
12
+ from typing import Literal , MutableMapping , cast
13
13
from urllib .error import URLError
14
14
from uuid import uuid4
15
15
31
31
from conda_forge_tick .feedstock_parser import BOOTSTRAP_MAPPINGS
32
32
from conda_forge_tick .git_utils import (
33
33
DryRunBackend ,
34
- DuplicatePullRequestError ,
35
34
GitCli ,
36
35
GitCliError ,
37
36
GitPlatformBackend ,
38
37
RepositoryNotFoundError ,
38
+ comment_on_pr ,
39
+ github3_client ,
39
40
github_backend ,
40
41
is_github_api_limit_reached ,
42
+ push_repo ,
41
43
)
42
44
from conda_forge_tick .lazy_json_backends import (
43
45
LazyJson ,
70
72
)
71
73
72
74
from .migrators_types import MigrationUidTypedDict
73
- from .models .pr_json import PullRequestData , PullRequestInfoSpecial , PullRequestState
74
75
75
76
logger = logging .getLogger (__name__ )
76
77
@@ -422,20 +423,13 @@ def _check_and_process_solvability(
422
423
return False
423
424
424
425
425
- def get_spoofed_closed_pr_info () -> PullRequestInfoSpecial :
426
- return PullRequestInfoSpecial (
427
- id = str (uuid4 ()),
428
- merged_at = "never issued" ,
429
- state = "closed" ,
430
- )
431
-
432
-
433
426
def run_with_tmpdir (
434
427
context : FeedstockContext ,
435
428
migrator : Migrator ,
436
429
git_backend : GitPlatformBackend ,
437
430
rerender : bool = True ,
438
431
base_branch : str = "main" ,
432
+ dry_run : bool = False ,
439
433
** kwargs : typing .Any ,
440
434
) -> tuple [MigrationUidTypedDict , dict ] | tuple [Literal [False ], Literal [False ]]:
441
435
"""
@@ -454,6 +448,7 @@ def run_with_tmpdir(
454
448
git_backend = git_backend ,
455
449
rerender = rerender ,
456
450
base_branch = base_branch ,
451
+ dry_run = dry_run ,
457
452
** kwargs ,
458
453
)
459
454
@@ -464,6 +459,7 @@ def run(
464
459
git_backend : GitPlatformBackend ,
465
460
rerender : bool = True ,
466
461
base_branch : str = "main" ,
462
+ dry_run : bool = False ,
467
463
** kwargs : typing .Any ,
468
464
) -> tuple [MigrationUidTypedDict , dict ] | tuple [Literal [False ], Literal [False ]]:
469
465
"""For a given feedstock and migration run the migration
@@ -558,64 +554,67 @@ def run(
558
554
logger .warning ("Skipping migration due to solvability check failure" )
559
555
return False , False
560
556
561
- pr_data : PullRequestData | PullRequestInfoSpecial | None
562
- """
563
- The PR data for the PR that was created. The contents of this variable will be stored in the bot's database.
564
- None means: We don't update the PR data.
565
- """
557
+ # This is needed because we want to migrate to the new backend step-by-step
558
+ repo : github3 .repos .Repository | None = github3_client ().repository (
559
+ context .git_repo_owner , context .git_repo_name
560
+ )
561
+
562
+ assert repo is not None
563
+
564
+ feedstock_dir = str (context .local_clone_dir .resolve ())
565
+
566
+ # TODO: Better annotation here
567
+ pr_json : typing .Union [MutableMapping , None , bool ]
566
568
if (
567
569
isinstance (migrator , MigrationYaml )
568
570
and not rerender_info .nontrivial_changes
569
571
and context .attrs ["name" ] != "conda-forge-pinning"
570
572
):
571
573
# spoof this so it looks like the package is done
572
- pr_data = get_spoofed_closed_pr_info ()
574
+ pr_json = {
575
+ "state" : "closed" ,
576
+ "merged_at" : "never issued" ,
577
+ "id" : str (uuid4 ()),
578
+ }
573
579
else :
574
- # push and PR
575
- git_backend .push_to_repository (
576
- owner = git_backend .user ,
577
- repo_name = context .git_repo_name ,
578
- git_dir = context .local_clone_dir ,
579
- branch = branch_name ,
580
- )
580
+ # push up
581
581
try :
582
- pr_data = git_backend .create_pull_request (
583
- target_owner = context .git_repo_owner ,
584
- target_repo = context .git_repo_name ,
585
- base_branch = base_branch ,
586
- head_branch = branch_name ,
587
- title = migration_run_data ["pr_title" ],
582
+ pr_json = push_repo (
583
+ fctx = context ,
584
+ feedstock_dir = feedstock_dir ,
588
585
body = migration_run_data ["pr_body" ],
586
+ repo = repo ,
587
+ title = migration_run_data ["pr_title" ],
588
+ branch = branch_name ,
589
+ base_branch = base_branch ,
590
+ dry_run = dry_run ,
589
591
)
590
- except DuplicatePullRequestError :
591
- # This shouldn't happen too often anymore since we won't double PR
592
- logger .warning (
593
- f"Attempted to create a duplicate PR for merging { git_backend .user } :{ branch_name } "
594
- f"into { context .git_repo_owner } :{ base_branch } . Ignoring."
595
- )
596
- # Don't update the PR data
597
- pr_data = None
598
592
599
- if (
600
- pr_data
601
- and pr_data .state != PullRequestState .CLOSED
602
- and rerender_info .rerender_comment
603
- ):
604
- git_backend .comment_on_pull_request (
605
- repo_owner = context .git_repo_owner ,
606
- repo_name = context .git_repo_name ,
607
- pr_number = pr_data .number ,
608
- comment = rerender_info .rerender_comment ,
593
+ # This shouldn't happen too often any more since we won't double PR
594
+ except github3 .GitHubError as e :
595
+ if e .msg != "Validation Failed" :
596
+ raise
597
+ else :
598
+ print (f"Error during push { e } " )
599
+ # If we just push to the existing PR then do nothing to the json
600
+ pr_json = False
601
+ ljpr = False
602
+
603
+ if pr_json and pr_json ["state" ] != "closed" and rerender_info .rerender_comment :
604
+ comment_on_pr (
605
+ pr_json ,
606
+ rerender_info .rerender_comment ,
607
+ repo ,
609
608
)
610
609
611
- if pr_data :
612
- pr_lazy_json = LazyJson (
613
- os .path .join ("pr_json" , f" { pr_data . id } .json" ),
610
+ if pr_json :
611
+ ljpr = LazyJson (
612
+ os .path .join ("pr_json" , str ( pr_json [ "id" ]) + " .json" ),
614
613
)
615
- with pr_lazy_json as __edit_pr_lazy_json :
616
- __edit_pr_lazy_json .update (** pr_data . model_dump ( mode = "json" ) )
614
+ with ljpr as __ljpr :
615
+ __ljpr .update (** pr_json )
617
616
else :
618
- pr_lazy_json = False
617
+ ljpr = False
619
618
620
619
# If we've gotten this far then the node is good
621
620
with context .attrs ["pr_info" ] as pri :
@@ -624,7 +623,8 @@ def run(
624
623
context .attrs , migrator_name , is_version = is_version_migration
625
624
)
626
625
627
- return migration_run_data ["migrate_return_value" ], pr_lazy_json
626
+ logger .info ("Removing feedstock dir" )
627
+ return migration_run_data ["migrate_return_value" ], ljpr
628
628
629
629
630
630
def _compute_time_per_migrator (migrators ):
@@ -707,6 +707,7 @@ def _run_migrator_on_feedstock_branch(
707
707
migrator ,
708
708
fctx : FeedstockContext ,
709
709
git_backend : GitPlatformBackend ,
710
+ dry_run ,
710
711
mctx ,
711
712
migrator_name ,
712
713
good_prs ,
@@ -722,8 +723,9 @@ def _run_migrator_on_feedstock_branch(
722
723
migrator = migrator ,
723
724
git_backend = git_backend ,
724
725
rerender = migrator .rerender ,
725
- base_branch = base_branch ,
726
726
hash_type = attrs .get ("hash_type" , "sha256" ),
727
+ base_branch = base_branch ,
728
+ dry_run = dry_run ,
727
729
)
728
730
finally :
729
731
fctx .attrs .pop ("new_version" , None )
@@ -756,7 +758,6 @@ def _run_migrator_on_feedstock_branch(
756
758
)
757
759
758
760
except (github3 .GitHubError , github .GithubException ) as e :
759
- # TODO: pull this down into run() - also check the other exceptions
760
761
if hasattr (e , "msg" ) and e .msg == "Repository was archived so is read-only." :
761
762
attrs ["archived" ] = True
762
763
else :
@@ -1008,6 +1009,7 @@ def _run_migrator(migrator, mctx, temp, time_per, git_backend: GitPlatformBacken
1008
1009
migrator = migrator ,
1009
1010
fctx = fctx ,
1010
1011
git_backend = git_backend ,
1012
+ dry_run = dry_run ,
1011
1013
mctx = mctx ,
1012
1014
migrator_name = migrator_name ,
1013
1015
good_prs = good_prs ,
0 commit comments