Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • project/automatic_updates
  • issue/automatic_updates-3159719
  • issue/automatic_updates-3227923
  • issue/automatic_updates-3227927
  • issue/automatic_updates-3227122
  • issue/automatic_updates-3227940
  • issue/automatic_updates-3228095
  • issue/automatic_updates-3228101
  • issue/automatic_updates-3228115
  • issue/automatic_updates-3228125
  • issue/automatic_updates-3228359
  • issue/automatic_updates-3228392
  • issue/automatic_updates-3225753
  • issue/automatic_updates-3227588
  • issue/automatic_updates-3228521
  • issue/automatic_updates-3228539
  • issue/automatic_updates-3226570
  • issue/automatic_updates-3228806
  • issue/automatic_updates-3227575
  • issue/automatic_updates-3229485
  • issue/automatic_updates-3228955
  • issue/automatic_updates-3230024
  • issue/automatic_updates-3230250
  • issue/automatic_updates-3230249
  • issue/automatic_updates-3230264
  • issue/automatic_updates-3230510
  • issue/automatic_updates-3230235
  • issue/automatic_updates-3230050
  • issue/automatic_updates-3230934
  • issue/automatic_updates-3230049
  • issue/automatic_updates-3230507
  • issue/automatic_updates-3231153
  • issue/automatic_updates-3231992
  • issue/automatic_updates-3232003
  • issue/automatic_updates-3232004
  • issue/automatic_updates-3231996
  • issue/automatic_updates-3231999
  • issue/automatic_updates-3230668
  • issue/automatic_updates-3232000
  • issue/automatic_updates-3232420
  • issue/automatic_updates-3232729
  • issue/automatic_updates-3232761
  • issue/automatic_updates-3231997
  • issue/automatic_updates-3232927
  • issue/automatic_updates-3232959
  • issue/automatic_updates-3233124
  • issue/automatic_updates-3230856
  • issue/automatic_updates-3233493
  • issue/automatic_updates-3233587
  • issue/automatic_updates-3233521
  • issue/automatic_updates-3236405
  • issue/automatic_updates-3236299
  • issue/automatic_updates-3238586
  • issue/automatic_updates-3238647
  • issue/automatic_updates-3238717
  • issue/automatic_updates-3238846
  • issue/automatic_updates-3238852
  • issue/automatic_updates-3238866
  • issue/automatic_updates-3238714
  • issue/automatic_updates-3239103
  • issue/automatic_updates-3233138
  • issue/automatic_updates-3239466
  • issue/automatic_updates-3239645
  • issue/automatic_updates-3239673
  • issue/automatic_updates-3277775
  • issue/automatic_updates-3280923
  • issue/automatic_updates-3275315
  • issue/automatic_updates-3279527
  • issue/automatic_updates-3279733
  • issue/automatic_updates-3281405
  • issue/automatic_updates-3281397
  • issue/automatic_updates-3280204
  • issue/automatic_updates-3277817
  • issue/automatic_updates-3277230
  • issue/automatic_updates-3276534
  • issue/automatic_updates-3279538
  • issue/automatic_updates-3280168
  • issue/automatic_updates-3271502
  • issue/automatic_updates-3283644
  • issue/automatic_updates-3302524
  • issue/automatic_updates-3275883
  • issue/automatic_updates-3280180
  • issue/automatic_updates-3274837
  • issue/automatic_updates-3281473
  • issue/automatic_updates-3281634
  • issue/automatic_updates-3239889
  • issue/automatic_updates-3240753
  • issue/automatic_updates-3233103
  • issue/automatic_updates-3240971
  • issue/automatic_updates-3233564
  • issue/automatic_updates-3241380
  • issue/automatic_updates-3241105
  • issue/automatic_updates-3242626
  • issue/automatic_updates-3242724
  • issue/automatic_updates-3243057
  • issue/automatic_updates-3243348
  • issue/automatic_updates-3243339
  • issue/automatic_updates-3243422
  • issue/automatic_updates-3243436
  • issue/automatic_updates-3243600
  • issue/automatic_updates-3243851
  • issue/automatic_updates-3243405
  • issue/automatic_updates-3244338
  • issue/automatic_updates-3244337
  • issue/automatic_updates-3244360
  • issue/automatic_updates-3244358
  • issue/automatic_updates-3244679
  • issue/automatic_updates-3244939
  • issue/automatic_updates-3244976
  • issue/automatic_updates-3245376
  • issue/automatic_updates-3245388
  • issue/automatic_updates-3245428
  • issue/automatic_updates-3245655
  • issue/automatic_updates-3245766
  • issue/automatic_updates-3245810
  • issue/automatic_updates-3245846
  • issue/automatic_updates-3246036
  • issue/automatic_updates-3246194
  • issue/automatic_updates-3246203
  • issue/automatic_updates-3246283
  • issue/automatic_updates-3279064
  • issue/automatic_updates-3246420
  • issue/automatic_updates-3246638
  • issue/automatic_updates-3246660
  • issue/automatic_updates-3246673
  • issue/automatic_updates-3246695
  • issue/automatic_updates-3245996
  • issue/automatic_updates-3247308
  • issue/automatic_updates-3247478
  • issue/automatic_updates-3247479
  • issue/automatic_updates-3279086
  • issue/automatic_updates-3248312
  • issue/automatic_updates-3248523
  • issue/automatic_updates-3248527
  • issue/automatic_updates-3244412
  • issue/automatic_updates-3248976
  • issue/automatic_updates-3248909
  • issue/automatic_updates-3246507
  • issue/automatic_updates-3249531
  • issue/automatic_updates-3249517
  • issue/automatic_updates-3249983
  • issue/automatic_updates-3249135
  • issue/automatic_updates-3250136
  • issue/automatic_updates-3250386
  • issue/automatic_updates-3251701
  • issue/automatic_updates-3250696
  • issue/automatic_updates-3248911
  • issue/automatic_updates-3227420
  • issue/automatic_updates-3252071
  • issue/automatic_updates-3252097
  • issue/automatic_updates-3252109
  • issue/automatic_updates-3252126
  • issue/automatic_updates-3249130
  • issue/automatic_updates-3251972
  • issue/automatic_updates-3252187
  • issue/automatic_updates-3252328
  • issue/automatic_updates-3252324
  • issue/automatic_updates-3252533
  • issue/automatic_updates-3253055
  • issue/automatic_updates-3253186
  • issue/automatic_updates-3253395
  • issue/automatic_updates-3253400
  • issue/automatic_updates-3253624
  • issue/automatic_updates-3253647
  • issue/automatic_updates-3253649
  • issue/automatic_updates-3253858
  • issue/automatic_updates-3254166
  • issue/automatic_updates-3254207
  • issue/automatic_updates-3279108
  • issue/automatic_updates-3254606
  • issue/automatic_updates-3254616
  • issue/automatic_updates-3254911
  • issue/automatic_updates-3255011
  • issue/automatic_updates-3255014
  • issue/automatic_updates-3255320
  • issue/automatic_updates-3277562
  • issue/automatic_updates-3255678
  • issue/automatic_updates-3256958
  • issue/automatic_updates-3257115
  • issue/automatic_updates-3257432
  • issue/automatic_updates-3257446
  • issue/automatic_updates-3257473
  • issue/automatic_updates-3257134
  • issue/automatic_updates-3257849
  • issue/automatic_updates-3258065
  • issue/automatic_updates-3258056
  • issue/automatic_updates-3258048
  • issue/automatic_updates-3258045
  • issue/automatic_updates-3258464
  • issue/automatic_updates-3258611
  • issue/automatic_updates-3258646
  • issue/automatic_updates-3258661
  • issue/automatic_updates-3258667
  • issue/automatic_updates-3258590
  • issue/automatic_updates-3259228
  • issue/automatic_updates-3259656
  • issue/automatic_updates-3252299
  • issue/automatic_updates-3259664
  • issue/automatic_updates-3259822
  • issue/automatic_updates-3259810
  • issue/automatic_updates-3259814
  • issue/automatic_updates-3260368
  • issue/automatic_updates-3257845
  • issue/automatic_updates-3260664
  • issue/automatic_updates-3260672
  • issue/automatic_updates-3260698
  • issue/automatic_updates-3260662
  • issue/automatic_updates-3260669
  • issue/automatic_updates-3260668
  • issue/automatic_updates-3261637
  • issue/automatic_updates-3261772
  • issue/automatic_updates-3261847
  • issue/automatic_updates-3262016
  • issue/automatic_updates-3262244
  • issue/automatic_updates-3262303
  • issue/automatic_updates-3261642
  • issue/automatic_updates-3262359
  • issue/automatic_updates-3262542
  • issue/automatic_updates-3261098
  • issue/automatic_updates-3260666
  • issue/automatic_updates-3262587
  • issue/automatic_updates-3262965
  • issue/automatic_updates-3263155
  • issue/automatic_updates-3263223
  • issue/automatic_updates-3254755
  • issue/automatic_updates-3261758
  • issue/automatic_updates-3258059
  • issue/automatic_updates-3259196
  • issue/automatic_updates-3263865
  • issue/automatic_updates-3262284
  • issue/automatic_updates-3264554
  • issue/automatic_updates-3248928
  • issue/automatic_updates-3248929
  • issue/automatic_updates-3265072
  • issue/automatic_updates-3265057
  • issue/automatic_updates-3265873
  • issue/automatic_updates-3266092
  • issue/automatic_updates-3266633
  • issue/automatic_updates-3266640
  • issue/automatic_updates-3266687
  • issue/automatic_updates-3266981
  • issue/automatic_updates-3267387
  • issue/automatic_updates-3267389
  • issue/automatic_updates-3267411
  • issue/automatic_updates-3267603
  • issue/automatic_updates-3265874
  • issue/automatic_updates-3267577
  • issue/automatic_updates-3267386
  • issue/automatic_updates-3268363
  • issue/automatic_updates-3268868
  • issue/automatic_updates-3268612
  • issue/automatic_updates-3269097
  • issue/automatic_updates-3267632
  • issue/automatic_updates-3270736
  • issue/automatic_updates-3271144
  • issue/automatic_updates-3271226
  • issue/automatic_updates-3271078
  • issue/automatic_updates-3271371
  • issue/automatic_updates-3267646
  • issue/automatic_updates-3272060
  • issue/automatic_updates-3265031
  • issue/automatic_updates-3253591
  • issue/automatic_updates-3272520
  • issue/automatic_updates-3272061
  • issue/automatic_updates-3272785
  • issue/automatic_updates-3273011
  • issue/automatic_updates-3273008
  • issue/automatic_updates-3273364
  • issue/automatic_updates-3273407
  • issue/automatic_updates-3271235
  • issue/automatic_updates-3273006
  • issue/automatic_updates-3271240
  • issue/automatic_updates-3271468
  • issue/automatic_updates-3272326
  • issue/automatic_updates-3273693
  • issue/automatic_updates-3264849
  • issue/automatic_updates-3273807
  • issue/automatic_updates-3273017
  • issue/automatic_updates-3274269
  • issue/automatic_updates-3274273
  • issue/automatic_updates-3274292
  • issue/automatic_updates-3273812
  • issue/automatic_updates-3274323
  • issue/automatic_updates-3274633
  • issue/automatic_updates-3274858
  • issue/automatic_updates-3274830
  • issue/automatic_updates-3274892
  • issue/automatic_updates-3275075
  • issue/automatic_updates-3275256
  • issue/automatic_updates-3275282
  • issue/automatic_updates-3275320
  • issue/automatic_updates-3275323
  • issue/automatic_updates-3275324
  • issue/automatic_updates-3275317
  • issue/automatic_updates-3275313
  • issue/automatic_updates-3275357
  • issue/automatic_updates-3275474
  • issue/automatic_updates-3275311
  • issue/automatic_updates-3275546
  • issue/automatic_updates-3275508
  • issue/automatic_updates-3275810
  • issue/automatic_updates-3275860
  • issue/automatic_updates-3275865
  • issue/automatic_updates-3275886
  • issue/automatic_updates-3275887
  • issue/automatic_updates-3276031
  • issue/automatic_updates-3276041
  • issue/automatic_updates-3276072
  • issue/automatic_updates-3276159
  • issue/automatic_updates-3276255
  • issue/automatic_updates-3275825
  • issue/automatic_updates-3276661
  • issue/automatic_updates-3275369
  • issue/automatic_updates-3277014
  • issue/automatic_updates-3277035
  • issue/automatic_updates-3272813
  • issue/automatic_updates-3277211
  • issue/automatic_updates-3277229
  • issue/automatic_updates-3275316
  • issue/automatic_updates-3274047
  • issue/automatic_updates-3277815
  • issue/automatic_updates-3276662
  • issue/automatic_updates-3277235
  • issue/automatic_updates-3278411
  • issue/automatic_updates-3278435
  • issue/automatic_updates-3279229
  • issue/automatic_updates-3277007
  • issue/automatic_updates-3284346
  • issue/automatic_updates-3239759
  • issue/automatic_updates-3284495
  • issue/automatic_updates-3284530
  • issue/automatic_updates-3282677
  • issue/automatic_updates-3281379
  • issue/automatic_updates-3285408
  • issue/automatic_updates-3285631
  • issue/automatic_updates-3285669
  • issue/automatic_updates-3273014
  • issue/automatic_updates-3273369
  • issue/automatic_updates-3285491
  • issue/automatic_updates-3285898
  • issue/automatic_updates-3287251
  • issue/automatic_updates-3291147
  • issue/automatic_updates-3286650
  • issue/automatic_updates-3291770
  • issue/automatic_updates-3280403
  • issue/automatic_updates-3291959
  • issue/automatic_updates-3287398
  • issue/automatic_updates-3285145
  • issue/automatic_updates-3292027
  • issue/automatic_updates-3278445
  • issue/automatic_updates-3292933
  • issue/automatic_updates-3292958
  • issue/automatic_updates-3293157
  • issue/automatic_updates-3292956
  • issue/automatic_updates-3293146
  • issue/automatic_updates-3293381
  • issue/automatic_updates-3293449
  • issue/automatic_updates-3293427
  • issue/automatic_updates-3293422
  • issue/automatic_updates-3293685
  • issue/automatic_updates-3291730
  • issue/automatic_updates-3293866
  • issue/automatic_updates-3294338
  • issue/automatic_updates-3293656
  • issue/automatic_updates-3294600
  • issue/automatic_updates-3294335
  • issue/automatic_updates-3295013
  • issue/automatic_updates-3284936
  • issue/automatic_updates-3295596
  • issue/automatic_updates-3295758
  • issue/automatic_updates-3295791
  • issue/automatic_updates-3295830
  • issue/automatic_updates-3295874
  • issue/automatic_updates-3295897
  • issue/automatic_updates-3296074
  • issue/automatic_updates-3295965
  • issue/automatic_updates-3296181
  • issue/automatic_updates-3296065
  • issue/automatic_updates-3296178
  • issue/automatic_updates-3296261
  • issue/automatic_updates-3293148
  • issue/automatic_updates-3303953
  • issue/automatic_updates-3304367
  • issue/automatic_updates-3304640
  • issue/automatic_updates-3304836
  • issue/automatic_updates-3304142
  • issue/automatic_updates-3298349
  • issue/automatic_updates-3298444
  • issue/automatic_updates-3298510
  • issue/automatic_updates-3298431
  • issue/automatic_updates-3298863
  • issue/automatic_updates-3298877
  • issue/automatic_updates-3298904
  • issue/automatic_updates-3298951
  • issue/automatic_updates-3299101
  • issue/automatic_updates-3299417
  • issue/automatic_updates-3293417
  • issue/automatic_updates-3299612
  • issue/automatic_updates-3299093
  • issue/automatic_updates-3299087
  • issue/automatic_updates-3300006
  • issue/automatic_updates-3300036
  • issue/automatic_updates-3293150
  • issue/automatic_updates-3303807
  • issue/automatic_updates-3303929
  • issue/automatic_updates-3304417
  • issue/automatic_updates-3303727
  • issue/automatic_updates-3305527
  • issue/automatic_updates-3301844
  • issue/automatic_updates-3302527
  • issue/automatic_updates-3302673
  • issue/automatic_updates-3302897
  • issue/automatic_updates-3303143
  • issue/automatic_updates-3303168
  • issue/automatic_updates-3303174
  • issue/automatic_updates-3303185
  • issue/automatic_updates-3303200
  • issue/automatic_updates-3303113
  • issue/automatic_updates-3304036
  • issue/automatic_updates-3304165
  • issue/automatic_updates-3304583
  • issue/automatic_updates-3303902
  • issue/automatic_updates-3304651
  • issue/automatic_updates-3305312
  • issue/automatic_updates-3305612
  • issue/automatic_updates-3305568
  • issue/automatic_updates-3305773
  • issue/automatic_updates-3305874
  • issue/automatic_updates-3310901
  • issue/automatic_updates-3310929
  • issue/automatic_updates-3310936
  • issue/automatic_updates-3310972
  • issue/automatic_updates-3311001
  • issue/automatic_updates-3311020
  • issue/automatic_updates-3305240
  • issue/automatic_updates-3305994
  • issue/automatic_updates-3305564
  • issue/automatic_updates-3305998
  • issue/automatic_updates-3306600
  • issue/automatic_updates-3306631
  • issue/automatic_updates-3307086
  • issue/automatic_updates-3307103
  • issue/automatic_updates-3307168
  • issue/automatic_updates-3306163
  • issue/automatic_updates-3304617
  • issue/automatic_updates-3307163
  • issue/automatic_updates-3307398
  • issue/automatic_updates-3307478
  • issue/automatic_updates-3307369
  • issue/automatic_updates-3308404
  • issue/automatic_updates-3307611
  • issue/automatic_updates-3308372
  • issue/automatic_updates-3308686
  • issue/automatic_updates-3308886
  • issue/automatic_updates-3309220
  • issue/automatic_updates-3309270
  • issue/automatic_updates-3308711
  • issue/automatic_updates-3309486
  • issue/automatic_updates-3305167
  • issue/automatic_updates-3309676
  • issue/automatic_updates-3309025
  • issue/automatic_updates-3309891
  • issue/automatic_updates-3308365
  • issue/automatic_updates-3310000
  • issue/automatic_updates-3309205
  • issue/automatic_updates-3248975
  • issue/automatic_updates-3310702
  • issue/automatic_updates-3272313
  • issue/automatic_updates-3310990
  • issue/automatic_updates-3310997
  • issue/automatic_updates-3311200
  • issue/automatic_updates-3310696
  • issue/automatic_updates-3311265
  • issue/automatic_updates-3303167
  • issue/automatic_updates-3310946
  • issue/automatic_updates-3308828
  • issue/automatic_updates-3310666
  • issue/automatic_updates-3109082
  • issue/automatic_updates-3311534
  • issue/automatic_updates-3311436
  • issue/automatic_updates-3308843
  • issue/automatic_updates-3303900
  • issue/automatic_updates-3312085
  • issue/automatic_updates-3312420
  • issue/automatic_updates-3312373
  • issue/automatic_updates-3312421
  • issue/automatic_updates-3312619
  • issue/automatic_updates-3312779
  • issue/automatic_updates-3275991
  • issue/automatic_updates-3312938
  • issue/automatic_updates-3312937
  • issue/automatic_updates-3312960
  • issue/automatic_updates-3312669
  • issue/automatic_updates-3312981
  • issue/automatic_updates-3313319
  • issue/automatic_updates-3313346
  • issue/automatic_updates-3310914
  • issue/automatic_updates-3317220
  • issue/automatic_updates-3317232
  • issue/automatic_updates-3317278
  • issue/automatic_updates-3317409
  • issue/automatic_updates-3317267
  • issue/automatic_updates-3317599
  • issue/automatic_updates-3317988
  • issue/automatic_updates-3318313
  • issue/automatic_updates-3313630
  • issue/automatic_updates-3313717
  • issue/automatic_updates-3313947
  • issue/automatic_updates-3313507
  • issue/automatic_updates-3276645
  • issue/automatic_updates-3313349
  • issue/automatic_updates-3314137
  • issue/automatic_updates-3314143
  • issue/automatic_updates-3304365
  • issue/automatic_updates-3317796
  • issue/automatic_updates-3317996
  • issue/automatic_updates-3316484
  • issue/automatic_updates-3313414
  • issue/automatic_updates-3314764
  • issue/automatic_updates-3314771
  • issue/automatic_updates-3314787
  • issue/automatic_updates-3314805
  • issue/automatic_updates-3314734
  • issue/automatic_updates-3298889
  • issue/automatic_updates-3314803
  • issue/automatic_updates-3315139
  • issue/automatic_updates-3314946
  • issue/automatic_updates-3315449
  • issue/automatic_updates-3315798
  • issue/automatic_updates-3315834
  • issue/automatic_updates-3309602
  • issue/automatic_updates-3316115
  • issue/automatic_updates-3316131
  • issue/automatic_updates-3316293
  • issue/automatic_updates-3316318
  • issue/automatic_updates-3310729
  • issue/automatic_updates-3315700
  • issue/automatic_updates-3316668
  • issue/automatic_updates-3316721
  • issue/automatic_updates-3306283
  • issue/automatic_updates-3316611
  • issue/automatic_updates-3316895
  • issue/automatic_updates-3317385
  • issue/automatic_updates-3318625
  • issue/automatic_updates-3318770
  • issue/automatic_updates-3318846
  • issue/automatic_updates-3318927
  • issue/automatic_updates-3318933
  • issue/automatic_updates-3319044
  • issue/automatic_updates-3319045
  • issue/automatic_updates-3325716
  • issue/automatic_updates-3324421
  • issue/automatic_updates-3320486
  • issue/automatic_updates-3320558
  • issue/automatic_updates-3321206
  • issue/automatic_updates-3326934
  • issue/automatic_updates-3320755
  • issue/automatic_updates-3328765
  • issue/automatic_updates-3325654
  • issue/automatic_updates-3325869
  • issue/automatic_updates-3277034
  • issue/automatic_updates-3328516
  • issue/automatic_updates-3322546
  • issue/automatic_updates-3320487
  • issue/automatic_updates-3320792
  • issue/automatic_updates-3320815
  • issue/automatic_updates-3320638
  • issue/automatic_updates-3321256
  • issue/automatic_updates-3321684
  • issue/automatic_updates-3325522
  • issue/automatic_updates-3326334
  • issue/automatic_updates-3328234
  • issue/automatic_updates-3328740
  • issue/automatic_updates-3316932
  • issue/automatic_updates-3321386
  • issue/automatic_updates-3321933
  • issue/automatic_updates-3321282
  • issue/automatic_updates-3326801
  • issue/automatic_updates-3327753
  • issue/automatic_updates-3328742
  • issue/automatic_updates-3322313
  • issue/automatic_updates-3322203
  • issue/automatic_updates-3322150
  • issue/automatic_updates-3322404
  • issue/automatic_updates-3321236
  • issue/automatic_updates-3321994
  • issue/automatic_updates-3322589
  • issue/automatic_updates-3321904
  • issue/automatic_updates-3316855
  • issue/automatic_updates-3322931
  • issue/automatic_updates-3322913
  • issue/automatic_updates-3323037
  • issue/automatic_updates-3322918
  • issue/automatic_updates-3323211
  • issue/automatic_updates-3323565
  • issue/automatic_updates-3320824
  • issue/automatic_updates-3320836
  • issue/automatic_updates-3329002
  • issue/automatic_updates-3321971
  • issue/automatic_updates-3299094
  • issue/automatic_updates-3248544
  • issue/automatic_updates-3330139
  • issue/automatic_updates-3330365
  • issue/automatic_updates-3330712
  • issue/automatic_updates-3318065
  • issue/automatic_updates-3331310
  • issue/automatic_updates-3322917
  • issue/automatic_updates-3330140
  • issue/automatic_updates-3323003
  • issue/automatic_updates-3331355
  • issue/automatic_updates-3334054
  • issue/automatic_updates-3323706
  • issue/automatic_updates-3331168
  • issue/automatic_updates-3343430
  • issue/automatic_updates-3344562
  • issue/automatic_updates-3345039
  • issue/automatic_updates-3344039
  • issue/automatic_updates-3345313
  • issue/automatic_updates-3331471
  • issue/automatic_updates-3334994
  • issue/automatic_updates-3327229
  • issue/automatic_updates-3343889
  • issue/automatic_updates-3344124
  • issue/automatic_updates-3344689
  • issue/automatic_updates-3316368
  • issue/automatic_updates-3345767
  • issue/automatic_updates-3317815
  • issue/automatic_updates-3328600
  • issue/automatic_updates-3332256
  • issue/automatic_updates-3335766
  • issue/automatic_updates-3335802
  • issue/automatic_updates-3335908
  • issue/automatic_updates-3336243
  • issue/automatic_updates-3336247
  • issue/automatic_updates-3336255
  • issue/automatic_updates-3336259
  • issue/automatic_updates-3337062
  • issue/automatic_updates-3337068
  • issue/automatic_updates-3311229
  • issue/automatic_updates-3337697
  • issue/automatic_updates-3343768
  • issue/automatic_updates-3344127
  • issue/automatic_updates-3344595
  • issue/automatic_updates-3345763
  • issue/automatic_updates-3345765
  • issue/automatic_updates-3345771
  • issue/automatic_updates-3337760
  • issue/automatic_updates-3337049
  • issue/automatic_updates-3342430
  • issue/automatic_updates-3319507
  • issue/automatic_updates-3344583
  • issue/automatic_updates-3345764
  • issue/automatic_updates-3345768
  • issue/automatic_updates-3338667
  • issue/automatic_updates-3339016
  • issue/automatic_updates-3343827
  • issue/automatic_updates-3344556
  • issue/automatic_updates-3338666
  • issue/automatic_updates-3345649
  • issue/automatic_updates-3339657
  • issue/automatic_updates-3339719
  • issue/automatic_updates-3338789
  • issue/automatic_updates-3340022
  • issue/automatic_updates-3340284
  • issue/automatic_updates-3340638
  • issue/automatic_updates-3316617
  • issue/automatic_updates-3341224
  • issue/automatic_updates-3337953
  • issue/automatic_updates-3339714
  • issue/automatic_updates-3341708
  • issue/automatic_updates-3341841
  • issue/automatic_updates-3326486
  • issue/automatic_updates-3321474
  • issue/automatic_updates-3341974
  • issue/automatic_updates-3342120
  • issue/automatic_updates-3342227
  • issue/automatic_updates-3323461
  • issue/automatic_updates-3342137
  • issue/automatic_updates-3342460
  • issue/automatic_updates-3342364
  • issue/automatic_updates-3345028
  • issue/automatic_updates-3345549
  • issue/automatic_updates-3345881
  • issue/automatic_updates-3345762
  • issue/automatic_updates-3342726
  • issue/automatic_updates-3337667
  • issue/automatic_updates-3343463
  • issue/automatic_updates-3345766
  • issue/automatic_updates-3345754
  • issue/automatic_updates-3345633
  • issue/automatic_updates-3345772
  • issue/automatic_updates-3345769
  • issue/automatic_updates-3345761
  • issue/automatic_updates-3345755
  • issue/automatic_updates-3345760
  • issue/automatic_updates-3345757
  • issue/automatic_updates-3346520
  • issue/automatic_updates-3346545
  • issue/automatic_updates-3337054
  • issue/automatic_updates-3346628
  • issue/automatic_updates-3346717
  • issue/automatic_updates-3346594
  • issue/automatic_updates-3346659
  • issue/automatic_updates-3347031
  • issue/automatic_updates-3346547
  • issue/automatic_updates-3347164
  • issue/automatic_updates-3318306
  • issue/automatic_updates-3345646
  • issue/automatic_updates-3347165
  • issue/automatic_updates-3347959
  • issue/automatic_updates-3347267
  • issue/automatic_updates-3338346
  • issue/automatic_updates-3348122
  • issue/automatic_updates-3348129
  • issue/automatic_updates-3348162
  • issue/automatic_updates-3348276
  • issue/automatic_updates-3348441
  • issue/automatic_updates-3351604
  • issue/automatic_updates-3316843
  • issue/automatic_updates-3351908
  • issue/automatic_updates-3352731
  • issue/automatic_updates-3352898
  • issue/automatic_updates-3348866
  • issue/automatic_updates-3342817
  • issue/automatic_updates-3348159
  • issue/automatic_updates-3349142
  • issue/automatic_updates-3349966
  • issue/automatic_updates-3350909
  • issue/automatic_updates-3351594
  • issue/automatic_updates-3351883
  • issue/automatic_updates-3351925
  • issue/automatic_updates-3352198
  • issue/automatic_updates-3334552
  • issue/automatic_updates-3342790
  • issue/automatic_updates-3345222
  • issue/automatic_updates-3351212
  • issue/automatic_updates-3351093
  • issue/automatic_updates-3351247
  • issue/automatic_updates-3351962
  • issue/automatic_updates-3345641
  • issue/automatic_updates-3338940
  • issue/automatic_updates-3343721
  • issue/automatic_updates-3351069
  • issue/automatic_updates-3353219
  • issue/automatic_updates-3159920
  • issue/automatic_updates-3352355
  • issue/automatic_updates-3341469
  • issue/automatic_updates-3354099
  • issue/automatic_updates-3339659
  • issue/automatic_updates-3354312
  • issue/automatic_updates-3351895
  • issue/automatic_updates-3354249
  • issue/automatic_updates-3353270
  • issue/automatic_updates-3354003
  • issue/automatic_updates-3355074
  • issue/automatic_updates-3355094
  • issue/automatic_updates-3355105
  • issue/automatic_updates-3355162
  • issue/automatic_updates-3355446
  • issue/automatic_updates-3355045
  • issue/automatic_updates-3355558
  • issue/automatic_updates-3355553
  • issue/automatic_updates-3354594
  • issue/automatic_updates-3355609
  • issue/automatic_updates-3354325
  • issue/automatic_updates-3356395
  • issue/automatic_updates-3356638
  • issue/automatic_updates-3356640
  • issue/automatic_updates-3354701
  • issue/automatic_updates-3355463
  • issue/automatic_updates-3356804
  • issue/automatic_updates-3357721
  • issue/automatic_updates-3357578
  • issue/automatic_updates-3357657
  • issue/automatic_updates-3304108
  • issue/automatic_updates-3357941
  • issue/automatic_updates-3358012
  • issue/automatic_updates-3345535
  • issue/automatic_updates-3354827
  • issue/automatic_updates-3358570
  • issue/automatic_updates-3358878
  • issue/automatic_updates-3355628
  • issue/automatic_updates-3358504
  • issue/automatic_updates-3357969
  • issue/automatic_updates-3359609
  • issue/automatic_updates-3359727
  • issue/automatic_updates-3359825
  • issue/automatic_updates-3359820
  • issue/automatic_updates-3360548
  • issue/automatic_updates-3357480
  • issue/automatic_updates-3360656
  • issue/automatic_updates-3360763
  • issue/automatic_updates-3360655
  • issue/automatic_updates-3355618
  • issue/automatic_updates-3349351
  • issue/automatic_updates-3362110
  • issue/automatic_updates-3362143
  • issue/automatic_updates-3362589
  • issue/automatic_updates-3349004
  • issue/automatic_updates-3362507
  • issue/automatic_updates-3362746
  • issue/automatic_updates-3362978
  • issue/automatic_updates-3363259
  • issue/automatic_updates-3363725
  • issue/automatic_updates-3363926
  • issue/automatic_updates-3363937
  • issue/automatic_updates-3364514
  • issue/automatic_updates-3284443
  • issue/automatic_updates-3363938
  • issue/automatic_updates-3364731
  • issue/automatic_updates-3364748
  • issue/automatic_updates-3364735
  • issue/automatic_updates-3364725
  • issue/automatic_updates-3359670
  • issue/automatic_updates-3365133
  • issue/automatic_updates-3365151
  • issue/automatic_updates-3365177
  • issue/automatic_updates-3364958
  • issue/automatic_updates-3365390
  • issue/automatic_updates-3365414
  • issue/automatic_updates-3346644
  • issue/automatic_updates-3366267
  • issue/automatic_updates-3366289
  • issue/automatic_updates-3366499
  • issue/automatic_updates-3365437
  • issue/automatic_updates-3354914
  • issue/automatic_updates-3253828
  • issue/automatic_updates-3345484
  • issue/automatic_updates-3352846
  • issue/automatic_updates-3368741
  • issue/automatic_updates-3406008
  • issue/automatic_updates-3406122
  • issue/automatic_updates-3370197
  • issue/automatic_updates-3366271
  • issue/automatic_updates-3364135
  • issue/automatic_updates-3370603
  • issue/automatic_updates-3400146
  • issue/automatic_updates-3406010
  • issue/automatic_updates-3404429
  • issue/automatic_updates-3371212
  • issue/automatic_updates-3371076
  • issue/automatic_updates-3372673
  • issue/automatic_updates-3368808
  • issue/automatic_updates-3374175
  • issue/automatic_updates-3374739
  • issue/automatic_updates-3374753
  • issue/automatic_updates-3375679
  • issue/automatic_updates-3377237
  • issue/automatic_updates-3377245
  • issue/automatic_updates-3378774
  • issue/automatic_updates-3378793
  • issue/automatic_updates-3360485
  • issue/automatic_updates-3380698
  • issue/automatic_updates-3375940
  • issue/automatic_updates-3381294
  • issue/automatic_updates-3381484
  • issue/automatic_updates-3382942
  • issue/automatic_updates-3383462
  • issue/automatic_updates-3383451
  • issue/automatic_updates-3384359
  • issue/automatic_updates-3384637
  • issue/automatic_updates-3375640
  • issue/automatic_updates-3386135
  • issue/automatic_updates-3386533
  • issue/automatic_updates-3387610
  • issue/automatic_updates-3387637
  • issue/automatic_updates-3387656
  • issue/automatic_updates-3389157
  • issue/automatic_updates-3388965
  • issue/automatic_updates-3387379
  • issue/automatic_updates-3390493
  • issue/automatic_updates-3308235
  • issue/automatic_updates-3391715
  • issue/automatic_updates-3392246
  • issue/automatic_updates-3393633
  • issue/automatic_updates-3379344
  • issue/automatic_updates-3394413
  • issue/automatic_updates-3394705
  • issue/automatic_updates-3394936
  • issue/automatic_updates-3363497
  • issue/automatic_updates-3395782
  • issue/automatic_updates-3341406
  • issue/automatic_updates-3311472
  • issue/automatic_updates-3397228
  • issue/automatic_updates-3352654
  • issue/automatic_updates-3398782
  • issue/automatic_updates-3399147
  • issue/automatic_updates-3399155
  • issue/automatic_updates-3406812
  • issue/automatic_updates-3408483
  • issue/automatic_updates-3408488
  • issue/automatic_updates-3408560
  • issue/automatic_updates-3437633
  • issue/automatic_updates-3408835
  • issue/automatic_updates-3408937
  • issue/automatic_updates-3409491
  • issue/automatic_updates-3409519
  • issue/automatic_updates-3377458
  • issue/automatic_updates-3437951
  • issue/automatic_updates-3409774
  • issue/automatic_updates-3410047
  • issue/automatic_updates-3411110
  • issue/automatic_updates-3411241
  • issue/automatic_updates-3411276
  • issue/automatic_updates-3411392
  • issue/automatic_updates-3411240
  • issue/automatic_updates-3412630
  • issue/automatic_updates-3413866
  • issue/automatic_updates-3414168
  • issue/automatic_updates-3415291
  • issue/automatic_updates-3415389
  • issue/automatic_updates-3415403
  • issue/automatic_updates-3416768
  • issue/automatic_updates-3417905
  • issue/automatic_updates-3420188
  • issue/automatic_updates-3421641
  • issue/automatic_updates-3424290
  • issue/automatic_updates-3426229
  • issue/automatic_updates-3426666
  • issue/automatic_updates-3426716
  • issue/automatic_updates-3428199
  • issue/automatic_updates-3436741
  • issue/automatic_updates-3441923
  • issue/automatic_updates-3428651
  • issue/automatic_updates-3441799
  • issue/automatic_updates-3443249
  • issue/automatic_updates-3428922
  • issue/automatic_updates-3441817
  • issue/automatic_updates-3429248
  • issue/automatic_updates-3440646
  • issue/automatic_updates-3437877
  • issue/automatic_updates-3445149
  • issue/automatic_updates-3429268
  • issue/automatic_updates-3442153
  • issue/automatic_updates-3438156
  • issue/automatic_updates-3436993
  • issue/automatic_updates-3437704
  • issue/automatic_updates-3432496
  • issue/automatic_updates-3440006
  • issue/automatic_updates-3435893
  • issue/automatic_updates-3441577
  • issue/automatic_updates-3437023
  • issue/automatic_updates-3432391
  • issue/automatic_updates-3432447
  • issue/automatic_updates-3432472
  • issue/automatic_updates-3432489
  • issue/automatic_updates-3432476
  • issue/automatic_updates-3435918
  • issue/automatic_updates-3439067
  • issue/automatic_updates-3437409
  • issue/automatic_updates-3449093
  • issue/automatic_updates-3449480
  • issue/automatic_updates-3449519
  • issue/automatic_updates-3449631
  • issue/automatic_updates-3449636
  • issue/automatic_updates-3449689
  • issue/automatic_updates-3449693
  • issue/automatic_updates-3450884
  • issue/automatic_updates-3452870
  • issue/automatic_updates-3453030
  • issue/automatic_updates-3455161
  • issue/automatic_updates-3459557
  • issue/automatic_updates-3462138
  • issue/automatic_updates-3462168
  • issue/automatic_updates-3462883
  • issue/automatic_updates-3463662
  • issue/automatic_updates-3463813
  • issue/automatic_updates-3446371
  • issue/automatic_updates-3465155
  • issue/automatic_updates-3340355
  • issue/automatic_updates-3467749
  • issue/automatic_updates-3473410
  • issue/automatic_updates-3441926
  • issue/automatic_updates-3474603
  • issue/automatic_updates-3484802
  • issue/automatic_updates-3498586
  • issue/automatic_updates-3499481
  • issue/automatic_updates-3498018
  • issue/automatic_updates-3506632
  • issue/automatic_updates-3511959
  • issue/automatic_updates-3511943
981 results
Show changes
Commits on Source (3)
Showing
with 879 additions and 86 deletions
......@@ -31,11 +31,18 @@
"test": [
"Composer\\Config::disableProcessTimeout",
"scripts/phpunit.sh"
]
],
"core-convert": "Drupal\\automatic_updates\\CoreCovert\\Converter::doConvert"
},
"scripts-descriptions": {
"phpcbf": "Automatically fixes standards violations where possible.",
"phpcs": "Checks code for standards compliance.",
"test": "Runs PHPUnit tests."
}
"test": "Runs PHPUnit tests.",
"core-convert": "Converts this module to a core merge request. Excepts 2 arguments. 1) The core clone directory. 2) The core merge request branch."
},
"autoload": {
"psr-4": {
"Drupal\\automatic_updates\\CoreCovert\\": "scripts/src"
}
}
}
......@@ -4,3 +4,4 @@ stager's
syncer
syncers
kirk
unwritable
......@@ -199,4 +199,15 @@ final class ProjectInfo {
return FALSE;
}
/**
* Gets the supported branches of the project.
*
* @return string[]
* The supported branches.
*/
public function getSupportedBranches(): array {
$available_updates = $this->getAvailableProjects()[$this->name];
return isset($available_updates['supported_branches']) ? explode(',', $available_updates['supported_branches']) : [];
}
}
<?xml version="1.0" encoding="utf-8"?>
<!--
Contains metadata about the following (fake) releases of Drupal core, all of which are secure, in order:
* 10.0.0
* 9.7.2
* 9.7.1
* 9.7.0
* 9.6.1
* 9.6.0
* 9.5.1
* 9.5.0
* 9.4.0, which is in an unsupported branch
* 9.7.x-dev
-->
<project xmlns:dc="http://purl.org/dc/elements/1.1/">
<title>Drupal</title>
<short_name>drupal</short_name>
<dc:creator>Drupal</dc:creator>
<supported_branches>9.5.,9.6.,9.7.,10.0.</supported_branches>
<project_status>published</project_status>
<link>http://example.com/project/drupal</link>
<terms>
<term>
<name>Projects</name>
<value>Drupal project</value>
</term>
</terms>
<releases>
<release>
<name>Drupal 10.0.0</name>
<version>10.0.0</version>
<status>published</status>
<release_link>http://example.com/drupal-10-0-0-release</release_link>
<download_link>http://example.com/drupal-10-0-0.tar.gz</download_link>
<date>1250425521</date>
<terms>
<term>
<name>Release type</name>
<value>New features</value>
</term>
<term>
<name>Release type</name>
<value>Bug fixes</value>
</term>
</terms>
</release>
<release>
<name>Drupal 9.7.2</name>
<version>9.7.2</version>
<status>published</status>
<release_link>http://example.com/drupal-9-7-2-release</release_link>
<download_link>http://example.com/drupal-9-7-2.tar.gz</download_link>
<date>1250425521</date>
<terms>
<term>
<name>Release type</name>
<value>New features</value>
</term>
<term>
<name>Release type</name>
<value>Bug fixes</value>
</term>
</terms>
</release>
<release>
<name>Drupal 9.7.1</name>
<version>9.7.1</version>
<status>published</status>
<release_link>http://example.com/drupal-9-7-1-release</release_link>
<download_link>http://example.com/drupal-9-7-1.tar.gz</download_link>
<date>1250425521</date>
<terms>
<term>
<name>Release type</name>
<value>New features</value>
</term>
<term>
<name>Release type</name>
<value>Bug fixes</value>
</term>
</terms>
</release>
<release>
<name>Drupal 9.7.0</name>
<version>9.7.0</version>
<status>published</status>
<release_link>http://example.com/drupal-9-7-0-release</release_link>
<download_link>http://example.com/drupal-9-7-0.tar.gz</download_link>
<date>1250424521</date>
<terms>
<term>
<name>Release type</name>
<value>New features</value>
</term>
<term>
<name>Release type</name>
<value>Bug fixes</value>
</term>
</terms>
</release>
<release>
<name>Drupal 9.6.1</name>
<version>9.6.1</version>
<status>published</status>
<release_link>http://example.com/drupal-9-6-1-release</release_link>
<download_link>http://example.com/drupal-9-6-1.tar.gz</download_link>
<date>1250425521</date>
<terms>
<term>
<name>Release type</name>
<value>New features</value>
</term>
<term>
<name>Release type</name>
<value>Bug fixes</value>
</term>
</terms>
</release>
<release>
<name>Drupal 9.6.0</name>
<version>9.6.0</version>
<status>published</status>
<release_link>http://example.com/drupal-9-6-0-release</release_link>
<download_link>http://example.com/drupal-9-6-0.tar.gz</download_link>
<date>1250424521</date>
<terms>
<term>
<name>Release type</name>
<value>New features</value>
</term>
<term>
<name>Release type</name>
<value>Bug fixes</value>
</term>
</terms>
</release>
<release>
<name>Drupal 9.5.1</name>
<version>9.5.1</version>
<status>published</status>
<release_link>http://example.com/drupal-9-5-1-release</release_link>
<download_link>http://example.com/drupal-9-5-1.tar.gz</download_link>
<date>1250425521</date>
<terms>
<term>
<name>Release type</name>
<value>New features</value>
</term>
<term>
<name>Release type</name>
<value>Bug fixes</value>
</term>
</terms>
</release>
<release>
<name>Drupal 9.5.0</name>
<version>9.5.0</version>
<status>published</status>
<release_link>http://example.com/drupal-9-5-0-release</release_link>
<download_link>http://example.com/drupal-9-5-0.tar.gz</download_link>
<date>1250424521</date>
<terms>
<term>
<name>Release type</name>
<value>New features</value>
</term>
<term>
<name>Release type</name>
<value>Bug fixes</value>
</term>
</terms>
</release>
<release>
<name>Drupal 9.4.0</name>
<version>9.4.0</version>
<status>published</status>
<release_link>http://example.com/drupal-9-4-0-release</release_link>
<download_link>http://example.com/drupal-9-4-0.tar.gz</download_link>
<date>1240424421</date>
<terms>
<term>
<name>Release type</name>
<value>New features</value>
</term>
<term>
<name>Release type</name>
<value>Bug fixes</value>
</term>
</terms>
</release>
<release>
<name>Drupal 9.7.x-dev</name>
<version>9.7.x-dev</version>
<status>published</status>
<release_link>http://example.com/drupal-9-7-x-dex-release</release_link>
<download_link>http://example.com/drupal-9-7-x-dex.tar.gz</download_link>
<date>1250424521</date>
<terms>
<term>
<name>Release type</name>
<value>New features</value>
</term>
<term>
<name>Release type</name>
<value>Bug fixes</value>
</term>
</terms>
</release>
</releases>
</project>
<?xml version="1.0" encoding="utf-8"?>
<!--
Contains metadata about releases of Drupal core with no supported branches:
-->
<project xmlns:dc="http://purl.org/dc/elements/1.1/">
<title>Drupal</title>
<short_name>drupal</short_name>
<dc:creator>Drupal</dc:creator>
<supported_branches/>
<project_status>published</project_status>
<link>http://example.com/project/drupal</link>
<terms>
<term>
<name>Projects</name>
<value>Drupal project</value>
</term>
</terms>
</project>
<?xml version="1.0" encoding="utf-8"?>
<!--
Contains metadata about releases of Drupal core with <supported_branches></supported_branches> not set:
-->
<project xmlns:dc="http://purl.org/dc/elements/1.1/">
<title>Drupal</title>
<short_name>drupal</short_name>
<dc:creator>Drupal</dc:creator>
<project_status>published</project_status>
<link>http://example.com/project/drupal</link>
<terms>
<term>
<name>Projects</name>
<value>Drupal project</value>
</term>
</terms>
</project>
......@@ -251,7 +251,6 @@ END;
// Now that we know the project was created successfully, we can set the
// web root with confidence.
$this->webRoot = 'project/' . $this->runComposer('composer config extra.drupal-scaffold.locations.web-root', 'project');
// BEGIN: DELETE FROM CORE MERGE REQUEST
// Install Automatic Updates into the test project and ensure it wasn't
// symlinked.
......@@ -441,7 +440,7 @@ END;
return $temp_directory;
}
// BEGIN: DELETE FROM CORE MERGE REQUEST
// BEGIN: DELETE FROM CORE MERGE REQUEST.
/**
* {@inheritdoc}
......@@ -463,5 +462,5 @@ END;
file_put_contents($file, json_encode($data, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
}
// END: DELETE FROM CORE MERGE REQUEST
// END: DELETE FROM CORE MERGE REQUEST.
}
<?php
namespace Drupal\Tests\package_manager\Kernel;
/**
* Test that the 'fake-site' fixture is a valid starting point.
*
* @group package_manager
*/
class FakeSiteFixtureTest extends PackageManagerKernelTestBase {
/**
* Tests the complete stage life cycle using the 'fake-site' fixture.
*/
public function testLifeCycle(): void {
$this->assertStatusCheckResults([]);
$this->assertResults([]);
// Ensure there are no validation errors after the stage lifecycle has been
// completed.
$this->assertStatusCheckResults([]);
}
}
......@@ -242,4 +242,52 @@ class ProjectInfoTest extends PackageManagerKernelTestBase {
$this->assertSame($expected_to_be_safe, $project_info->isInstalledVersionSafe());
}
/**
* Data provider for testGetSupportedBranches().
*
* @return mixed[][]
* The test cases.
*/
public function providerGetSupportedBranches(): array {
$dir = __DIR__ . '/../../fixtures/release-history/';
return [
'xml with supported branches' => [
$dir . 'drupal.10.0.0.xml',
[
'9.5.',
'9.6.',
'9.7.',
'10.0.',
],
],
'xml with supported branches not set' => [
$dir . 'drupal.9.8.1-supported_branches_not_set.xml',
[],
],
'xml with empty supported branches' => [
$dir . 'drupal.9.8.1-empty_supported_branches.xml',
[
'',
],
],
];
}
/**
* @covers ::getSupportedBranches()
*
* @param string $release_xml
* The path of the release metadata.
* @param string[] $expected_supported_branches
* The expected supported branches.
*
* @dataProvider providerGetSupportedBranches
*/
public function testGetSupportedBranches(string $release_xml, array $expected_supported_branches): void {
$this->setReleaseMetadata(['drupal' => $release_xml]);
$project_info = new ProjectInfo('drupal');
$this->assertSame($expected_supported_branches, $project_info->getSupportedBranches());
}
}
<?php
namespace Drupal\automatic_updates\CoreCovert;
use Composer\Script\Event;
use Symfony\Component\Filesystem\Filesystem;
/**
* Converts the contrib module to core merge request.
*
* File usage:
*
* @code
* composer core-covert /path/to/core merge-request-branch
* @endcode
*
* The core clone should already have the core merge request locally.
*/
class Converter {
/**
* Prints message.
*
* @param string $msg
* The message to print.
*/
private static function info(string $msg): void {
print "\n$msg";
}
/**
* Converts the contrib module to core merge request.
*
* @param \Composer\Script\Event $event
* The Composer event.
*/
public static function doConvert(Event $event): void {
$args = $event->getArguments();
if (count($args) !== 2) {
throw new \Exception("This scripts 2 arguments, a directory that is a core clone and the branch.");
}
$core_dir = $args[0];
$core_branch = $args[1];
if (!is_dir($core_dir)) {
throw new \Exception("$core_dir is not a directory.");
}
$old_machine_name = 'automatic_updates';
$new_machine_name = 'auto_updates';
static::switchToBranches($core_dir, $core_branch);
self::info('Switched branches');
$fs = new Filesystem();
$core_module_path = static::getCoreModulePath($core_dir);
$package_manager_core_path = $core_dir . "/core/modules/package_manager";
// Remove old module.
$fs->remove($core_module_path);
self::info('Removed old core module');
$fs->remove($package_manager_core_path);
self::info("Removed package manager");
$fs->mirror(self::getContribDir(), $core_module_path);
self::info('Mirrored into core module');
// Remove unneeded.
$removals = [
'package_manager/package_manager.install',
'automatic_updates_9_3_shim',
'automatic_updates_extensions',
'drupalci.yml',
'README.md',
'.git',
'pcre.ini',
'composer.json',
'.gitattributes',
'.gitignore',
'DEVELOPING.md',
'scripts',
'dictionary.txt',
];
$removals = array_map(function ($path) use ($core_module_path) {
return "$core_module_path/$path";
}, $removals);
$fs->remove($removals);
self::info('Remove not needed');
// Replace in file names and contents.
$replacements = [
$old_machine_name => $new_machine_name,
'AutomaticUpdates' => 'AutoUpdates',
"core_version_requirement: ^9.3" => "package: Core\nversion: VERSION\nlifecycle: experimental",
];
foreach ($replacements as $search => $replace) {
static::renameFiles($core_module_path, $search, $replace);
static::replaceContents($core_module_path, $search, $replace);
}
self::info('Replacements done.');
static::removeLines($core_dir);
self::info('Remove unneeded lines');
$fs->rename("$core_module_path/package_manager", $core_dir . "/core/modules/package_manager");
self::info('Move package manager');
static::addWordsToDictionary($core_dir, self::getContribDir() . "/dictionary.txt");
self::info("Added to dictionary");
static::runCoreChecks($core_dir);
self::info('Ran core checks');
static::makeCommit($core_dir);
self::info('Make commit');
self::info("Done. Probably good but you should check before you push.");
}
/**
* Returns the path to the root of the contrib module.
*
* @return string
* The full path to the root of the contrib module.
*/
private static function getContribDir(): string {
return realpath(__DIR__ . '/../..');
}
/**
* Returns the path where the contrib module will be placed in Drupal Core.
*
* @param string $core_dir
* The path to the root of Drupal Core.
*
* @return string
* The path where the contrib module will be placed in Drupal Core
*/
private static function getCoreModulePath(string $core_dir): string {
return $core_dir . '/core/modules/auto_updates';
}
/**
* Replaces a string in the contents of the module files.
*
* @param string $core_module_path
* The path of module in Drupal Core.
* @param string $search
* The string to be replaced.
* @param string $replace
* The string to replace.
*/
private static function replaceContents(string $core_module_path, string $search, string $replace): void {
$files = static::getDirContents($core_module_path, TRUE);
foreach ($files as $file) {
$filePath = $file->getRealPath();
file_put_contents($filePath, str_replace($search, $replace, file_get_contents($filePath)));
}
}
/**
* Renames the module files.
*
* @param string $core_module_path
* The path of module in Drupal Core.
* @param string $old_pattern
* The old file name.
* @param string $new_pattern
* The new file name.
*/
private static function renameFiles(string $core_module_path, string $old_pattern, string $new_pattern): void {
$files = static::getDirContents($core_module_path);
// Keep a record of the files and directories to change.
// We will change all the files first, so we don't change the location of
// any files in the middle. This probably won't work if we had nested
// folders with the pattern on 2 folder levels, but we don't.
$filesToChange = [];
$dirsToChange = [];
foreach ($files as $file) {
$fileName = $file->getFilename();
if ($fileName === '.') {
$fullPath = $file->getPath();
$parts = explode('/', $fullPath);
$name = array_pop($parts);
$path = "/" . implode('/', $parts);
}
else {
$name = $fileName;
$path = $file->getPath();
}
if (strpos($name, $old_pattern) !== FALSE) {
$new_filename = str_replace($old_pattern, $new_pattern, $name);
if ($file->isFile()) {
$filesToChange[$file->getRealPath()] = $file->getPath() . "/$new_filename";
}
else {
// Store directories by path depth.
$depth = count(explode('/', $path));
$dirsToChange[$depth][$file->getRealPath()] = "$path/$new_filename";
}
}
}
foreach ($filesToChange as $old => $new) {
(new Filesystem())->rename($old, $new);
}
// Rename directories starting with the most nested to avoid renaming
// parents directories first.
krsort($dirsToChange);
foreach ($dirsToChange as $dirs) {
foreach ($dirs as $old => $new) {
(new Filesystem())->rename($old, $new);
}
}
}
/**
* Gets the contents of a directory.
*
* @param string $path
* The path of the directory.
* @param bool $excludeDirs
* (optional) If TRUE, all directories will be excluded. Defaults to FALSE.
*
* @return \SplFileInfo[]
* Array of objects containing file information.
*/
private static function getDirContents(string $path, bool $excludeDirs = FALSE): array {
$rii = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($path));
$files = [];
/** @var \SplFileInfo $file */
foreach ($rii as $file) {
if ($excludeDirs && $file->isDir()) {
continue;
}
$files[] = $file;
}
return $files;
}
/**
* Ensures the git status is clean.
*
* @return bool
* TRUE if git status is clean , otherwise returns a exception.
*/
private static function ensureGitClean(): bool {
$status_output = shell_exec('git status');
if (strpos($status_output, 'nothing to commit, working tree clean') === FALSE) {
throw new \Exception("git not clean: " . $status_output);
}
return TRUE;
}
/**
* Gets the current git branch.
*
* @return string
* The current git branch.
*/
private static function getCurrentBranch(): string {
return trim(shell_exec('git rev-parse --abbrev-ref HEAD'));
}
/**
* Switches to the branches we need.
*
* @param string $core_dir
* The path to the root of Drupal Core.
* @param string $core_branch
* The core merge request branch.
*/
private static function switchToBranches(string $core_dir, string $core_branch): void {
static::switchToBranch('8.x-2.x');
chdir($core_dir);
static::switchToBranch($core_branch);
}
/**
* Switches to a branches and makes sure it is clean.
*
* @param string $branch
* The branch to switch to.
*/
private static function switchToBranch(string $branch): void {
static::ensureGitClean();
shell_exec("git checkout $branch");
if ($branch !== static::getCurrentBranch()) {
throw new \Exception("could not check $branch");
}
}
/**
* Makes commit in the root of Drupal Core.
*
* @param string $core_dir
* The path to the root of Drupal Core.
*/
private static function makeCommit(string $core_dir): void {
chdir(self::getContribDir());
self::ensureGitClean();
$hash = trim(shell_exec('git rev-parse HEAD'));
$message = trim(shell_exec("git show -s --format='%s'"));
chdir($core_dir);
shell_exec('git add core');
shell_exec("git commit -m 'Contrib: $message - https://git.drupalcode.org/project/automatic_updates/-/commit/$hash'");
}
/**
* Adds new words to cspell dictionary.
*
* @param string $core_dir
* The path to the root of Drupal Core.
* @param string $dict_file_to_merge
* The path to the dictionary file with additional words.
*/
private static function addWordsToDictionary(string $core_dir, string $dict_file_to_merge): void {
if (!file_exists($dict_file_to_merge)) {
throw new \LogicException(sprintf('%s does not exist', $dict_file_to_merge));
}
$dict_file = $core_dir . '/core/misc/cspell/dictionary.txt';
$contents = file_get_contents($dict_file);
$words = explode("\n", $contents);
$words = array_filter($words);
$new_words = explode("\n", file_get_contents($dict_file_to_merge));
$words = array_merge($words, $new_words);
$words = array_unique($words);
asort($words);
file_put_contents($dict_file, implode("\n", $words));
}
/**
* Runs code quality checks.
*
* @param string $core_dir
* The path to the root of Drupal Core.
*/
private static function runCoreChecks(string $core_dir): void {
chdir($core_dir);
$result = NULL;
system(' sh ./core/scripts/dev/commit-code-check.sh --branch 9.5.x', $result);
if ($result !== 0) {
print "😭commit-code-check.sh failed";
exit(1);
}
print "🎉 commit-code-check.sh passed!";
}
/**
* Removes lines from the module based on a starting and ending token
* These are lines that are not need in core at all.
*
* @param string $core_dir
* The path to the root of Drupal Core.
*/
private static function removeLines(string $core_dir): void {
$files = static::getDirContents(static::getCoreModulePath($core_dir), TRUE);
foreach ($files as $file) {
$filePath = $file->getRealPath();
$contents = file_get_contents($filePath);
$lines = explode("\n", $contents);
$skip = FALSE;
$newLines = [];
foreach ($lines as $line) {
if (strpos($line, '// BEGIN: DELETE FROM CORE MERGE REQUEST')) {
if ($skip) {
throw new \Exception("Already found begin");
}
$skip = TRUE;
}
if (!$skip) {
$newLines[] = $line;
}
if (strpos($line, '// END: DELETE FROM CORE MERGE REQUEST')) {
if (!$skip) {
throw new \Exception("Didn't find matching begin");
}
$skip = FALSE;
}
}
if ($skip) {
throw new \Exception("Didn't find ending token");
}
file_put_contents($filePath, implode("\n", $newLines));
}
}
}
......@@ -174,13 +174,19 @@ final class UpdaterForm extends UpdateFormBase {
];
$project_info = new ProjectInfo('drupal');
$installed_version = ExtensionVersion::createFromVersionString($project_info->getInstalledVersion());
try {
// @todo Until https://www.drupal.org/i/3264849 is fixed, we can only show
// one release on the form. First, try to show the latest release in the
// currently installed minor. Failing that, try to show the latest
// release in the next minor.
$installed_minor_release = $this->releaseChooser->getLatestInInstalledMinor($this->updater);
$next_minor_release = $this->releaseChooser->getLatestInNextMinor($this->updater);
$support_branches = $project_info->getSupportedBranches();
$releases = [];
foreach ($support_branches as $support_branch) {
$support_branch_extension_version = ExtensionVersion::createFromSupportBranch($support_branch);
if ($support_branch_extension_version->getMajorVersion() === $installed_version->getMajorVersion() && $support_branch_extension_version->getMinorVersion() >= $installed_version->getMinorVersion()) {
$recent_release_in_minor = $this->releaseChooser->getMostRecentReleaseInMinor($this->updater, $support_branch . '0');
if ($recent_release_in_minor) {
$releases[$support_branch] = $recent_release_in_minor;
}
}
}
}
catch (\RuntimeException $e) {
$form['message'] = [
......@@ -197,7 +203,7 @@ final class UpdaterForm extends UpdateFormBase {
}
$this->displayResults($results, $this->renderer);
$project = $project_info->getProjectInfo();
if ($installed_minor_release === NULL && $next_minor_release === NULL) {
if (empty($releases)) {
if ($project['status'] === UpdateManagerInterface::CURRENT) {
$this->messenger()->addMessage($this->t('No update available'));
}
......@@ -249,72 +255,82 @@ final class UpdaterForm extends UpdateFormBase {
$type = 'update-recommended';
}
$create_update_buttons = !$stage_exists && ValidationResult::getOverallSeverity($results) !== SystemManager::REQUIREMENT_ERROR;
if ($installed_minor_release) {
$installed_version = ExtensionVersion::createFromVersionString($project_info->getInstalledVersion());
$form['installed_minor'] = $this->createReleaseTable(
$installed_minor_release,
$release_status,
$this->t('Latest version of Drupal @major.@minor (currently installed):', [
'@major' => $installed_version->getMajorVersion(),
'@minor' => $installed_version->getMinorVersion(),
]),
$type,
$create_update_buttons,
// Any update in the current minor should be the primary update.
TRUE,
);
}
if ($next_minor_release) {
// If there is no update in the current minor make the button for the next
// minor primary unless the project status is 'CURRENT' or 'NOT_CURRENT'.
// 'NOT_CURRENT' does not denote that installed version is not a valid
// only that there is newer version available.
$is_primary = !$installed_minor_release && !($project['status'] === UpdateManagerInterface::CURRENT || $project['status'] === UpdateManagerInterface::NOT_CURRENT);
$next_minor_version = ExtensionVersion::createFromVersionString($next_minor_release->getVersion());
// Since updating to another minor version of Drupal is more disruptive
// than updating within the currently installed minor version, ensure we
// display a link to the release notes for the first (x.y.0) release of
// the next minor version, which will inform site owners of any potential
// pitfalls or major changes. We should always be able to get release info
// for it; if we can't, that's an error condition.
$first_release_version = $next_minor_version->getMajorVersion() . '.' . $next_minor_version->getMinorVersion() . '.0';
$available_updates = update_get_available(TRUE);
if (isset($available_updates['drupal']['releases'][$first_release_version])) {
$next_minor_first_release = ProjectRelease::createFromArray($available_updates['drupal']['releases'][$first_release_version]);
$installed_minor_release = FALSE;
$next_minor_release_count = 0;
foreach ($releases as $release) {
$release_version = ExtensionVersion::createFromVersionString($release->getVersion());
if ($release_version->getMinorVersion() === $installed_version->getMinorVersion()) {
$installed_minor_release = TRUE;
$installed_version = ExtensionVersion::createFromVersionString($project_info->getInstalledVersion());
$form['installed_minor'] = $this->createReleaseTable(
$release,
$release_status,
$this->t('Latest version of Drupal @major.@minor (currently installed):', [
'@major' => $installed_version->getMajorVersion(),
'@minor' => $installed_version->getMinorVersion(),
]),
$type,
$create_update_buttons,
// Any update in the current minor should be the primary update.
TRUE,
);
}
else {
throw new \LogicException("Release information for Drupal $first_release_version is not available.");
}
$next_minor_release_count++;
if ($next_minor_release_count === 1) {
if ($this->moduleHandler->moduleExists('help')) {
$url = Url::fromRoute('help.page')
->setRouteParameter('name', 'automatic_updates')
->setOption('fragment', 'minor-update');
$form['minor_update_help'] = [
'#markup' => $this->t('The following updates are in newer minor version of Drupal. <a href=":url">Learn more about updating to another minor version.</a>', [
':url' => $url->toString(),
]),
'#prefix' => '<p>',
'#suffix' => '</p>',
];
}
}
// If there is no update in the current minor make the button for the
// next minor primary unless the project status is 'CURRENT' or
// 'NOT_CURRENT'. 'NOT_CURRENT' does not denote that installed version
// is not a valid only that there is newer version available.
if (!isset($is_primary)) {
$is_primary = !$installed_minor_release && !($project['status'] === UpdateManagerInterface::CURRENT || $project['status'] === UpdateManagerInterface::NOT_CURRENT);
}
else {
$is_primary = FALSE;
}
if ($this->moduleHandler->moduleExists('help')) {
$url = Url::fromRoute('help.page')
->setRouteParameter('name', 'automatic_updates')
->setOption('fragment', 'minor-update');
// Since updating to another minor version of Drupal is more
// disruptive than updating within the currently installed minor
// version, ensure we display a link to the release notes for the
// first (x.y.0) release of the next minor version, which will inform
// site owners of any potential pitfalls or major changes. We should
// always be able to get release info for it; if we can't, that's an
// error condition.
$first_release_version = $release_version->getMajorVersion() . '.' . $release_version->getMinorVersion() . '.0';
$available_updates = update_get_available(TRUE);
// @todo In https://www.drupal.org/i/3310666 handle if the .0 release is
// not available, and only pre-releases are available.
$next_minor_first_release = ProjectRelease::createFromArray($available_updates['drupal']['releases'][$first_release_version]);
// @todo Updating this wording in https://www.drupal.org/i/3280403 to
// reflect that multiple minor branches may be visible.
$form['minor_update_help'] = [
'#markup' => $this->t('The following updates are in the next minor version of Drupal. <a href=":url">Learn more about updating to another minor version.</a>', [
':url' => $url->toString(),
$form["next_minor_$next_minor_release_count"] = $this->createReleaseTable(
$release,
$installed_minor_release ? $this->t('Minor update') : $release_status,
$this->t('Latest version of Drupal @major.@minor (next minor) (<a href=":url">Release notes</a>):', [
'@major' => $release_version->getMajorVersion(),
'@minor' => $release_version->getMinorVersion(),
':url' => $next_minor_first_release->getReleaseUrl(),
]),
'#prefix' => '<p>',
'#suffix' => '</p>',
];
$installed_minor_release ? 'update-optional' : $type,
$create_update_buttons,
$is_primary
);
}
$form['next_minor'] = $this->createReleaseTable(
$next_minor_release,
$installed_minor_release ? $this->t('Minor update') : $release_status,
$this->t('Latest version of Drupal @major.@minor (next minor) (<a href=":url">Release notes</a>):', [
'@major' => $next_minor_version->getMajorVersion(),
'@minor' => $next_minor_version->getMinorVersion(),
':url' => $next_minor_first_release->getReleaseUrl(),
]),
$installed_minor_release ? 'update-optional' : $type,
$create_update_buttons,
$is_primary
);
}
$form['backup'] = [
......
......@@ -75,7 +75,7 @@ final class ReleaseChooser {
* @throws \InvalidArgumentException
* If the given semantic version number does not contain a patch version.
*/
protected function getMostRecentReleaseInMinor(Updater $updater, string $version): ?ProjectRelease {
public function getMostRecentReleaseInMinor(Updater $updater, string $version): ?ProjectRelease {
if (static::getPatchVersion($version) === NULL) {
throw new \InvalidArgumentException("The version number $version does not contain a patch version");
}
......
......@@ -130,11 +130,11 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase {
$assert_session = $this->assertSession();
$assert_minor_update_help = function () use ($assert_session): void {
$assert_session->pageTextContains('The following updates are in the next minor version of Drupal. Learn more about updating to another minor version.');
$assert_session->pageTextContainsOnce('The following updates are in newer minor version of Drupal. Learn more about updating to another minor version.');
$assert_session->linkExists('Learn more about updating to another minor version.');
};
$assert_no_minor_update_help = function () use ($assert_session): void {
$assert_session->pageTextNotContains('The following updates are in the next minor version of Drupal. Learn more about updating to another minor version.');
$assert_session->pageTextNotContains('The following updates are in newer minor version of Drupal. Learn more about updating to another minor version.');
};
$page = $this->getSession()->getPage();
......@@ -158,7 +158,7 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase {
// Check the form when there is an update in the installed minor only.
$assert_session->pageTextContainsOnce('Currently installed: 9.8.0 (Security update required!)');
$this->checkReleaseTable('#edit-installed-minor', '.update-update-security', '9.8.1', TRUE, 'Latest version of Drupal 9.8 (currently installed):');
$assert_session->elementNotExists('css', '#edit-next-minor');
$assert_session->elementNotExists('css', '#edit-next-minor-1');
$assert_no_minor_update_help();
// Check the form when there is an update in the next minor only.
......@@ -166,9 +166,9 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase {
$this->setCoreVersion('9.7.0');
$page->clickLink('Check manually');
$this->checkForMetaRefresh();
$this->checkReleaseTable('#edit-next-minor', '.update-update-recommended', '9.8.1', TRUE, 'Latest version of Drupal 9.8 (next minor) (Release notes):');
$this->checkReleaseTable('#edit-next-minor-1', '.update-update-recommended', '9.8.1', TRUE, 'Latest version of Drupal 9.8 (next minor) (Release notes):');
$assert_minor_update_help();
$this->assertReleaseNotesLink(9, 8);
$this->assertReleaseNotesLink(9, 8, '#edit-next-minor-1');
$assert_session->pageTextContainsOnce('Currently installed: 9.7.0 (Not supported!)');
$assert_session->elementNotExists('css', '#edit-installed-minor');
......@@ -180,7 +180,7 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase {
$this->checkForMetaRefresh();
$assert_session->pageTextContainsOnce('Currently installed: 9.7.0 (Update available)');
$this->checkReleaseTable('#edit-installed-minor', '.update-update-recommended', '9.7.1', TRUE, 'Latest version of Drupal 9.7 (currently installed):');
$assert_session->elementNotExists('css', '#edit-next-minor');
$assert_session->elementNotExists('css', '#edit-next-minor-1');
$assert_no_minor_update_help();
// Check that if minor updates are enabled the update in the next minor will
......@@ -188,8 +188,8 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase {
$this->config('automatic_updates.settings')->set('allow_core_minor_updates', TRUE)->save();
$this->getSession()->reload();
$this->checkReleaseTable('#edit-installed-minor', '.update-update-recommended', '9.7.1', TRUE, 'Latest version of Drupal 9.7 (currently installed):');
$this->checkReleaseTable('#edit-next-minor', '.update-update-optional', '9.8.2', FALSE, 'Latest version of Drupal 9.8 (next minor) (Release notes):');
$this->assertReleaseNotesLink(9, 8);
$this->checkReleaseTable('#edit-next-minor-1', '.update-update-optional', '9.8.2', FALSE, 'Latest version of Drupal 9.8 (next minor) (Release notes):');
$this->assertReleaseNotesLink(9, 8, '#edit-next-minor-1');
$assert_minor_update_help();
$this->setCoreVersion('9.7.1');
......@@ -197,8 +197,39 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase {
$this->checkForMetaRefresh();
$assert_session->pageTextContainsOnce('Currently installed: 9.7.1 (Update available)');
$assert_session->elementNotExists('css', '#edit-installed-minor');
$this->checkReleaseTable('#edit-next-minor', '.update-update-recommended', '9.8.2', FALSE, 'Latest version of Drupal 9.8 (next minor) (Release notes):');
$this->assertReleaseNotesLink(9, 8);
$this->checkReleaseTable('#edit-next-minor-1', '.update-update-recommended', '9.8.2', FALSE, 'Latest version of Drupal 9.8 (next minor) (Release notes):');
$this->assertReleaseNotesLink(9, 8, '#edit-next-minor-1');
$assert_minor_update_help();
// Check that if minor updates are enabled then updates in the next minors
// are visible.
$this->config('automatic_updates.settings')->set('allow_core_minor_updates', TRUE)->save();
$this->setReleaseMetadata(__DIR__ . '/../../../package_manager/tests/fixtures/release-history/drupal.10.0.0.xml');
$this->setCoreVersion('9.5.0');
$page->clickLink('Check manually');
$this->checkForMetaRefresh();
$assert_session->pageTextNotContains('10.0.0');
$assert_session->pageTextContainsOnce('Currently installed: 9.5.0 (Update available)');
$this->checkReleaseTable('#edit-installed-minor', '.update-update-recommended', '9.5.1', TRUE, 'Latest version of Drupal 9.5 (currently installed):');
$this->checkReleaseTable('#edit-next-minor-1', '.update-update-optional', '9.6.1', FALSE, 'Latest version of Drupal 9.6 (next minor) (Release notes):');
$this->assertReleaseNotesLink(9, 6, '#edit-next-minor-1');
$this->checkReleaseTable('#edit-next-minor-2', '.update-update-optional', '9.7.2', FALSE, 'Latest version of Drupal 9.7 (next minor) (Release notes):');
$this->assertReleaseNotesLink(9, 7, '#edit-next-minor-2');
$assert_minor_update_help();
// Check that if installed version is unsupported and minor updates are
// enabled then updates in the next minors are visible.
$this->setCoreVersion('9.4.0');
$page->clickLink('Check manually');
$this->checkForMetaRefresh();
$assert_session->pageTextNotContains('10.0.0');
$assert_session->pageTextContainsOnce('Currently installed: 9.4.0 (Not supported!)');
$this->checkReleaseTable('#edit-next-minor-1', '.update-update-recommended', '9.5.1', TRUE, 'Latest version of Drupal 9.5 (next minor) (Release notes):');
$this->assertReleaseNotesLink(9, 5, '#edit-next-minor-1');
$this->checkReleaseTable('#edit-next-minor-2', '.update-update-recommended', '9.6.1', FALSE, 'Latest version of Drupal 9.6 (next minor) (Release notes):');
$this->assertReleaseNotesLink(9, 6, '#edit-next-minor-2');
$this->checkReleaseTable('#edit-next-minor-3', '.update-update-recommended', '9.7.2', FALSE, 'Latest version of Drupal 9.7 (next minor) (Release notes):');
$this->assertReleaseNotesLink(9, 7, '#edit-next-minor-3');
$assert_minor_update_help();
$this->assertUpdateStagedTimes(0);
......@@ -898,10 +929,12 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase {
* Major version of next minor release.
* @param int $minor
* Minor version of next minor release.
* @param string $selector
* The selector.
*/
private function assertReleaseNotesLink(int $major, int $minor): void {
private function assertReleaseNotesLink(int $major, int $minor, string $selector): void {
$assert_session = $this->assertSession();
$row = $assert_session->elementExists('css', '#edit-next-minor');
$row = $assert_session->elementExists('css', $selector);
$link_href = $assert_session->elementExists('named', ['link', 'Release notes'], $row)->getAttribute('href');
$this->assertSame('http://example.com/drupal-' . $major . '-' . $minor . '-0-release', $link_href);
}
......
......@@ -2,6 +2,7 @@
namespace Drupal\Tests\automatic_updates\Kernel;
use Drupal\Core\Extension\ExtensionVersion;
use Drupal\update\ProjectRelease;
/**
......@@ -140,6 +141,7 @@ class ReleaseChooserTest extends AutomaticUpdatesKernelTestBase {
*
* @covers ::getLatestInInstalledMinor
* @covers ::getLatestInNextMinor
* @covers ::getMostRecentReleaseInMinor
*/
public function testReleases(string $updater_service, bool $minor_support, string $installed_version, ?string $current_minor, ?string $next_minor): void {
$this->setCoreVersion($installed_version);
......@@ -150,6 +152,14 @@ class ReleaseChooserTest extends AutomaticUpdatesKernelTestBase {
$updater = $this->container->get($updater_service);
$this->assertReleaseVersion($current_minor, $chooser->getLatestInInstalledMinor($updater));
$this->assertReleaseVersion($next_minor, $chooser->getLatestInNextMinor($updater));
$this->assertReleaseVersion($current_minor, $chooser->getMostRecentReleaseInMinor($updater, $this->getRelativeVersion($installed_version, 0)));
$next_minor_version = $this->getRelativeVersion($installed_version, 1);
$this->assertReleaseVersion($next_minor, $chooser->getMostRecentReleaseInMinor($updater, $next_minor_version));
$previous_minor_version = $this->getRelativeVersion($installed_version, -1);
// The chooser should never return a release for a minor before the
// currently installed version.
$this->assertReleaseVersion(NULL, $chooser->getMostRecentReleaseInMinor($updater, $previous_minor_version));
}
/**
......@@ -170,4 +180,20 @@ class ReleaseChooserTest extends AutomaticUpdatesKernelTestBase {
}
}
/**
* Gets a version number in a minor version relative to another version.
*
* @param string $version
* The version string.
* @param int $minor_offset
* The minor offset.
*
* @return string
* The first patch release in a minor relative to the version string.
*/
private function getRelativeVersion(string $version, int $minor_offset): string {
$installed_version_object = ExtensionVersion::createFromVersionString($version);
return $installed_version_object->getMajorVersion() . '.' . (((int) $installed_version_object->getMinorVersion()) + $minor_offset) . '.0';
}
}