Add allowed refs to CEL environment

This commit is contained in:
Luc Perkins 2024-06-17 16:08:55 -07:00
parent 31963128ab
commit f3df166096
No known key found for this signature in database
GPG Key ID: 16DB1108FB591835
5 changed files with 50 additions and 12 deletions

View File

@ -14,15 +14,32 @@ nix run github:DeterminateSystems/flake-checker
nix run github:DeterminateSystems/flake-checker /path/to/flake.lock
```
Nix Flake Checker looks at your `flake.lock`'s root-level [Nixpkgs] inputs and checks that:
Nix Flake Checker looks at your `flake.lock`'s root-level [Nixpkgs] inputs.
There are two ways to express flake policies:
* Via [policy conditions](#policy-conditions) using [Common Expression Language][cel] (CEL)
* Via [parameters](#parameters)
## Policy conditions
## Parameters
and checks that:
- Any explicit Nixpkgs Git refs are in this list:
- `nixos-23.11`
- `nixos-23.11-small`
- `nixos-unstable`
- `nixos-unstable-small`
- `nixpkgs-23.11-darwin`
- `nixpkgs-unstable`
* `nixos-23.11`
* `nixos-23.11-small`
* `nixos-24.05`
* `nixos-24.05-small`
* `nixos-unstable`
* `nixos-unstable-small`
* `nixpkgs-23.11-darwin`
* `nixpkgs-24.05-darwin`
* `nixpkgs-unstable`
- Any Nixpkgs dependencies are less than 30 days old
- Any Nixpkgs dependencies have the [`NixOS`][nixos-org] org as the GitHub owner (and thus that the dependency isn't a fork or non-upstream variant)
@ -96,6 +113,7 @@ The `parse-flake-lock` crate doesn't yet exhaustively parse all input node types
If you'd like to help make the parser more exhaustive, [pull requests][prs] are quite welcome.
[action]: https://github.com/DeterminateSystems/flake-checker-action
[cel]: https://cel.dev
[detsys]: https://determinate.systems
[flakes]: https://zero-to-nix.com/concepts/flakes
[install]: https://zero-to-nix.com/start/install

View File

@ -11,6 +11,7 @@ pub(super) fn evaluate_condition(
flake_lock: &FlakeLock,
nixpkgs_keys: &[String],
condition: &str,
allowed_refs: Vec<String>,
) -> Result<Vec<Issue>, FlakeCheckerError> {
let mut issues: Vec<Issue> = vec![];
let mut ctx = Context::default();
@ -19,6 +20,15 @@ pub(super) fn evaluate_condition(
for (name, dep) in deps {
if let Node::Repo(repo) = dep {
let allowed_refs: Value = Value::from(
allowed_refs
.iter()
.map(|r| Value::from(r.to_string()))
.collect::<Vec<Value>>(),
);
ctx.add_variable_from_value("allowed_refs", allowed_refs);
for (k, v) in nixpkgs_cel_values(repo) {
ctx.add_variable_from_value(k, v);
}

View File

@ -147,19 +147,29 @@ mod test {
#[test]
fn test_cel_conditions() {
let allowed_refs: Vec<String> =
serde_json::from_str(include_str!("../allowed-refs.json")).unwrap();
// (n, condition, expected)
let cases: Vec<(usize, &str, bool)> =
vec![(0, "has(git_ref) && has(days_old) && has(owner)", true)];
let cases: Vec<(usize, &str, bool)> = vec![(
0,
"has(git_ref) && has(days_old) && has(owner) && has(allowed_refs) && allowed_refs.contains(git_ref) && owner == 'NixOS'",
true,
)];
for (n, condition, expected) in cases {
let path = PathBuf::from(format!("tests/flake.cel.{n}.lock"));
let path = PathBuf::from(format!("tests/flake.cel.clean.{n}.lock"));
let flake_lock = FlakeLock::new(&path).unwrap();
let config = FlakeCheckConfig {
check_outdated: false,
..Default::default()
};
let result = evaluate_condition(&flake_lock, &config.nixpkgs_keys, condition);
let result = evaluate_condition(
&flake_lock,
&config.nixpkgs_keys,
condition,
allowed_refs.clone(),
);
if expected {
assert!(result.is_ok());

View File

@ -179,7 +179,7 @@ fn main() -> Result<ExitCode, FlakeCheckerError> {
};
let issues = if let Some(condition) = &condition {
evaluate_condition(&flake_lock, &nixpkgs_keys, condition)?
evaluate_condition(&flake_lock, &nixpkgs_keys, condition, allowed_refs.clone())?
} else {
check_flake_lock(&flake_lock, &flake_check_config, allowed_refs.clone())?
};