@@ -581,7 +581,32 @@ impl RustwideBuilder {
581
581
None
582
582
} ;
583
583
584
- let has_examples = build. host_source_dir ( ) . join ( "examples" ) . is_dir ( ) ;
584
+ let mut async_conn = self . runtime . block_on ( self . db . get_async ( ) ) ?;
585
+
586
+ self . runtime . block_on ( finish_build (
587
+ & mut async_conn,
588
+ build_id,
589
+ & res. result . rustc_version ,
590
+ & res. result . docsrs_version ,
591
+ if res. result . successful {
592
+ BuildStatus :: Success
593
+ } else {
594
+ BuildStatus :: Failure
595
+ } ,
596
+ documentation_size,
597
+ None ,
598
+ ) ) ?;
599
+
600
+ {
601
+ let _span = info_span ! ( "store_build_logs" ) . entered ( ) ;
602
+ let build_log_path = format ! ( "build-logs/{build_id}/{default_target}.txt" ) ;
603
+ self . storage . store_one ( build_log_path, res. build_log ) ?;
604
+ for ( target, log) in target_build_logs {
605
+ let build_log_path = format ! ( "build-logs/{build_id}/{target}.txt" ) ;
606
+ self . storage . store_one ( build_log_path, log) ?;
607
+ }
608
+ }
609
+
585
610
if res. result . successful {
586
611
self . metrics . successful_builds . inc ( ) ;
587
612
} else if res. cargo_metadata . root ( ) . is_library ( ) {
@@ -611,8 +636,26 @@ impl RustwideBuilder {
611
636
let cargo_metadata = res. cargo_metadata . root ( ) ;
612
637
let repository = self . get_repo ( cargo_metadata) ?;
613
638
614
- let mut async_conn = self . runtime . block_on ( self . db . get_async ( ) ) ?;
639
+ // when we have an unsuccessful build, but the release was already successfullly
640
+ // built in the past, don't touch the release record so the docs stay intact.
641
+ // This mainly happens with manually triggered or automated rebuilds.
642
+ // The `release_build_status` table is already updated with the information from
643
+ // the current build via `finish_build`.
644
+ let current_release_build_status = self . runtime . block_on ( sqlx:: query_scalar!(
645
+ r#"
646
+ SELECT build_status AS "build_status: BuildStatus"
647
+ FROM release_build_status
648
+ WHERE rid = $1
649
+ "# ,
650
+ release_id. 0 ,
651
+ ) . fetch_optional ( & mut * async_conn) ) ?;
652
+
653
+ if !res. result . successful && current_release_build_status == Some ( BuildStatus :: Success ) {
654
+ info ! ( "build was unsuccessful, but the release was already successfully built in the past. Skipping release record update." ) ;
655
+ return Ok ( false ) ;
656
+ }
615
657
658
+ let has_examples = build. host_source_dir ( ) . join ( "examples" ) . is_dir ( ) ;
616
659
self . runtime . block_on ( finish_release (
617
660
& mut async_conn,
618
661
crate_id,
@@ -639,31 +682,6 @@ impl RustwideBuilder {
639
682
) ) ?;
640
683
}
641
684
642
- let build_status = if res. result . successful {
643
- BuildStatus :: Success
644
- } else {
645
- BuildStatus :: Failure
646
- } ;
647
- self . runtime . block_on ( finish_build (
648
- & mut async_conn,
649
- build_id,
650
- & res. result . rustc_version ,
651
- & res. result . docsrs_version ,
652
- build_status,
653
- documentation_size,
654
- None ,
655
- ) ) ?;
656
-
657
- {
658
- let _span = info_span ! ( "store_build_logs" ) . entered ( ) ;
659
- let build_log_path = format ! ( "build-logs/{build_id}/{default_target}.txt" ) ;
660
- self . storage . store_one ( build_log_path, res. build_log ) ?;
661
- for ( target, log) in target_build_logs {
662
- let build_log_path = format ! ( "build-logs/{build_id}/{target}.txt" ) ;
663
- self . storage . store_one ( build_log_path, log) ?;
664
- }
665
- }
666
-
667
685
// Some crates.io crate data is mutable, so we proactively update it during a release
668
686
if !is_local {
669
687
match self
@@ -1023,8 +1041,12 @@ impl Default for BuildPackageSummary {
1023
1041
1024
1042
#[ cfg( test) ]
1025
1043
mod tests {
1044
+ use std:: iter;
1045
+
1026
1046
use super :: * ;
1027
1047
use crate :: db:: types:: Feature ;
1048
+ use crate :: registry_api:: ReleaseData ;
1049
+ use crate :: storage:: CompressionAlgorithm ;
1028
1050
use crate :: test:: { wrapper, AxumRouterTestExt , TestEnvironment } ;
1029
1051
1030
1052
fn get_features (
@@ -1297,6 +1319,91 @@ mod tests {
1297
1319
} )
1298
1320
}
1299
1321
1322
+ #[ test]
1323
+ #[ ignore]
1324
+ fn test_failed_build_with_existing_successful_release ( ) {
1325
+ wrapper ( |env| {
1326
+ // rand 0.8.5 fails to build with recent nightly versions
1327
+ // https://github.com/rust-lang/docs.rs/issues/26750
1328
+ let crate_ = "rand" ;
1329
+ let version = "0.8.5" ;
1330
+
1331
+ // create a successful release & build in the database
1332
+ let release_id = env. runtime ( ) . block_on ( async {
1333
+ let mut conn = env. async_db ( ) . await . async_conn ( ) . await ;
1334
+ let crate_id = initialize_crate ( & mut conn, crate_) . await ?;
1335
+ let release_id = initialize_release ( & mut conn, crate_id, version) . await ?;
1336
+ let build_id = initialize_build ( & mut conn, release_id) . await ?;
1337
+ finish_build (
1338
+ & mut conn,
1339
+ build_id,
1340
+ "some-version" ,
1341
+ "other-version" ,
1342
+ BuildStatus :: Success ,
1343
+ None ,
1344
+ None ,
1345
+ )
1346
+ . await ?;
1347
+ finish_release (
1348
+ & mut conn,
1349
+ crate_id,
1350
+ release_id,
1351
+ & MetadataPackage :: default ( ) ,
1352
+ Path :: new ( "/unknown/" ) ,
1353
+ "x86_64-unknown-linux-gnu" ,
1354
+ serde_json:: Value :: Array ( vec ! [ ] ) ,
1355
+ vec ! [
1356
+ "i686-pc-windows-msvc" . into( ) ,
1357
+ "i686-unknown-linux-gnu" . into( ) ,
1358
+ "x86_64-apple-darwin" . into( ) ,
1359
+ "x86_64-pc-windows-msvc" . into( ) ,
1360
+ "x86_64-unknown-linux-gnu" . into( ) ,
1361
+ ] ,
1362
+ & ReleaseData :: default ( ) ,
1363
+ true ,
1364
+ false ,
1365
+ iter:: once ( CompressionAlgorithm :: Bzip2 ) ,
1366
+ None ,
1367
+ true ,
1368
+ 42 ,
1369
+ )
1370
+ . await ?;
1371
+
1372
+ Ok :: < _ , anyhow:: Error > ( release_id)
1373
+ } ) ?;
1374
+
1375
+ fn check_rustdoc_status ( env : & TestEnvironment , rid : ReleaseId ) -> Result < ( ) > {
1376
+ assert_eq ! (
1377
+ env. runtime( ) . block_on( async {
1378
+ let mut conn = env. async_db( ) . await . async_conn( ) . await ;
1379
+ sqlx:: query_scalar!(
1380
+ "SELECT rustdoc_status FROM releases WHERE id = $1" ,
1381
+ rid. 0
1382
+ )
1383
+ . fetch_one( & mut * conn)
1384
+ . await
1385
+ } ) ?,
1386
+ Some ( true )
1387
+ ) ;
1388
+ Ok ( ( ) )
1389
+ }
1390
+
1391
+ check_rustdoc_status ( env, release_id) ?;
1392
+
1393
+ let mut builder = RustwideBuilder :: init ( env) . unwrap ( ) ;
1394
+ builder. update_toolchain ( ) ?;
1395
+ assert ! (
1396
+ // not successful build
1397
+ !builder
1398
+ . build_package( crate_, version, PackageKind :: CratesIo ) ?
1399
+ . successful
1400
+ ) ;
1401
+
1402
+ check_rustdoc_status ( env, release_id) ?;
1403
+ Ok ( ( ) )
1404
+ } ) ;
1405
+ }
1406
+
1300
1407
#[ test]
1301
1408
#[ ignore]
1302
1409
fn test_proc_macro ( ) {
0 commit comments