diff --git a/Cargo.lock b/Cargo.lock index 6f9455400ec..fda0e343b52 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -969,6 +969,7 @@ dependencies = [ "ci-common", "clap 4.5.50", "duct", + "regex", "serde_json", ] diff --git a/tools/ci/commands/lint/Cargo.toml b/tools/ci/commands/lint/Cargo.toml index 44bfa5776bd..66e7d8a7f9c 100644 --- a/tools/ci/commands/lint/Cargo.toml +++ b/tools/ci/commands/lint/Cargo.toml @@ -7,5 +7,6 @@ edition.workspace = true anyhow.workspace = true clap.workspace = true duct.workspace = true +regex.workspace = true serde_json.workspace = true ci-common = { path = "../../common" } diff --git a/tools/ci/commands/lint/src/main.rs b/tools/ci/commands/lint/src/main.rs index 956d4f44ce4..fb59d12b502 100644 --- a/tools/ci/commands/lint/src/main.rs +++ b/tools/ci/commands/lint/src/main.rs @@ -4,12 +4,14 @@ use anyhow::{bail, Context, Result}; use ci_common::{ensure_repo_root, pnpm}; use clap::Parser; use duct::cmd; +use regex::Regex; use serde_json::Value; use std::collections::BTreeSet; use std::ffi::OsString; use std::fs; use std::path::Path; use std::path::PathBuf; +use std::sync::LazyLock; /// Lints the codebase /// @@ -104,6 +106,11 @@ fn npmrc_minimum_release_age(path: &Path, expected_minimum_release_age: u64) -> }) } +fn workflow_installs_pnpm_with_npm(contents: &str) -> bool { + static NPM_INSTALL_PNPM: LazyLock = LazyLock::new(|| Regex::new(r"npm install.*pnpm").unwrap()); + NPM_INSTALL_PNPM.is_match(contents) +} + fn check_pnpm_release_age_policy() -> Result<()> { ensure_repo_root()?; @@ -211,6 +218,12 @@ fn check_pnpm_release_age_policy() -> Result<()> { workflow_path.display() ); } + if workflow_installs_pnpm_with_npm(&contents) { + bail!( + "{} must use ./.github/actions/setup-pnpm instead of installing pnpm with npm", + workflow_path.display() + ); + } } Ok(())