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 (2)
Showing
with 476 additions and 102 deletions
......@@ -30,7 +30,7 @@ function automatic_updates_requirements($phase) {
// Check that site has cron updates enabled or not.
// @todo Remove in https://www.drupal.org/project/automatic_updates/issues/3284443
if (\Drupal::configFactory()->get('automatic_updates.settings')->get('cron') !== CronUpdateStage::DISABLED) {
if (\Drupal::configFactory()->get('automatic_updates.settings')->get('unattended.level') !== CronUpdateStage::DISABLED) {
$requirements['automatic_updates_cron'] = [
'title' => t('Cron installs updates automatically'),
'severity' => SystemManager::REQUIREMENT_WARNING,
......
......@@ -9,6 +9,7 @@ declare(strict_types = 1);
use Drupal\automatic_updates\BatchProcessor;
use Drupal\automatic_updates\CronUpdateStage;
use Drupal\automatic_updates\Validator\AutomatedCronDisabledValidator;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\automatic_updates\Validation\AdminStatusCheckMessages;
use Drupal\Core\Url;
......@@ -165,7 +166,22 @@ function automatic_updates_module_implements_alter(&$implementations, $hook) {
function automatic_updates_cron() {
// @todo Refactor this after https://www.drupal.org/project/drupal/issues/2538292
// @todo Remove this after https://www.drupal.org/project/drupal/issues/3318964
if (defined('MAINTENANCE_MODE') || stripos($_SERVER['PHP_SELF'], 'update.php') !== FALSE) {
// We don't want to run status checks if we're on the command line, because
// if unattended updates are configured to run via the web, running status
// checks on the command line could cause invalid results to get cached.
if (defined('MAINTENANCE_MODE') || stripos($_SERVER['PHP_SELF'], 'update.php') !== FALSE || CronUpdateStage::isCommandLine()) {
return;
}
/** @var \Drupal\automatic_updates\Validator\AutomatedCronDisabledValidator $automated_cron_validator */
$automated_cron_validator = \Drupal::service(AutomatedCronDisabledValidator::class);
if ($automated_cron_validator->hasTerminateBeenCalled()) {
// Running updates and status checks will not work during kernel
// termination.
\Drupal::logger('automatic_updates')
->info('Unattended automatic updates were triggered by Automated Cron, which is not supported. No update was performed. See the <a href=":url">status report</a> for more information.', [
':url' => Url::fromRoute('system.status')->toString(),
]);
return;
}
......
......@@ -67,6 +67,9 @@ services:
$lock: '@lock'
tags:
- { name: event_subscriber }
Drupal\automatic_updates\Validator\AutomatedCronDisabledValidator:
tags:
- { name: event_subscriber }
automatic_updates.validator.staged_database_updates:
class: Drupal\automatic_updates\Validator\StagedDatabaseUpdateValidator
tags:
......
cron: disable
unattended:
method: web
level: disable
allow_core_minor_updates: false
status_check_mail: errors_only
......@@ -2,9 +2,22 @@ automatic_updates.settings:
type: config_object
label: 'Automatic Updates settings'
mapping:
cron:
type: string
label: 'Enable automatic updates during cron'
unattended:
type: mapping
label: 'Settings for unattended update'
mapping:
method:
type: string
label: 'Method of running unattended updates'
constraints:
NotNull: []
Choice: [console, web]
level:
type: string
label: 'Which level of unattended updates to perform'
constraints:
NotNull: []
Choice: [disable, security, patch]
cron_port:
type: integer
label: 'Port to use for finalization sub-request'
......
......@@ -5,6 +5,9 @@ declare(strict_types = 1);
namespace Drupal\automatic_updates\Commands;
use Drupal\automatic_updates\DrushUpdateStage;
use Drupal\automatic_updates\StatusCheckMailer;
use Drupal\automatic_updates\Validation\StatusChecker;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drush\Commands\DrushCommands;
/**
......@@ -22,8 +25,19 @@ final class AutomaticUpdatesCommands extends DrushCommands {
*
* @param \Drupal\automatic_updates\DrushUpdateStage $stage
* The console cron updater service.
* @param \Drupal\automatic_updates\Validation\StatusChecker $statusChecker
* The status checker service.
* @param \Drupal\automatic_updates\StatusCheckMailer $statusCheckMailer
* The status check mailer service.
* @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory
* The config factory service.
*/
public function __construct(private readonly DrushUpdateStage $stage) {
public function __construct(
private readonly DrushUpdateStage $stage,
private readonly StatusChecker $statusChecker,
private readonly StatusCheckMailer $statusCheckMailer,
private readonly ConfigFactoryInterface $configFactory,
) {
parent::__construct();
}
......@@ -60,6 +74,7 @@ final class AutomaticUpdatesCommands extends DrushCommands {
$io->info('Running post-apply tasks and final clean-up...');
$this->stage->handlePostApply($options['stage-id'], $options['from-version'], $options['to-version']);
$this->runStatusChecks();
}
else {
if ($this->stage->getMode() === DrushUpdateStage::DISABLED) {
......@@ -75,8 +90,24 @@ final class AutomaticUpdatesCommands extends DrushCommands {
}
else {
$io->info("There is no Drupal core update available.");
$this->runStatusChecks();
}
}
}
/**
* Runs status checks, and sends failure notifications if necessary.
*/
private function runStatusChecks(): void {
$method = $this->configFactory->get('automatic_updates.settings')
->get('unattended.method');
// To ensure consistent results, only run the status checks if we're
// explicitly configured to do unattended updates on the command line.
if ($method === 'console') {
$last_results = $this->statusChecker->getResults();
$this->statusCheckMailer->sendFailureNotifications($last_results, $this->statusChecker->run()->getResults());
}
}
}
......@@ -40,6 +40,13 @@ use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
*/
class CronUpdateStage extends UpdateStage implements CronInterface {
/**
* The current interface between PHP and the server.
*
* @var string
*/
private static $serverApi = PHP_SAPI;
/**
* All automatic updates are disabled.
*
......@@ -121,6 +128,16 @@ class CronUpdateStage extends UpdateStage implements CronInterface {
parent::__construct($composerInspector, $pathLocator, $beginner, $stager, $committer, $fileSystem, $eventDispatcher, $tempStoreFactory, $time, $pathFactory, $failureMarker);
}
/**
* Indicates if we are currently running at the command line.
*
* @return bool
* TRUE if we are running at the command line, otherwise FALSE.
*/
final public static function isCommandLine(): bool {
return self::$serverApi === 'cli';
}
/**
* Handles updates during cron.
*
......@@ -392,7 +409,7 @@ class CronUpdateStage extends UpdateStage implements CronInterface {
* allowed during cron.
*/
final public function getMode(): string {
$mode = $this->configFactory->get('automatic_updates.settings')->get('cron');
$mode = $this->configFactory->get('automatic_updates.settings')->get('unattended.level');
return $mode ?: static::SECURITY;
}
......@@ -400,7 +417,14 @@ class CronUpdateStage extends UpdateStage implements CronInterface {
* {@inheritdoc}
*/
public function run() {
if ($this->handleCron()) {
$method = $this->configFactory->get('automatic_updates.settings')
->get('unattended.method');
// If we are configured to run updates via the web, and we're actually being
// accessed via the web (i.e., anything that isn't the command line), go
// ahead and try to do the update. In all other circumstances, just run the
// normal cron handler.
if ($method === 'web' && !self::isCommandLine() && $this->handleCron()) {
return TRUE;
}
return $this->inner->run();
......
......@@ -5,6 +5,7 @@ declare(strict_types = 1);
namespace Drupal\automatic_updates\Validation;
use Drupal\automatic_updates\CronUpdateStage;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\Messenger\MessengerTrait;
......@@ -49,6 +50,8 @@ final class AdminStatusCheckMessages implements ContainerInjectionInterface {
* The cron update stage service.
* @param \Drupal\Core\Render\RendererInterface $renderer
* The renderer service.
* @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory
* The config factory service.
*/
public function __construct(
private readonly StatusChecker $statusChecker,
......@@ -56,7 +59,8 @@ final class AdminStatusCheckMessages implements ContainerInjectionInterface {
private readonly AccountProxyInterface $currentUser,
private readonly CurrentRouteMatch $currentRouteMatch,
private readonly CronUpdateStage $stage,
private readonly RendererInterface $renderer
private readonly RendererInterface $renderer,
private readonly ConfigFactoryInterface $configFactory
) {}
/**
......@@ -69,7 +73,8 @@ final class AdminStatusCheckMessages implements ContainerInjectionInterface {
$container->get('current_user'),
$container->get('current_route_match'),
$container->get('automatic_updates.cron_update_stage'),
$container->get('renderer')
$container->get('renderer'),
$container->get('config.factory')
);
}
......@@ -81,12 +86,21 @@ final class AdminStatusCheckMessages implements ContainerInjectionInterface {
return;
}
if ($this->statusChecker->getResults() === NULL) {
$method = $this->configFactory->get('automatic_updates.settings')
->get('unattended.method');
$checker_url = Url::fromRoute('automatic_updates.status_check')->setOption('query', $this->getDestinationArray());
if ($checker_url->access()) {
if ($method === 'web' && $checker_url->access()) {
$this->messenger()->addError($this->t('Your site has not recently run an update readiness check. <a href=":url">Rerun readiness checks now.</a>', [
':url' => $checker_url->toString(),
]));
}
elseif ($method === 'console') {
// @todo Link to the documentation on how to set up unattended updates
// via the terminal in https://drupal.org/i/3362695.
$message = $this->t('Unattended updates are configured to run via the console, but not appear to have run recently.');
$this->messenger()->addError($message);
}
}
else {
// Display errors, if there are any. If there aren't, then display
......
......@@ -4,6 +4,7 @@ declare(strict_types = 1);
namespace Drupal\automatic_updates\Validation;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Datetime\DateFormatterInterface;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
......@@ -33,10 +34,13 @@ final class StatusCheckRequirements implements ContainerInjectionInterface {
* The status checker service.
* @param \Drupal\Core\Datetime\DateFormatterInterface $dateFormatter
* The date formatter service.
* @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory
* The config factory service.
*/
public function __construct(
private readonly StatusChecker $statusChecker,
private readonly DateFormatterInterface $dateFormatter
private readonly DateFormatterInterface $dateFormatter,
private readonly ConfigFactoryInterface $configFactory,
) {}
/**
......@@ -45,10 +49,23 @@ final class StatusCheckRequirements implements ContainerInjectionInterface {
public static function create(ContainerInterface $container): self {
return new static(
$container->get('automatic_updates.status_checker'),
$container->get('date.formatter')
$container->get('date.formatter'),
$container->get('config.factory'),
);
}
/**
* Returns the method used to run unattended updates.
*
* @return string
* The method used to run unattended updates. Will be either 'console' or
* 'web'.
*/
private function getMethod(): string {
return $this->configFactory->get('automatic_updates.settings')
->get('unattended.method');
}
/**
* Gets requirements arrays as specified in hook_requirements().
*
......@@ -56,8 +73,26 @@ final class StatusCheckRequirements implements ContainerInjectionInterface {
* Requirements arrays as specified by hook_requirements().
*/
public function getRequirements(): array {
$results = $this->statusChecker->run()->getResults();
$requirements = [];
$results = $this->statusChecker->getResults();
// If unattended updates are run on the terminal, we don't want to do the
// status check right now, since running them over the web may yield
// inaccurate or irrelevant results. The console command runs status checks,
// so if there are no results, we can assume it has not been run in a while,
// and raise an error about that.
if (is_null($results) && $this->getMethod() === 'console') {
$requirements['automatic_updates_status_check_console_command_not_run'] = [
'title' => $this->t('Update readiness checks'),
'severity' => SystemManager::REQUIREMENT_ERROR,
// @todo Link to the documentation on how to set up unattended updates
// via the terminal in https://drupal.org/i/3362695.
'value' => $this->t('Unattended updates are configured to run via the console, but do not appear to have run recently.'),
];
return $requirements;
}
$results ??= $this->statusChecker->run()->getResults();
if (empty($results)) {
$requirements['automatic_updates_status_check'] = [
'title' => $this->t('Update readiness checks'),
......@@ -144,6 +179,11 @@ final class StatusCheckRequirements implements ContainerInjectionInterface {
* NULL.
*/
protected function createRunLink(): ?TranslatableMarkup {
// Only show this link if unattended updates are being run over the web.
if ($this->getMethod() !== 'web') {
return NULL;
}
$status_check_url = Url::fromRoute('automatic_updates.status_check');
if ($status_check_url->access()) {
return $this->t(
......
......@@ -154,13 +154,15 @@ final class StatusChecker implements EventSubscriberInterface {
$this->clearStoredResults();
}
elseif ($config->getName() === 'automatic_updates.settings') {
// If anything about how we run unattended updates has changed, clear the
// stored results, since they can be affected by these settings.
if ($event->isChanged('unattended')) {
$this->clearStoredResults();
}
// We only send status check failure notifications if unattended updates
// are enabled. If notifications were previously disabled but have been
// re-enabled, or their sensitivity level has changed, clear the stored
// results so that we'll send accurate notifications next time cron runs.
if ($event->isChanged('cron') && $config->getOriginal('cron') === CronUpdateStage::DISABLED) {
$this->clearStoredResults();
}
elseif ($event->isChanged('status_check_mail') && $config->get('status_check_mail') !== StatusCheckMailer::DISABLED) {
$this->clearStoredResults();
}
......
<?php
declare(strict_types = 1);
namespace Drupal\automatic_updates\Validator;
use Drupal\automatic_updates\CronUpdateStage;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\package_manager\Event\StatusCheckEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\KernelEvents;
/**
* Ensures that updates cannot be triggered by Automated Cron.
*
* @internal
* This is an internal part of Automatic Updates and may be changed or removed
* at any time without warning. External code should not interact with this
* class.
*/
final class AutomatedCronDisabledValidator implements EventSubscriberInterface {
use StringTranslationTrait;
/**
* Flags whether the KernelEvents::TERMINATE event has been dispatched.
*
* @var bool
*/
private bool $terminateCalled = FALSE;
/**
* AutomatedCronDisabledValidator constructor.
*
* @param \Drupal\Core\Extension\ModuleHandlerInterface $moduleHandler
* The module handler.
*/
public function __construct(
private readonly ModuleHandlerInterface $moduleHandler,
) {}
/**
* Checks that Automated Cron is not going to trigger unattended updates.
*
* @param \Drupal\package_manager\Event\StatusCheckEvent $event
* The event being handled.
*/
public function validateStatusCheck(StatusCheckEvent $event): void {
if ($event->stage instanceof CronUpdateStage && $this->moduleHandler->moduleExists('automated_cron')) {
$event->addWarning([
$this->t('This site has the Automated Cron module installed. To use unattended automatic updates, please configure cron manually on your hosting environment. The Automatic Updates module will not do anything if it is triggered by Automated Cron. See the <a href=":url">Automated Cron documentation</a> for information.', [
':url' => 'https://www.drupal.org/docs/administering-a-drupal-site/cron-automated-tasks/cron-automated-tasks-overview#s-more-reliable-enable-cron-using-external-trigger',
]),
]);
}
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents(): array {
return [
StatusCheckEvent::class => 'validateStatusCheck',
// Ensure this runs before
// \Drupal\automated_cron\EventSubscriber\AutomatedCron::onTerminate().
KernelEvents::TERMINATE => ['setTerminateCalled', PHP_INT_MAX],
];
}
/**
* Sets a flag is when the kernel terminates.
*/
public function setTerminateCalled(): void {
$this->terminateCalled = TRUE;
}
/**
* Determines whether the kernel has terminated.
*
* @return bool
* TRUE if the kernel has terminated (i.e., KernelEvents::TERMINATE has been
* handled), otherwise FALSE.
*/
public function hasTerminateBeenCalled(): bool {
return $this->terminateCalled;
}
}
......@@ -7,11 +7,9 @@ namespace Drupal\automatic_updates\Validator;
use Drupal\automatic_updates\CronUpdateStage;
use Drupal\Component\Datetime\TimeInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Lock\LockBackendInterface;
use Drupal\Core\State\StateInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\Url;
use Drupal\package_manager\Event\StatusCheckEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
......@@ -23,7 +21,7 @@ use Symfony\Component\EventDispatcher\EventSubscriberInterface;
* at any time without warning. External code should not interact with this
* class.
*/
class CronFrequencyValidator implements EventSubscriberInterface {
final class CronFrequencyValidator implements EventSubscriberInterface {
use StringTranslationTrait;
......@@ -59,8 +57,6 @@ class CronFrequencyValidator implements EventSubscriberInterface {
*
* @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory
* The config factory service.
* @param \Drupal\Core\Extension\ModuleHandlerInterface $moduleHandler
* The module handler.
* @param \Drupal\Core\State\StateInterface $state
* The state service.
* @param \Drupal\Component\Datetime\TimeInterface $time
......@@ -70,19 +66,18 @@ class CronFrequencyValidator implements EventSubscriberInterface {
*/
public function __construct(
private readonly ConfigFactoryInterface $configFactory,
private readonly ModuleHandlerInterface $moduleHandler,
private readonly StateInterface $state,
private readonly TimeInterface $time,
private readonly LockBackendInterface $lock,
) {}
/**
* Validates that cron runs frequently enough to perform automatic updates.
* Validates the cron frequency according to the last cron run time.
*
* @param \Drupal\package_manager\Event\StatusCheckEvent $event
* The event object.
*/
public function checkCronFrequency(StatusCheckEvent $event): void {
public function validateLastCronRun(StatusCheckEvent $event): void {
// We only want to do this check if the stage belongs to Automatic Updates.
if (!$event->stage instanceof CronUpdateStage) {
return;
......@@ -92,43 +87,6 @@ class CronFrequencyValidator implements EventSubscriberInterface {
if ($event->stage->getMode() === CronUpdateStage::DISABLED) {
return;
}
elseif ($this->moduleHandler->moduleExists('automated_cron')) {
$this->validateAutomatedCron($event);
}
else {
$this->validateLastCronRun($event);
}
}
/**
* Validates the cron frequency according to Automated Cron settings.
*
* @param \Drupal\package_manager\Event\StatusCheckEvent $event
* The event object.
*/
protected function validateAutomatedCron(StatusCheckEvent $event): void {
$message = $this->t('Cron is not set to run frequently enough. <a href=":configure">Configure it</a> to run at least every @frequency hours or disable automated cron and run it via an external scheduling system.', [
':configure' => Url::fromRoute('system.cron_settings')->toString(),
'@frequency' => static::SUGGESTED_INTERVAL,
]);
$interval = $this->configFactory->get('automated_cron.settings')->get('interval');
if ($interval > static::ERROR_INTERVAL) {
$event->addError([$message]);
}
elseif ($interval > static::WARNING_INTERVAL) {
$event->addWarning([$message]);
}
}
/**
* Validates the cron frequency according to the last cron run time.
*
* @param \Drupal\package_manager\Event\StatusCheckEvent $event
* The event object.
*/
protected function validateLastCronRun(StatusCheckEvent $event): void {
// If cron is running right now, cron is clearly being run recently enough!
if (!$this->lock->lockMayBeAvailable('cron')) {
return;
......@@ -152,7 +110,7 @@ class CronFrequencyValidator implements EventSubscriberInterface {
*/
public static function getSubscribedEvents(): array {
return [
StatusCheckEvent::class => 'checkCronFrequency',
StatusCheckEvent::class => 'validateLastCronRun',
];
}
......
......@@ -37,7 +37,7 @@ function automatic_updates_test_cron_form_update_settings_alter(array &$form, Fo
CronUpdateStage::ALL => t('All supported updates'),
CronUpdateStage::SECURITY => t('Security updates only'),
],
'#default_value' => \Drupal::config('automatic_updates.settings')->get('cron'),
'#default_value' => \Drupal::config('automatic_updates.settings')->get('unattended.level'),
'#description' => t(
'If enabled, Drupal core will be automatically updated when an update is available. Automatic updates are only supported for @current_minor.x versions of Drupal core. Drupal @current_minor will receive security updates until @supported_until_version is released.',
[
......@@ -58,6 +58,6 @@ function automatic_updates_test_cron_form_update_settings_alter(array &$form, Fo
function _automatic_updates_test_cron_update_settings_form_submit(array &$form, FormStateInterface $form_state) {
\Drupal::configFactory()
->getEditable('automatic_updates.settings')
->set('cron', $form_state->getValue('automatic_updates_cron'))
->set('unattended.level', $form_state->getValue('automatic_updates_cron'))
->save();
}
......@@ -21,7 +21,7 @@ abstract class UpdateTestBase extends TemplateProjectTestBase {
parent::createTestProject($template);
// @todo Remove in https://www.drupal.org/project/automatic_updates/issues/3284443
$code = <<<END
\$config['automatic_updates.settings']['cron'] = 'security';
\$config['automatic_updates.settings']['unattended']['level'] = 'security';
END;
$this->writeSettings($code);
// Install Automatic Updates, and other modules needed for testing.
......@@ -69,6 +69,7 @@ END;
$this->visit('/admin/reports/status');
$mink = $this->getMink();
$page = $mink->getSession()->getPage();
$page->clickLink('Rerun readiness checks');
$readiness_check_summaries = $page->findAll('css', 'summary:contains("Update readiness checks")');
// There should always either be the summary section indicating the site is
......
<?php
namespace Drupal\Tests\automatic_updates\Functional;
use Drupal\automatic_updates\CronUpdateStage;
/**
* Tests that updates are not run by Automated Cron.
*
* @covers \Drupal\automatic_updates\Validator\AutomatedCronDisabledValidator
* @group automatic_updates
*/
class AutomatedCronDisabledValidatorTest extends AutomaticUpdatesFunctionalTestBase {
/**
* {@inheritdoc}
*/
protected $defaultTheme = 'stark';
/**
* {@inheritdoc}
*/
protected static $modules = ['dblog', 'automated_cron'];
/**
* {@inheritdoc}
*/
protected function setUp(): void {
parent::setUp();
$this->drupalLogin($this->createUser(['access site reports']));
}
/**
* Tests that automatic updates are not triggered by Automated Cron.
*/
public function testAutomatedCronUpdate() {
// Delete the last cron run time, to ensure that Automated Cron will run.
$this->container->get('state')->delete('system.cron_last');
$this->config('automatic_updates.settings')
->set('unattended.level', CronUpdateStage::ALL)
->save();
$this->drupalGet('user');
// The `drupalGet()` will not wait for the HTTP kernel to terminate (i.e.,
// the `KernelEvents::TERMINATE` event) to complete. Although this event
// will likely already be completed, wait 1 second to avoid random test
// failures.
sleep(1);
$this->drupalGet('admin/reports/dblog');
$this->assertSession()->elementAttributeContains('css', 'a[title^="Unattended"]', 'title', 'Unattended automatic updates were triggered by Automated Cron, which is not supported. No update was performed. See the status report for more information.');
}
}
......@@ -39,7 +39,9 @@ abstract class AutomaticUpdatesFunctionalTestBase extends BrowserTestBase {
parent::setUp();
$this->useFixtureDirectoryAsActive(__DIR__ . '/../../../package_manager/tests/fixtures/fake_site');
// @todo Remove in https://www.drupal.org/project/automatic_updates/issues/3284443
$this->config('automatic_updates.settings')->set('cron', CronUpdateStage::SECURITY)->save();
$this->config('automatic_updates.settings')
->set('unattended.level', CronUpdateStage::SECURITY)
->save();
}
/**
......
......@@ -127,11 +127,7 @@ class StatusCheckTest extends AutomaticUpdatesFunctionalTestBase {
*/
public function testStatusChecksOnStatusReport(): void {
$assert = $this->assertSession();
// Ensure automated_cron is disabled before installing automatic_updates.
// This ensures we are testing that automatic_updates runs the checkers when
// the module itself is installed and they weren't run on cron.
$this->assertFalse($this->container->get('module_handler')->moduleExists('automated_cron'));
$page = $this->getSession()->getPage();
$this->container->get('module_installer')->install(['automatic_updates', 'automatic_updates_test']);
// If the site is ready for updates, the users will see the same output
......@@ -186,49 +182,50 @@ class StatusCheckTest extends AutomaticUpdatesFunctionalTestBase {
$this->drupalGet('admin/reports/status');
$this->assertErrors($expected_results);
$this->drupalLogin($this->checkerRunnerUser);
$this->drupalGet('/admin/reports/status');
$expected_results = [
'error' => $this->createValidationResult(SystemManager::REQUIREMENT_ERROR),
'warning' => $this->createValidationResult(SystemManager::REQUIREMENT_WARNING),
];
TestSubscriber1::setTestResult($expected_results, StatusCheckEvent::class);
// Confirm a new message is displayed if the page is reloaded.
$this->getSession()->reload();
// On the status page, we should see the summaries and messages, even if
// there is only 1 message.
$this->assertErrors([$expected_results['error']]);
$this->assertWarnings([$expected_results['warning']]);
$page->clickLink('Rerun readiness checks');
// We should see the summaries and messages, even if there's only 1 message.
$this->assertErrors([$expected_results['error']], TRUE);
$this->assertWarnings([$expected_results['warning']], TRUE);
// If there's a result with only one message, but no summary, ensure that
// message is displayed.
$result = ValidationResult::createError([t('A lone message, with no summary.')]);
TestSubscriber1::setTestResult([$result], StatusCheckEvent::class);
$this->getSession()->reload();
$this->assertErrors([$result]);
$page->clickLink('Rerun readiness checks');
$this->assertErrors([$result], TRUE);
$expected_results = [
'error' => $this->createValidationResult(SystemManager::REQUIREMENT_ERROR, 2),
'warning' => $this->createValidationResult(SystemManager::REQUIREMENT_WARNING, 2),
];
TestSubscriber1::setTestResult($expected_results, StatusCheckEvent::class);
$this->getSession()->reload();
// Confirm that both messages and summaries will be displayed on status
// report when there multiple messages.
$this->assertErrors([$expected_results['error']]);
$this->assertWarnings([$expected_results['warning']]);
$page->clickLink('Rerun readiness checks');
// Confirm that both messages and summaries will be displayed when there are
// multiple messages.
$this->assertErrors([$expected_results['error']], TRUE);
$this->assertWarnings([$expected_results['warning']], TRUE);
$expected_results = [$this->createValidationResult(SystemManager::REQUIREMENT_WARNING, 2)];
TestSubscriber1::setTestResult($expected_results, StatusCheckEvent::class);
$this->getSession()->reload();
$page->clickLink('Rerun readiness checks');
$assert->pageTextContainsOnce('Update readiness checks');
// Confirm that warnings will display on the status report if there are no
// errors.
$this->assertWarnings($expected_results);
$this->assertWarnings($expected_results, TRUE);
$expected_results = [$this->createValidationResult(SystemManager::REQUIREMENT_WARNING)];
TestSubscriber1::setTestResult($expected_results, StatusCheckEvent::class);
$this->getSession()->reload();
$page->clickLink('Rerun readiness checks');
$assert->pageTextContainsOnce('Update readiness checks');
$this->assertWarnings($expected_results);
$this->assertWarnings($expected_results, TRUE);
}
/**
......@@ -261,10 +258,6 @@ class StatusCheckTest extends AutomaticUpdatesFunctionalTestBase {
$assert = $this->assertSession();
$messages_section_selector = '[data-drupal-messages]';
// Ensure automated_cron is disabled before installing automatic_updates. This
// ensures we are testing that automatic_updates runs the checkers when the
// module itself is installed and they weren't run on cron.
$this->assertFalse($this->container->get('module_handler')->moduleExists('automated_cron'));
$this->container->get('module_installer')->install(['automatic_updates', 'automatic_updates_test']);
// If site is ready for updates no message will be displayed on admin pages.
......@@ -381,7 +374,9 @@ class StatusCheckTest extends AutomaticUpdatesFunctionalTestBase {
// Confirm status check messages are not displayed when cron updates are
// disabled.
$this->config('automatic_updates.settings')->set('cron', CronUpdateStage::DISABLED)->save();
$this->config('automatic_updates.settings')
->set('unattended.level', CronUpdateStage::DISABLED)
->save();
$this->drupalGet('admin/structure');
$this->checkForMetaRefresh();
$assert->pageTextNotContains(static::$warningsExplanation);
......@@ -403,7 +398,9 @@ class StatusCheckTest extends AutomaticUpdatesFunctionalTestBase {
// the functionality to retrieve our fake release history metadata.
$this->container->get('module_installer')->install(['automatic_updates', 'automatic_updates_test']);
// @todo Remove in https://www.drupal.org/project/automatic_updates/issues/3284443
$this->config('automatic_updates.settings')->set('cron', CronUpdateStage::SECURITY)->save();
$this->config('automatic_updates.settings')
->set('unattended.level', CronUpdateStage::SECURITY)
->save();
$this->drupalGet('admin/reports/status');
$this->assertNoErrors(TRUE);
......@@ -578,6 +575,79 @@ class StatusCheckTest extends AutomaticUpdatesFunctionalTestBase {
$assert_session->pageTextContains($no_results_message);
}
/**
* Tests that the status report shows cached status check results.
*/
public function testStatusReportShowsCachedResults(): void {
$session = $this->getSession();
$this->drupalLogin($this->checkerRunnerUser);
$this->container->get('module_installer')->install([
'automatic_updates',
'automatic_updates_test',
]);
$this->container = $this->container->get('kernel')->getContainer();
// Clear stored results that were collected when the module was installed.
$this->container->get('automatic_updates.status_checker')
->clearStoredResults();
// Flag a validation error, whose summary will be displayed in the messages
// area.
$result = $this->createValidationResult(SystemManager::REQUIREMENT_ERROR);
TestSubscriber1::setTestResult([$result], StatusCheckEvent::class);
$this->drupalGet('/admin/reports/status');
$this->assertErrors([$result], TRUE);
// Clear the result, and ensure that it's still visible because it is
// cached.
TestSubscriber::setTestResult(NULL, StatusCheckEvent::class);
$session->reload();
$this->assertErrors([$result], TRUE);
// If unattended updates are configured to run via the command line, we
// should see a warning that the status checks have not run recently. This
// is because changing the configuration clears the cached results, since
// they may be affected by the change.
// @see \Drupal\automatic_updates\Validation\StatusChecker::onConfigSave()
$this->config('automatic_updates.settings')
->set('unattended.method', 'console')
->save();
$session->reload();
$assert_session = $this->assertSession();
$assert_session->pageTextContainsOnce('Unattended updates are configured to run via the console, but do not appear to have run recently.');
$assert_session->pageTextNotContains((string) $result->messages[0]);
}
/**
* Tests the status checks when unattended updates are run via the console.
*/
public function testUnattendedUpdatesRunFromConsole(): void {
$this->container->get('module_installer')->install(['automatic_updates']);
$this->container = $this->container->get('kernel')->getContainer();
// Clear stored results that were collected when the module was installed.
$this->container->get('automatic_updates.status_checker')
->clearStoredResults();
$this->config('automatic_updates.settings')
->set('unattended.method', 'console')
->save();
// If we visit the status report, we should see an error requirement because
// unattended updates are configured to run via the terminal, and there are
// no stored status check results, which means that the console command has
// probably not run recently (or ever).
$this->drupalGet('/admin/reports/status');
$this->assertRequirement('error', 'Unattended updates are configured to run via the console, but do not appear to have run recently.', [], FALSE);
// We should see a similar message on any other admin page.
$this->drupalGet('/admin/structure');
$this->assertSession()
->statusMessageContains('Unattended updates are configured to run via the console, but not appear to have run recently.', 'error');
}
/**
* Asserts that the status check requirement displays no errors or warnings.
*
......
......@@ -51,7 +51,12 @@ abstract class AutomaticUpdatesKernelTestBase extends PackageManagerKernelTestBa
parent::setUp();
// Enable cron updates, which will eventually be the default.
// @todo Remove in https://www.drupal.org/project/automatic_updates/issues/3284443
$this->config('automatic_updates.settings')->set('cron', CronUpdateStage::SECURITY)->save();
$this->config('automatic_updates.settings')
->set('unattended', [
'method' => 'web',
'level' => CronUpdateStage::SECURITY,
])
->save();
// By default, pretend we're running Drupal core 9.8.0 and a non-security
// update to 9.8.1 is available.
......@@ -62,6 +67,13 @@ abstract class AutomaticUpdatesKernelTestBase extends PackageManagerKernelTestBa
// from a sane state.
// @see \Drupal\automatic_updates\Validator\CronFrequencyValidator
$this->container->get('state')->set('system.cron_last', time());
// Cron updates are not done when running at the command line, so override
// our cron handler's PHP_SAPI constant to a valid value that isn't `cli`.
// The choice of `cgi-fcgi` is arbitrary; see
// https://www.php.net/php_sapi_name for some valid values of PHP_SAPI.
$property = new \ReflectionProperty(CronUpdateStage::class, 'serverApi');
$property->setValue(NULL, 'cgi-fcgi');
}
/**
......
......@@ -156,7 +156,9 @@ class CronUpdateStageTest extends AutomaticUpdatesKernelTestBase {
$this->setReleaseMetadata($release_data);
$this->setCoreVersion('9.8.0');
update_get_available(TRUE);
$this->config('automatic_updates.settings')->set('cron', $setting)->save();
$this->config('automatic_updates.settings')
->set('unattended.level', $setting)
->save();
// Since we're just trying to ensure that all of Package Manager's services
// are called as expected, disable validation by replacing the event
......@@ -260,7 +262,9 @@ class CronUpdateStageTest extends AutomaticUpdatesKernelTestBase {
}
$this->installConfig('automatic_updates');
// @todo Remove in https://www.drupal.org/project/automatic_updates/issues/3284443
$this->config('automatic_updates.settings')->set('cron', CronUpdateStage::SECURITY)->save();
$this->config('automatic_updates.settings')
->set('unattended.level', CronUpdateStage::SECURITY)
->save();
// Ensure that there is a security release to which we should update.
$this->setReleaseMetadata([
'drupal' => __DIR__ . "/../../../package_manager/tests/fixtures/release-history/drupal.9.8.1-security.xml",
......@@ -368,7 +372,9 @@ class CronUpdateStageTest extends AutomaticUpdatesKernelTestBase {
* Tests stage is not destroyed if another update is applying.
*/
public function testStageNotDestroyedIfApplying(): void {
$this->config('automatic_updates.settings')->set('cron', CronUpdateStage::ALL)->save();
$this->config('automatic_updates.settings')
->set('unattended.level', CronUpdateStage::ALL)
->save();
$this->setReleaseMetadata([
'drupal' => __DIR__ . "/../../../package_manager/tests/fixtures/release-history/drupal.9.8.1-security.xml",
]);
......@@ -406,7 +412,9 @@ class CronUpdateStageTest extends AutomaticUpdatesKernelTestBase {
* Tests stage is not destroyed if not available and site is on secure version.
*/
public function testStageNotDestroyedIfSecure(): void {
$this->config('automatic_updates.settings')->set('cron', CronUpdateStage::ALL)->save();
$this->config('automatic_updates.settings')
->set('unattended.level', CronUpdateStage::ALL)
->save();
$this->setReleaseMetadata([
'drupal' => __DIR__ . "/../../../package_manager/tests/fixtures/release-history/drupal.9.8.2.xml",
]);
......@@ -548,7 +556,7 @@ END;
'drupal' => __DIR__ . '/../../../package_manager/tests/fixtures/release-history/drupal.9.8.2.xml',
]);
$this->config('automatic_updates.settings')
->set('cron', CronUpdateStage::ALL)
->set('unattended.level', CronUpdateStage::ALL)
->save();
$error = ValidationResult::createError([
......
<?php
namespace Drupal\Tests\automatic_updates\Kernel;
use Drupal\automatic_updates\Validation\StatusChecker;
/**
* @group automatic_updates
*/
class HookCronTest extends AutomaticUpdatesKernelTestBase {
/**
* {@inheritdoc}
*/
protected static $modules = ['automatic_updates'];
/**
* Tests that our cron hook does not run if we're at the command line.
*/
public function testCronHookBypassedAtCommandLine(): void {
if (PHP_SAPI !== 'cli') {
$this->markTestSkipped('This test requires that PHP be running at the command line.');
}
// The status check should not have run yet.
/** @var \Drupal\automatic_updates\Validation\StatusChecker $status_checker */
$status_checker = $this->container->get(StatusChecker::class);
$this->assertNull($status_checker->getLastRunTime());
// Since we're at the command line, status checks should still not run, even
// if we do run cron.
$this->container->get('cron')->run();
$this->assertNull($status_checker->getResults());
}
}