Skip to content

Commit c8a4b19

Browse files
gleocadiegyuheon0h
andauthored
fix(ci): Address semver job issue (#1704)
# What does this PR do? Adds a `git clone` fallback to `libdd-libunwind-sys/build.rs` for obtaining the libunwind source when the crate is built outside of a git repository. The source acquisition logic is now structured as three steps: 1. If `libunwind/src` already exists (submodule checked out, or files copied in), do nothing. 2. If inside a git repo (`.git` exists), try `git submodule update --init --recursive`. 3. Otherwise, fall back to `git clone --depth 1` of the libunwind repository directly. # Motivation The `semver-check` CI job runs `cargo-semver-checks --baseline-rev origin/main`, which extracts the baseline source into a plain directory under `target/semver-checks/git-origin_main/<commit>/`. This directory has no `.git` — it's a raw file extraction, not a git clone or worktree. When building the baseline version of `libdd-crashtracker`, cargo needs to compile its dependency `libdd-libunwind-sys`, which triggers `build.rs`. The previous implementation unconditionally ran `git submodule update --init` assuming it was inside a git repo, which failed with: ``` error: pathspec 'libdd-libunwind-sys/libunwind' did not match any file(s) known to git ``` This is not reproducible locally because a normal `git clone` properly initializes the submodule, and `build.rs` skips the git commands entirely when `libunwind/src` is already present. # Additional Notes - This fix must land on `main` before other branches that modify `libdd-crashtracker` can pass the `semver-check` CI job. This is because `cargo-semver-checks` uses the **baseline** (main) version of `build.rs` when building the baseline, not the branch's version. - The libunwind repo URL and branch are extracted into constants (`LIBUNWIND_REPO`, `LIBUNWIND_BRANCH`) to keep them in sync with `.gitmodules`. - The `git clone` fallback also covers other non-git contexts such as `cargo vendor` or any tool that extracts crate source without preserving git metadata. # How to test the change? ``` git clone --no-checkout https://github.com/DataDog/libdatadog.git test-full cd test-full git checkout --detach origin/gyuheon0h/28.1.1 git submodule update --init --recursive -- libdd-libunwind-sys/libunwind rm -rf target/semver-checks/ ./scripts/semver-level.sh -v libdd-crashtracker main ``` Co-authored-by: gyuheon.oh <gyuheon.oh@datadoghq.com>
1 parent b04809b commit c8a4b19

1 file changed

Lines changed: 80 additions & 26 deletions

File tree

libdd-libunwind-sys/build.rs

Lines changed: 80 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -9,37 +9,91 @@ fn main() {
99
#[cfg(target_os = "linux")]
1010
mod linux {
1111
use std::env;
12-
use std::path::PathBuf;
12+
use std::path::{Path, PathBuf};
13+
use std::process::Command;
14+
15+
const LIBUNWIND_REPO: &str = "https://github.com/DataDog/libunwind.git";
16+
const LIBUNWIND_BRANCH: &str = "kevin/v1.8.1-custom-2";
17+
18+
/// Try initializing the libunwind git submodule from the repo root.
19+
/// Only works when running inside a git repository.
20+
fn try_submodule_init(repo_root: &Path) -> bool {
21+
if !repo_root.join(".git").exists() {
22+
return false;
23+
}
24+
eprintln!("Initializing libunwind submodule...");
25+
Command::new("git")
26+
.args([
27+
"submodule",
28+
"update",
29+
"--init",
30+
"--recursive",
31+
"--",
32+
"libdd-libunwind-sys/libunwind",
33+
])
34+
.current_dir(repo_root)
35+
.status()
36+
.map(|s| s.success())
37+
.unwrap_or(false)
38+
}
39+
40+
/// Clone the libunwind repository directly into `target_dir`.
41+
/// Used as a fallback when not inside a git repo (e.g. cargo-semver-checks
42+
/// extracts baseline source into a plain directory without .git).
43+
fn clone_libunwind(target_dir: &Path) -> bool {
44+
eprintln!("Cloning libunwind source (no git repo or submodule unavailable)...");
45+
let _ = std::fs::remove_dir_all(target_dir);
46+
Command::new("git")
47+
.args([
48+
"clone",
49+
"--depth",
50+
"1",
51+
"--branch",
52+
LIBUNWIND_BRANCH,
53+
LIBUNWIND_REPO,
54+
&target_dir.to_string_lossy(),
55+
])
56+
.status()
57+
.map(|s| s.success())
58+
.unwrap_or(false)
59+
}
60+
61+
fn ensure_libunwind_source(manifest_dir: &str, libunwind_dir: &Path) {
62+
if libunwind_dir.join("src").exists() {
63+
return;
64+
}
65+
66+
let repo_root = Path::new(manifest_dir).parent().unwrap();
67+
68+
if try_submodule_init(repo_root) && libunwind_dir.join("src").exists() {
69+
return;
70+
}
71+
72+
// This can happen when running cargo-semver-checks
73+
// because it extracts the baseline source into a plain directory without .git
74+
if clone_libunwind(libunwind_dir) && libunwind_dir.join("src").exists() {
75+
return;
76+
}
77+
78+
panic!(
79+
"Failed to obtain libunwind source at {}.\n\
80+
Try manually:\n \
81+
git submodule update --init --recursive\n \
82+
or: git clone --branch {} {} {}",
83+
libunwind_dir.display(),
84+
LIBUNWIND_BRANCH,
85+
LIBUNWIND_REPO,
86+
libunwind_dir.display()
87+
);
88+
}
1389

1490
pub(crate) fn main() {
1591
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
1692
let build_dir = out_dir.join("libunwind_build");
17-
let manifest_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap();
18-
let libunwind_dir = std::path::Path::new(&manifest_dir).join("libunwind");
93+
let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
94+
let libunwind_dir = Path::new(&manifest_dir).join("libunwind");
1995

20-
if !libunwind_dir.join("src").exists() {
21-
eprintln!("Initializing libunwind submodule...");
22-
let status = std::process::Command::new("git")
23-
.args([
24-
"submodule",
25-
"update",
26-
"--init",
27-
"--recursive",
28-
"--",
29-
"libdd-libunwind-sys/libunwind",
30-
])
31-
.current_dir(std::path::Path::new(&manifest_dir).parent().unwrap())
32-
.status()
33-
.expect("Failed to run git. Is git installed?");
34-
35-
if !status.success() || !libunwind_dir.join("src").exists() {
36-
panic!(
37-
"Failed to initialize libunwind submodule at {}.\n\
38-
Try manually: git submodule update --init --recursive",
39-
libunwind_dir.display()
40-
);
41-
}
42-
}
96+
ensure_libunwind_source(&manifest_dir, &libunwind_dir);
4397

4498
std::fs::create_dir_all(&build_dir).unwrap();
4599

0 commit comments

Comments
 (0)