@@ -18,6 +18,7 @@ use anyhow::{anyhow, bail, Error};
1818use docsrs_metadata:: { Metadata , DEFAULT_TARGETS , HOST_TARGET } ;
1919use failure:: Error as FailureError ;
2020use postgres:: Client ;
21+ use regex:: Regex ;
2122use rustwide:: cmd:: { Command , CommandError , SandboxBuilder , SandboxImage } ;
2223use rustwide:: logging:: { self , LogStorage } ;
2324use rustwide:: toolchain:: ToolchainError ;
@@ -73,7 +74,16 @@ impl RustwideBuilder {
7374 . purge_all_build_dirs ( )
7475 . map_err ( FailureError :: compat) ?;
7576
76- let toolchain = Toolchain :: dist ( & config. toolchain ) ;
77+ // If the toolchain is all hex, assume it references an artifact from
78+ // CI, for instance an `@bors try` build.
79+ let re = Regex :: new ( r"^[a-fA-F0-9]+$" ) . unwrap ( ) ;
80+ let toolchain = if re. is_match ( & config. toolchain ) {
81+ debug ! ( "using CI build {}" , & config. toolchain) ;
82+ Toolchain :: ci ( & config. toolchain , false )
83+ } else {
84+ debug ! ( "using toolchain {}" , & config. toolchain) ;
85+ Toolchain :: dist ( & config. toolchain )
86+ } ;
7787
7888 Ok ( RustwideBuilder {
7989 workspace,
@@ -108,6 +118,23 @@ impl RustwideBuilder {
108118 }
109119
110120 pub fn update_toolchain ( & mut self ) -> Result < bool > {
121+ // For CI builds, a lot of the normal update_toolchain things don't apply.
122+ // CI builds are only for one platform (https://forge.rust-lang.org/infra/docs/rustc-ci.html#try-builds)
123+ // so we only try installing for the current platform. If that's not a match,
124+ // for instance if we're running on macOS or Windows, this will error.
125+ // Also, detecting the rustc version relies on calling rustc through rustup with the
126+ // +channel argument, but the +channel argument doesn't work for CI builds. So
127+ // we fake the rustc version and install from scratch every time since we can't detect
128+ // the already-installed rustc version.
129+ if let Some ( ci) = self . toolchain . as_ci ( ) {
130+ self . toolchain
131+ . install ( & self . workspace )
132+ . map_err ( FailureError :: compat) ?;
133+ self . rustc_version = format ! ( "rustc 1.9999.0-nightly ({} 2999-12-29)" , ci. sha( ) ) ;
134+ self . add_essential_files ( ) ?;
135+ return Ok ( true ) ;
136+ }
137+
111138 // Ignore errors if detection fails.
112139 let old_version = self . detect_rustc_version ( ) . ok ( ) ;
113140
@@ -174,6 +201,8 @@ impl RustwideBuilder {
174201 Ok ( has_changed)
175202 }
176203
204+ /// Return a string containing the output of `rustc --version`. Only valid
205+ /// for dist toolchains. Will error if run with a CI toolchain.
177206 fn detect_rustc_version ( & self ) -> Result < String > {
178207 info ! ( "detecting rustc's version..." ) ;
179208 let res = Command :: new ( & self . workspace , self . toolchain . rustc ( ) )
@@ -190,7 +219,6 @@ impl RustwideBuilder {
190219 }
191220
192221 pub fn add_essential_files ( & mut self ) -> Result < ( ) > {
193- self . rustc_version = self . detect_rustc_version ( ) ?;
194222 let rustc_version = parse_rustc_version ( & self . rustc_version ) ?;
195223
196224 info ! ( "building a dummy crate to get essential files" ) ;
0 commit comments