Skip to content

Commit f707607

Browse files
authored
fix(turbopack): Use vergen-gitcl instead of shadow-rs (or vergen-git2) for napi and next-api crates to fix stale git lock files (#76889)
This does not depend on libgit2 which apparently breaks our builds on some platforms. Instead it uses the git CLI using my PR: rustyhorde/vergen#406 Original PR: #76773 Revert: #76879 Manually triggered CI run to try to build all platforms: https://github.com/vercel/next.js/actions/runs/13711866131
1 parent 4518bc9 commit f707607

File tree

16 files changed

+266
-283
lines changed

16 files changed

+266
-283
lines changed

Cargo.lock

Lines changed: 154 additions & 185 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -396,9 +396,6 @@ serde_bytes = "0.11.15"
396396
serde_path_to_error = "0.1.16"
397397
serde_qs = "0.13.0"
398398
serde_with = "3.12.0"
399-
shadow-rs = { version = "0.37.0", default-features = false, features = [
400-
"tzdb",
401-
] }
402399
smallvec = { version = "1.13.1", features = [
403400
"serde",
404401
"const_generics",
@@ -423,6 +420,8 @@ unicode-segmentation = "1.10.1"
423420
unsize = "1.1.0"
424421
url = "2.2.2"
425422
urlencoding = "2.1.2"
423+
vergen = { git = "https://github.com/bgw/vergen.git", branch = "bgw/no-optional-locks", features = ["cargo"] }
424+
vergen-gitcl = { git = "https://github.com/bgw/vergen.git", branch = "bgw/no-optional-locks", features = ["cargo"] }
426425
webbrowser = "0.8.7"
427426

428427
[patch.crates-io]

crates/napi/Cargo.toml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,14 +66,13 @@ rand = { workspace = true }
6666
rustc-hash = { workspace = true }
6767
serde = "1"
6868
serde_json = "1"
69-
shadow-rs = { workspace = true }
7069
tracing = { workspace = true }
7170
tracing-subscriber = { workspace = true }
7271
tracing-chrome = "0.5.0"
7372
url = { workspace = true }
7473
urlencoding = { workspace = true }
7574
once_cell = { workspace = true }
76-
dashmap = "6.1.0"
75+
dashmap = { workspace = true }
7776

7877
swc_core = { workspace = true, features = [
7978
"base_concurrent",
@@ -139,11 +138,11 @@ turbo-tasks-malloc = { workspace = true, default-features = false }
139138
tokio = { workspace = true, features = ["full"] }
140139

141140
[build-dependencies]
141+
anyhow = { workspace = true }
142142
napi-build = "2"
143143
serde = { workspace = true }
144144
serde_json = { workspace = true }
145-
# It is not a mistake this dependency is specified in dep / build-dep both.
146-
shadow-rs = { workspace = true }
145+
vergen-gitcl = { workspace = true }
147146

148147
# build-dependencies for the native, non-wasm32 build
149148
[target.'cfg(not(target_arch = "wasm32"))'.build-dependencies]

crates/napi/build.rs

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,52 @@
1-
use std::fs;
1+
use std::{env, process::Command, str};
22

33
extern crate napi_build;
44

5-
fn main() {
5+
fn main() -> anyhow::Result<()> {
6+
println!("cargo:rerun-if-env-changed=CI");
7+
let is_ci = env::var("CI").is_ok_and(|value| !value.is_empty());
8+
69
// Generates, stores build-time information as static values.
710
// There are some places relying on correct values for this (i.e telemetry),
811
// So failing build if this fails.
9-
shadow_rs::ShadowBuilder::builder()
10-
.build()
11-
.expect("Should able to generate build time information");
12+
let cargo = vergen_gitcl::CargoBuilder::default()
13+
.target_triple(true)
14+
.build()?;
15+
// We use the git dirty state to disable persistent caching (persistent caching relies on a
16+
// commit hash to be safe). One tradeoff of this is that we must invalidate the rust build more
17+
// often.
18+
//
19+
// This invalidates the build if any untracked files change. That's sufficient for the case
20+
// where we transition from dirty to clean.
21+
//
22+
// There's an edge-case here where the repository could be newly dirty, but we can't know
23+
// because our build hasn't been invalidated, since the untracked files weren't untracked last
24+
// time we ran. That will cause us to incorrectly report ourselves as clean.
25+
//
26+
// However, in practice that shouldn't be much of an issue: If no other dependency of this
27+
// top-level crate has changed (which would've triggered our rebuild), then the resulting binary
28+
// must be equivalent to a clean build anyways. Therefore, persistent caching using the HEAD
29+
// commit hash as a version is okay.
30+
let git = vergen_gitcl::GitclBuilder::default()
31+
.dirty(/* include_untracked */ true)
32+
.describe(
33+
/* tags */ true,
34+
/* dirty */ !is_ci, // suppress the dirty suffix in CI
35+
/* matches */ Some("v[0-9]*"), // find the last version tag
36+
)
37+
.build()?;
38+
vergen_gitcl::Emitter::default()
39+
.add_instructions(&cargo)?
40+
.add_instructions(&git)?
41+
.fail_on_error()
42+
.emit()?;
1243

13-
let git_head = fs::read_to_string("../../.git/HEAD").unwrap_or_default();
14-
if !git_head.is_empty() && !git_head.starts_with("ref: ") {
15-
println!("cargo:warning=git version {}", git_head);
44+
match Command::new("git").args(["rev-parse", "HEAD"]).output() {
45+
Ok(out) if out.status.success() => println!(
46+
"cargo:warning=git HEAD: {}",
47+
str::from_utf8(&out.stdout).unwrap()
48+
),
49+
_ => println!("cargo:warning=`git rev-parse HEAD` failed"),
1650
}
1751

1852
#[cfg(not(all(target_os = "macos", target_arch = "aarch64")))]
@@ -36,4 +70,6 @@ fn main() {
3670

3771
#[cfg(not(target_arch = "wasm32"))]
3872
turbo_tasks_build::generate_register();
73+
74+
Ok(())
3975
}

crates/napi/src/lib.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,6 @@ pub mod turbo_trace_server;
6161
pub mod turbopack;
6262
pub mod util;
6363

64-
// Declare build-time information variables generated in build.rs
65-
shadow_rs::shadow!(build);
66-
6764
#[cfg(not(any(feature = "__internal_dhat-heap", feature = "__internal_dhat-ad-hoc")))]
6865
#[global_allocator]
6966
static ALLOC: turbo_tasks_malloc::TurboMalloc = turbo_tasks_malloc::TurboMalloc;

crates/napi/src/next_api/utils.rs

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ use turbo_tasks::{
1313
TryJoinIterExt, TurboTasks, TurboTasksApi, UpdateInfo, Vc,
1414
};
1515
use turbo_tasks_backend::{
16-
default_backing_storage, noop_backing_storage, DefaultBackingStorage, NoopBackingStorage,
16+
default_backing_storage, noop_backing_storage, DefaultBackingStorage, GitVersionInfo,
17+
NoopBackingStorage,
1718
};
1819
use turbo_tasks_fs::FileContent;
1920
use turbopack_core::{
@@ -130,26 +131,10 @@ pub fn create_turbo_tasks(
130131
dependency_tracking: bool,
131132
) -> Result<NextTurboTasks> {
132133
Ok(if persistent_caching {
133-
let dirty_suffix = if crate::build::GIT_CLEAN
134-
|| option_env!("CI").is_some_and(|value| !value.is_empty())
135-
{
136-
""
137-
} else {
138-
"-dirty"
139-
};
140-
#[allow(
141-
clippy::const_is_empty,
142-
reason = "LAST_TAG might be empty if the tag can't be determined"
143-
)]
144-
let version_info = if crate::build::LAST_TAG.is_empty() {
145-
format!("{}{}", crate::build::SHORT_COMMIT, dirty_suffix)
146-
} else {
147-
format!(
148-
"{}-{}{}",
149-
crate::build::LAST_TAG,
150-
crate::build::SHORT_COMMIT,
151-
dirty_suffix
152-
)
134+
let version_info = GitVersionInfo {
135+
describe: env!("VERGEN_GIT_DESCRIBE"),
136+
dirty: option_env!("CI").is_none_or(|value| value.is_empty())
137+
&& env!("VERGEN_GIT_DIRTY") == "true",
153138
};
154139
NextTurboTasks::PersistentCaching(TurboTasks::new(
155140
turbo_tasks_backend::TurboTasksBackend::new(

crates/napi/src/util.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,8 @@ pub fn log_internal_error_and_inform(err_info: &str) {
127127
}
128128

129129
#[napi]
130-
pub fn get_target_triple() -> String {
131-
crate::build::BUILD_TARGET.to_string()
130+
pub fn get_target_triple() -> &'static str {
131+
env!("VERGEN_CARGO_TARGET_TRIPLE")
132132
}
133133

134134
pub trait MapErr<T>: Into<Result<T, anyhow::Error>> {

crates/next-api/Cargo.toml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ regex = { workspace = true }
2424
rustc-hash = { workspace = true }
2525
serde = { workspace = true }
2626
serde_json = { workspace = true }
27-
shadow-rs = { workspace = true }
2827
swc_core = { workspace = true }
2928
tracing = { workspace = true }
3029
turbo-rcstr = { workspace = true }
@@ -43,6 +42,6 @@ turbopack-node = { workspace = true }
4342
turbopack-nodejs = { workspace = true }
4443

4544
[build-dependencies]
46-
# It is not a mistake this dependency is specified in dep / build-dep both.
47-
shadow-rs = { workspace = true }
45+
anyhow = { workspace = true }
4846
turbo-tasks-build = { workspace = true }
47+
vergen = { workspace = true }

crates/next-api/build.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
use turbo_tasks_build::generate_register;
22

3-
fn main() {
3+
fn main() -> anyhow::Result<()> {
44
// Generates, stores build-time information as static values.
55
// There are some places relying on correct values for this (i.e telemetry),
66
// So failing build if this fails.
7-
shadow_rs::ShadowBuilder::builder()
8-
.build_pattern(shadow_rs::BuildPattern::Lazy)
9-
.build()
10-
.expect("Should able to generate build time information");
7+
let cargo = vergen::CargoBuilder::default()
8+
.target_triple(true)
9+
.build()?;
10+
vergen::Emitter::default()
11+
.add_instructions(&cargo)?
12+
.fail_on_error()
13+
.emit()?;
1114

1215
generate_register();
16+
17+
Ok(())
1318
}

crates/next-api/src/lib.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,6 @@ mod server_actions;
2323
mod versioned_content_map;
2424
mod webpack_stats;
2525

26-
// Declare build-time information variables generated in build.rs
27-
shadow_rs::shadow!(build);
28-
2926
pub fn register() {
3027
next_core::register();
3128
turbopack_nodejs::register();

0 commit comments

Comments
 (0)