rust - 我如何导致编译在 CI 警告时失败并在 .cargo/config 中设置额外的 rustflags?

标签 rust continuous-integration rust-cargo

我试图让 Cargo 因 CI 上的警告而失败,但在本地开发时却没有。

我有一个可行的解决方案,即在 CI 作业中设置 RUSTFLAGS=“-D warnings”。这很有效,因为它确实会导致本地 crate 的构建失败,而不是依赖项 crate(由于 —cap-lints)。

最近,必须在( checkin ).cargo/config 文件中设置一些 rustflags:

[target.’cfg(target_os = “linux”)’]
rustflags = [“some”, “options”]

这不起作用,因为 RUSTFLAGS 优先并且 .cargo/config 标志将被忽略。我不想将 -D 警告 添加到 config 中,因为这在开发时可能会很痛苦。

当前的解决方法是在 CI 作业之前调整 config 的脚本:

sed -i "s:\(rustflags = .*\)]:\1, \"-D\", \"warnings\"]:g" .cargo/config
echo '[build]' >> .cargo/config
echo 'rustflags = [ "-D", "warnings"]' >> .cargo/config

这会将 -D 警告 附加到配置中的现有 rustflags 创建一个额外的包罗万象的 config确保 -D 警告 也在非 Linux CI 构建中启用的条目。

这太骇人听闻了;我还缺少更好的解决方案吗?

也许这应该是 Cargo 存储库的功能请求,但我不知道理想的解决方案是什么样的。

最佳答案

您可以使用 built::util::detect_ci()判断当前构建是否在 CI 下执行。然后你可以使用一个小的构建脚本来设置一个 cfg

Cargo.toml

[package]
build = true

[build-dependencies]
built = { version = "0.3", default_features = false }

build.rs

fn main() {
    if let Some(ci) = built::util::detect_ci() {
        // There may be a better way to do this
        println!("cargo:rustc-cfg=DENY_WARNINGS");
        println!("cargo:warning=Denying warnings because we are in CI \"{}\"", ci);
    }
}

注意构建脚本的结果是缓存的,所以一旦这个构建脚本运行并且 Cargo 决定了我们是否在 CI 下运行,它会一直保持这个结果直到你修改构建脚本或者 cargo 清洁。这对本地开发或 CI 来说应该不是问题,除非 Scotty 定期向您发送消息。

ma​​in.rslib.rs

#![cfg_attr(DENY_WARNINGS, deny(warnings))]

fn main() {
    // This will be a warning locally but fail to compile e.g. if built on Travis
    Result::<(), ()>::Err(());
}

关于rust - 我如何导致编译在 CI 警告时失败并在 .cargo/config 中设置额外的 rustflags?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56870422/

相关文章:

rust - 如何只为给定的平台使用一个箱子?

rust - 对于文件列表,如何仅为已更改的文件运行构建脚本?

Rust 集成测试无法 `use` 库

multithreading - 如何在线程之间共享对 AtomicBool 的访问?

string - mut循环内的字符串重新声明

rust - 如何将可见性 token 传递给位标志!宏?

ruby-on-rails - 持续部署

rust - 如何同时使用 actix-web 3 和 rusoto 0.46?

build - Gitlab-CI:gitlab ci trigger build 仅用于合并请求

java - Jenkins war 部署到 Tomcat 7