Skip to content

Commit

Permalink
Add refStatuses CEL variable
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Jayman2000 committed Dec 18, 2024
1 parent 65bc77d commit 8259eba
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 3 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ Variable | Description
`numDaysOld` | The number of days old the input is.
`owner` | The input's owner (if a GitHub input).
`supportedRefs` | A list of [supported Git refs](#supported-branches) (all are branch names).
`refStatuses` | A map. Each key is a branch name. Each value is a branch status (`"rolling"`, `"beta"`, `"stable"`, `"deprecated"` or `"unmaintained"`).

We recommend a condition *at least* this stringent:

Expand Down
5 changes: 5 additions & 0 deletions src/condition.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use cel_interpreter::{Context, Program, Value};
use parse_flake_lock::{FlakeLock, Node};

use std::collections::HashMap;

use crate::{
error::FlakeCheckerError,
flake::{nixpkgs_deps, num_days_old},
Expand All @@ -10,16 +12,19 @@ use crate::{
const KEY_GIT_REF: &str = "gitRef";
const KEY_NUM_DAYS_OLD: &str = "numDaysOld";
const KEY_OWNER: &str = "owner";
const KEY_REF_STATUSES: &str = "refStatuses";
const KEY_SUPPORTED_REFS: &str = "supportedRefs";

pub(super) fn evaluate_condition(
flake_lock: &FlakeLock,
nixpkgs_keys: &[String],
condition: &str,
ref_statuses: HashMap<String, String>,
supported_refs: Vec<String>,
) -> Result<Vec<Issue>, FlakeCheckerError> {
let mut issues: Vec<Issue> = vec![];
let mut ctx = Context::default();
ctx.add_variable_from_value(KEY_REF_STATUSES, ref_statuses);
ctx.add_variable_from_value(KEY_SUPPORTED_REFS, supported_refs);

let deps = nixpkgs_deps(flake_lock, nixpkgs_keys)?;
Expand Down
3 changes: 2 additions & 1 deletion src/flake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ mod test {

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

for (condition, expected) in cases {
Expand All @@ -187,6 +187,7 @@ mod test {
&flake_lock,
&config.nixpkgs_keys,
condition,
ref_statuses.clone(),
supported_refs.clone(),
);

Expand Down
10 changes: 8 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,10 +151,16 @@ fn main() -> Result<ExitCode, FlakeCheckerError> {
fail_mode,
};

let allowed_refs = supported_refs(ref_statuses);
let allowed_refs = supported_refs(ref_statuses.clone());

let issues = if let Some(condition) = &condition {
evaluate_condition(&flake_lock, &nixpkgs_keys, condition, allowed_refs.clone())?
evaluate_condition(
&flake_lock,
&nixpkgs_keys,
condition,
ref_statuses,
allowed_refs.clone(),
)?
} else {
check_flake_lock(&flake_lock, &flake_check_config, allowed_refs.clone())?
};
Expand Down

0 comments on commit 8259eba

Please sign in to comment.