Skip to content

Commit 8259eba

Browse files
committed
Add refStatuses CEL variable
By default, Nix Flake Checker will reject Nixpkgs branches that have their status set to "beta" or "unmaintained". All other statuses are allowed. That policy works well most of the time, but there are some situations where that policy is undesirable. Here are some examples: 1. A user might want Nix Flake Checker to give them an error if they’re using a deprecated Nixpkgs branch. This way, Nix Flake Checker will remind the user to update before a branch becomes unmaintained. (This is what I want to do, personally). 2. A user might want to upgrade to a Nixpkgs branch while that branch is in beta. This way, the user can report issues with a particular NixOS, and (hopefully) get those issues fixed before that NixOS release is declared stable. (This is what @dpc wants to do [1][2]). 3. An organisation might want to forbid the use of rolling branches. This way, the organisation only has to deal with breaking changes once every six months. Before this change, here’s what you would need to do in order to make Nix Flake Checker enforce those three policies: 1. flake-checker --condition "supportedRefs.contains(gitRef) && !(gitRef.contains('24.05'))" 2. flake-checker --condition "supportedRefs.contains(gitRef) || gitRef.contains('24.11')" 3. flake-checker --condition "supportedRefs.contains(gitRef) && !(gitRef.contains('unstable'))" Number 1 and 2 are especially problematic because they must manually be updated whenever new channels are created or an existing channel’s status changes. This change adds a new CEL variable named refStatuses. refStatuses makes it easier to override Nix Flake Checker’s default policy for allowed branches. Here’s how you would implement those three policies using the new refStatuses variable. 1. flake-checker --condition "supportedRefs.contains(gitRef) && refStatuses[gitRef] != 'deprecated'" 2. flake-checker --condition "supportedRefs.contains(gitRef) || refStatuses[gitRef] == 'beta'" 3. flake-checker --condition "supportedRefs.contains(gitRef) && refStatuses[gitRef] != 'rolling'" [1]: DeterminateSystems/flake-checker-action#47 [2]: #149
1 parent 65bc77d commit 8259eba

File tree

4 files changed

+16
-3
lines changed

4 files changed

+16
-3
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ Variable | Description
7272
`numDaysOld` | The number of days old the input is.
7373
`owner` | The input's owner (if a GitHub input).
7474
`supportedRefs` | A list of [supported Git refs](#supported-branches) (all are branch names).
75+
`refStatuses` | A map. Each key is a branch name. Each value is a branch status (`"rolling"`, `"beta"`, `"stable"`, `"deprecated"` or `"unmaintained"`).
7576

7677
We recommend a condition *at least* this stringent:
7778

src/condition.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use cel_interpreter::{Context, Program, Value};
22
use parse_flake_lock::{FlakeLock, Node};
33

4+
use std::collections::HashMap;
5+
46
use crate::{
57
error::FlakeCheckerError,
68
flake::{nixpkgs_deps, num_days_old},
@@ -10,16 +12,19 @@ use crate::{
1012
const KEY_GIT_REF: &str = "gitRef";
1113
const KEY_NUM_DAYS_OLD: &str = "numDaysOld";
1214
const KEY_OWNER: &str = "owner";
15+
const KEY_REF_STATUSES: &str = "refStatuses";
1316
const KEY_SUPPORTED_REFS: &str = "supportedRefs";
1417

1518
pub(super) fn evaluate_condition(
1619
flake_lock: &FlakeLock,
1720
nixpkgs_keys: &[String],
1821
condition: &str,
22+
ref_statuses: HashMap<String, String>,
1923
supported_refs: Vec<String>,
2024
) -> Result<Vec<Issue>, FlakeCheckerError> {
2125
let mut issues: Vec<Issue> = vec![];
2226
let mut ctx = Context::default();
27+
ctx.add_variable_from_value(KEY_REF_STATUSES, ref_statuses);
2328
ctx.add_variable_from_value(KEY_SUPPORTED_REFS, supported_refs);
2429

2530
let deps = nixpkgs_deps(flake_lock, nixpkgs_keys)?;

src/flake.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ mod test {
173173

174174
let ref_statuses: HashMap<String, String> =
175175
serde_json::from_str(include_str!("../ref-statuses.json")).unwrap();
176-
let supported_refs = supported_refs(ref_statuses);
176+
let supported_refs = supported_refs(ref_statuses.clone());
177177
let path = PathBuf::from("tests/flake.cel.0.lock");
178178

179179
for (condition, expected) in cases {
@@ -187,6 +187,7 @@ mod test {
187187
&flake_lock,
188188
&config.nixpkgs_keys,
189189
condition,
190+
ref_statuses.clone(),
190191
supported_refs.clone(),
191192
);
192193

src/main.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,10 +151,16 @@ fn main() -> Result<ExitCode, FlakeCheckerError> {
151151
fail_mode,
152152
};
153153

154-
let allowed_refs = supported_refs(ref_statuses);
154+
let allowed_refs = supported_refs(ref_statuses.clone());
155155

156156
let issues = if let Some(condition) = &condition {
157-
evaluate_condition(&flake_lock, &nixpkgs_keys, condition, allowed_refs.clone())?
157+
evaluate_condition(
158+
&flake_lock,
159+
&nixpkgs_keys,
160+
condition,
161+
ref_statuses,
162+
allowed_refs.clone(),
163+
)?
158164
} else {
159165
check_flake_lock(&flake_lock, &flake_check_config, allowed_refs.clone())?
160166
};

0 commit comments

Comments
 (0)