diff --git a/README.md b/README.md index 4f1cf9a..304b570 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,7 @@ The Nix Flake Checker Action has a number of configuration parameters that you c | Parameter | Description | Default | | :-------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | :----------- | +| `condition` | An optional Common Expression Language (CEL) condition expressing your flake policy. Supersedes all `check-*` parameters. | | | `flake-lock-path` | The path to the `flake.lock` file you want to check. | `flake.lock` | | `check-outdated` | Whether to check that the root Nixpkgs input is less than 30 days old. | `true` | | `check-owner` | Whether to check that the root Nixpkgs input has the `NixOS` GitHub org as its owner. | `true` | diff --git a/action.yml b/action.yml index fd671b1..e860123 100644 --- a/action.yml +++ b/action.yml @@ -9,6 +9,11 @@ inputs: description: | The path to the `flake.lock` file you want to check. default: flake.lock + condition: + description: | + A Common Expression Language (CEL) condition expressing your flake policy. + Supersedes all `check-*` parameters. + required: false check-outdated: description: | Whether to check that the root Nixpkgs input is less than 30 days old. diff --git a/dist/index.js b/dist/index.js index 924f208..1f34e16 100644 --- a/dist/index.js +++ b/dist/index.js @@ -95094,6 +95094,7 @@ var FlakeCheckerAction = class extends DetSysAction { // We don't need Nix in this Action because we fetch a static binary using curl and run it requireNix: "ignore" }); + this.condition = inputs_exports.getStringOrNull("condition"); this.flakeLockPath = inputs_exports.getString("flake-lock-path"); this.nixpkgsKeys = inputs_exports.getString("nixpkgs-keys"); this.checkOutdated = inputs_exports.getBool("check-outdated"); @@ -95135,6 +95136,9 @@ var FlakeCheckerAction = class extends DetSysAction { const executionEnv = {}; executionEnv.NIX_FLAKE_CHECKER_FLAKE_LOCK_PATH = this.flakeLockPath; executionEnv.NIX_FLAKE_CHECKER_NIXPKGS_KEYS = this.nixpkgsKeys; + if (this.condition) { + executionEnv.NIX_FLAKE_CHECKER_CONDITION = this.condition; + } if (!this.sendStatistics) { executionEnv.NIX_FLAKE_CHECKER_NO_TELEMETRY = "false"; } diff --git a/dist/index.js.map b/dist/index.js.map index 9805e56..00e5412 100644 --- a/dist/index.js.map +++ b/dist/index.js.map @@ -1 +1 @@ -{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import * as actionsCore from \"@actions/core\";\nimport * as actionsExec from \"@actions/exec\";\nimport { DetSysAction, inputs } from \"detsys-ts\";\n\nconst EVENT_EXECUTION_FAILURE = \"execution_failure\";\n\nclass FlakeCheckerAction extends DetSysAction {\n flakeLockPath: string;\n nixpkgsKeys: string;\n checkOutdated: boolean;\n checkOwner: boolean;\n checkSupported: boolean;\n ignoreMissingFlakeLock: boolean;\n failMode: boolean;\n sendStatistics: boolean;\n\n constructor() {\n super({\n name: \"flake-checker\",\n fetchStyle: \"gh-env-style\",\n diagnosticsSuffix: \"telemetry\",\n // We don't need Nix in this Action because we fetch a static binary using curl and run it\n requireNix: \"ignore\",\n });\n\n this.flakeLockPath = inputs.getString(\"flake-lock-path\");\n this.nixpkgsKeys = inputs.getString(\"nixpkgs-keys\");\n this.checkOutdated = inputs.getBool(\"check-outdated\");\n this.checkOwner = inputs.getBool(\"check-owner\");\n this.checkSupported = inputs.getBool(\"check-supported\");\n this.ignoreMissingFlakeLock = inputs.getBool(\"ignore-missing-flake-lock\");\n this.failMode = inputs.getBool(\"fail-mode\");\n this.sendStatistics = inputs.getBool(\"send-statistics\");\n }\n\n async main(): Promise {\n await this.checkFlake();\n }\n\n // No post step\n async post(): Promise {}\n\n private async checkFlake(): Promise {\n const binaryPath = await this.fetchExecutable();\n const executionEnv = await this.executionEnvironment();\n\n actionsCore.debug(\n `Execution environment: ${JSON.stringify(executionEnv, null, 4)}`,\n );\n\n const exitCode = await actionsExec.exec(binaryPath, [], {\n env: {\n ...executionEnv,\n ...process.env, // To get $PATH, etc\n },\n ignoreReturnCode: true,\n });\n\n if (exitCode !== 0) {\n this.recordEvent(EVENT_EXECUTION_FAILURE, {\n exitCode,\n });\n actionsCore.setFailed(`Non-zero exit code of \\`${exitCode}\\`.`);\n }\n\n return exitCode;\n }\n\n private async executionEnvironment(): Promise {\n const executionEnv: ExecutionEnvironment = {};\n\n executionEnv.NIX_FLAKE_CHECKER_FLAKE_LOCK_PATH = this.flakeLockPath;\n executionEnv.NIX_FLAKE_CHECKER_NIXPKGS_KEYS = this.nixpkgsKeys;\n\n if (!this.sendStatistics) {\n executionEnv.NIX_FLAKE_CHECKER_NO_TELEMETRY = \"false\";\n }\n\n if (!this.checkOutdated) {\n executionEnv.NIX_FLAKE_CHECKER_CHECK_OUTDATED = \"false\";\n }\n\n if (!this.checkOwner) {\n executionEnv.NIX_FLAKE_CHECKER_CHECK_OWNER = \"false\";\n }\n\n if (!this.checkSupported) {\n executionEnv.NIX_FLAKE_CHECKER_CHECK_SUPPORTED = \"false\";\n }\n\n if (!this.ignoreMissingFlakeLock) {\n executionEnv.NIX_FLAKE_CHECKER_IGNORE_MISSING_FLAKE_LOCK = \"false\";\n }\n\n if (this.failMode) {\n executionEnv.NIX_FLAKE_CHECKER_FAIL_MODE = \"true\";\n }\n\n return executionEnv;\n }\n}\n\ntype ExecutionEnvironment = {\n // All env vars are strings, no fanciness here.\n RUST_BACKTRACE?: string;\n NIX_FLAKE_CHECKER_FLAKE_LOCK_PATH?: string;\n NIX_FLAKE_CHECKER_NIXPKGS_KEYS?: string;\n NIX_FLAKE_CHECKER_NO_TELEMETRY?: string;\n NIX_FLAKE_CHECKER_CHECK_OUTDATED?: string;\n NIX_FLAKE_CHECKER_CHECK_OWNER?: string;\n NIX_FLAKE_CHECKER_CHECK_SUPPORTED?: string;\n NIX_FLAKE_CHECKER_IGNORE_MISSING_FLAKE_LOCK?: string;\n NIX_FLAKE_CHECKER_FAIL_MODE?: string;\n};\n\nfunction main(): void {\n new FlakeCheckerAction().execute();\n}\n\nmain();\n"],"mappings":";AAAA,YAAY,iBAAiB;AAC7B,YAAY,iBAAiB;AAC7B,SAAS,cAAc,cAAc;AAErC,IAAM,0BAA0B;AAEhC,IAAM,qBAAN,cAAiC,aAAa;AAAA,EAU5C,cAAc;AACZ,UAAM;AAAA,MACJ,MAAM;AAAA,MACN,YAAY;AAAA,MACZ,mBAAmB;AAAA;AAAA,MAEnB,YAAY;AAAA,IACd,CAAC;AAED,SAAK,gBAAgB,OAAO,UAAU,iBAAiB;AACvD,SAAK,cAAc,OAAO,UAAU,cAAc;AAClD,SAAK,gBAAgB,OAAO,QAAQ,gBAAgB;AACpD,SAAK,aAAa,OAAO,QAAQ,aAAa;AAC9C,SAAK,iBAAiB,OAAO,QAAQ,iBAAiB;AACtD,SAAK,yBAAyB,OAAO,QAAQ,2BAA2B;AACxE,SAAK,WAAW,OAAO,QAAQ,WAAW;AAC1C,SAAK,iBAAiB,OAAO,QAAQ,iBAAiB;AAAA,EACxD;AAAA,EAEA,MAAM,OAAsB;AAC1B,UAAM,KAAK,WAAW;AAAA,EACxB;AAAA;AAAA,EAGA,MAAM,OAAsB;AAAA,EAAC;AAAA,EAE7B,MAAc,aAA8B;AAC1C,UAAM,aAAa,MAAM,KAAK,gBAAgB;AAC9C,UAAM,eAAe,MAAM,KAAK,qBAAqB;AAErD,IAAY;AAAA,MACV,0BAA0B,KAAK,UAAU,cAAc,MAAM,CAAC,CAAC;AAAA,IACjE;AAEA,UAAM,WAAW,MAAkB,iBAAK,YAAY,CAAC,GAAG;AAAA,MACtD,KAAK;AAAA,QACH,GAAG;AAAA,QACH,GAAG,QAAQ;AAAA;AAAA,MACb;AAAA,MACA,kBAAkB;AAAA,IACpB,CAAC;AAED,QAAI,aAAa,GAAG;AAClB,WAAK,YAAY,yBAAyB;AAAA,QACxC;AAAA,MACF,CAAC;AACD,MAAY,sBAAU,2BAA2B,QAAQ,KAAK;AAAA,IAChE;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,uBAAsD;AAClE,UAAM,eAAqC,CAAC;AAE5C,iBAAa,oCAAoC,KAAK;AACtD,iBAAa,iCAAiC,KAAK;AAEnD,QAAI,CAAC,KAAK,gBAAgB;AACxB,mBAAa,iCAAiC;AAAA,IAChD;AAEA,QAAI,CAAC,KAAK,eAAe;AACvB,mBAAa,mCAAmC;AAAA,IAClD;AAEA,QAAI,CAAC,KAAK,YAAY;AACpB,mBAAa,gCAAgC;AAAA,IAC/C;AAEA,QAAI,CAAC,KAAK,gBAAgB;AACxB,mBAAa,oCAAoC;AAAA,IACnD;AAEA,QAAI,CAAC,KAAK,wBAAwB;AAChC,mBAAa,8CAA8C;AAAA,IAC7D;AAEA,QAAI,KAAK,UAAU;AACjB,mBAAa,8BAA8B;AAAA,IAC7C;AAEA,WAAO;AAAA,EACT;AACF;AAeA,SAAS,OAAa;AACpB,MAAI,mBAAmB,EAAE,QAAQ;AACnC;AAEA,KAAK;","names":[]} \ No newline at end of file +{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import * as actionsCore from \"@actions/core\";\nimport * as actionsExec from \"@actions/exec\";\nimport { DetSysAction, inputs } from \"detsys-ts\";\n\nconst EVENT_EXECUTION_FAILURE = \"execution_failure\";\n\nclass FlakeCheckerAction extends DetSysAction {\n condition: string | null;\n flakeLockPath: string;\n nixpkgsKeys: string;\n checkOutdated: boolean;\n checkOwner: boolean;\n checkSupported: boolean;\n ignoreMissingFlakeLock: boolean;\n failMode: boolean;\n sendStatistics: boolean;\n\n constructor() {\n super({\n name: \"flake-checker\",\n fetchStyle: \"gh-env-style\",\n diagnosticsSuffix: \"telemetry\",\n // We don't need Nix in this Action because we fetch a static binary using curl and run it\n requireNix: \"ignore\",\n });\n\n this.condition = inputs.getStringOrNull(\"condition\");\n this.flakeLockPath = inputs.getString(\"flake-lock-path\");\n this.nixpkgsKeys = inputs.getString(\"nixpkgs-keys\");\n this.checkOutdated = inputs.getBool(\"check-outdated\");\n this.checkOwner = inputs.getBool(\"check-owner\");\n this.checkSupported = inputs.getBool(\"check-supported\");\n this.ignoreMissingFlakeLock = inputs.getBool(\"ignore-missing-flake-lock\");\n this.failMode = inputs.getBool(\"fail-mode\");\n this.sendStatistics = inputs.getBool(\"send-statistics\");\n }\n\n async main(): Promise {\n await this.checkFlake();\n }\n\n // No post step\n async post(): Promise {}\n\n private async checkFlake(): Promise {\n const binaryPath = await this.fetchExecutable();\n const executionEnv = await this.executionEnvironment();\n\n actionsCore.debug(\n `Execution environment: ${JSON.stringify(executionEnv, null, 4)}`,\n );\n\n const exitCode = await actionsExec.exec(binaryPath, [], {\n env: {\n ...executionEnv,\n ...process.env, // To get $PATH, etc\n },\n ignoreReturnCode: true,\n });\n\n if (exitCode !== 0) {\n this.recordEvent(EVENT_EXECUTION_FAILURE, {\n exitCode,\n });\n actionsCore.setFailed(`Non-zero exit code of \\`${exitCode}\\`.`);\n }\n\n return exitCode;\n }\n\n private async executionEnvironment(): Promise {\n const executionEnv: ExecutionEnvironment = {};\n\n executionEnv.NIX_FLAKE_CHECKER_FLAKE_LOCK_PATH = this.flakeLockPath;\n executionEnv.NIX_FLAKE_CHECKER_NIXPKGS_KEYS = this.nixpkgsKeys;\n\n if (this.condition) {\n executionEnv.NIX_FLAKE_CHECKER_CONDITION = this.condition;\n }\n\n if (!this.sendStatistics) {\n executionEnv.NIX_FLAKE_CHECKER_NO_TELEMETRY = \"false\";\n }\n\n if (!this.checkOutdated) {\n executionEnv.NIX_FLAKE_CHECKER_CHECK_OUTDATED = \"false\";\n }\n\n if (!this.checkOwner) {\n executionEnv.NIX_FLAKE_CHECKER_CHECK_OWNER = \"false\";\n }\n\n if (!this.checkSupported) {\n executionEnv.NIX_FLAKE_CHECKER_CHECK_SUPPORTED = \"false\";\n }\n\n if (!this.ignoreMissingFlakeLock) {\n executionEnv.NIX_FLAKE_CHECKER_IGNORE_MISSING_FLAKE_LOCK = \"false\";\n }\n\n if (this.failMode) {\n executionEnv.NIX_FLAKE_CHECKER_FAIL_MODE = \"true\";\n }\n\n return executionEnv;\n }\n}\n\ntype ExecutionEnvironment = {\n // All env vars are strings, no fanciness here.\n RUST_BACKTRACE?: string;\n NIX_FLAKE_CHECKER_CONDITION?: string;\n NIX_FLAKE_CHECKER_FLAKE_LOCK_PATH?: string;\n NIX_FLAKE_CHECKER_NIXPKGS_KEYS?: string;\n NIX_FLAKE_CHECKER_NO_TELEMETRY?: string;\n NIX_FLAKE_CHECKER_CHECK_OUTDATED?: string;\n NIX_FLAKE_CHECKER_CHECK_OWNER?: string;\n NIX_FLAKE_CHECKER_CHECK_SUPPORTED?: string;\n NIX_FLAKE_CHECKER_IGNORE_MISSING_FLAKE_LOCK?: string;\n NIX_FLAKE_CHECKER_FAIL_MODE?: string;\n};\n\nfunction main(): void {\n new FlakeCheckerAction().execute();\n}\n\nmain();\n"],"mappings":";AAAA,YAAY,iBAAiB;AAC7B,YAAY,iBAAiB;AAC7B,SAAS,cAAc,cAAc;AAErC,IAAM,0BAA0B;AAEhC,IAAM,qBAAN,cAAiC,aAAa;AAAA,EAW5C,cAAc;AACZ,UAAM;AAAA,MACJ,MAAM;AAAA,MACN,YAAY;AAAA,MACZ,mBAAmB;AAAA;AAAA,MAEnB,YAAY;AAAA,IACd,CAAC;AAED,SAAK,YAAY,OAAO,gBAAgB,WAAW;AACnD,SAAK,gBAAgB,OAAO,UAAU,iBAAiB;AACvD,SAAK,cAAc,OAAO,UAAU,cAAc;AAClD,SAAK,gBAAgB,OAAO,QAAQ,gBAAgB;AACpD,SAAK,aAAa,OAAO,QAAQ,aAAa;AAC9C,SAAK,iBAAiB,OAAO,QAAQ,iBAAiB;AACtD,SAAK,yBAAyB,OAAO,QAAQ,2BAA2B;AACxE,SAAK,WAAW,OAAO,QAAQ,WAAW;AAC1C,SAAK,iBAAiB,OAAO,QAAQ,iBAAiB;AAAA,EACxD;AAAA,EAEA,MAAM,OAAsB;AAC1B,UAAM,KAAK,WAAW;AAAA,EACxB;AAAA;AAAA,EAGA,MAAM,OAAsB;AAAA,EAAC;AAAA,EAE7B,MAAc,aAA8B;AAC1C,UAAM,aAAa,MAAM,KAAK,gBAAgB;AAC9C,UAAM,eAAe,MAAM,KAAK,qBAAqB;AAErD,IAAY;AAAA,MACV,0BAA0B,KAAK,UAAU,cAAc,MAAM,CAAC,CAAC;AAAA,IACjE;AAEA,UAAM,WAAW,MAAkB,iBAAK,YAAY,CAAC,GAAG;AAAA,MACtD,KAAK;AAAA,QACH,GAAG;AAAA,QACH,GAAG,QAAQ;AAAA;AAAA,MACb;AAAA,MACA,kBAAkB;AAAA,IACpB,CAAC;AAED,QAAI,aAAa,GAAG;AAClB,WAAK,YAAY,yBAAyB;AAAA,QACxC;AAAA,MACF,CAAC;AACD,MAAY,sBAAU,2BAA2B,QAAQ,KAAK;AAAA,IAChE;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,uBAAsD;AAClE,UAAM,eAAqC,CAAC;AAE5C,iBAAa,oCAAoC,KAAK;AACtD,iBAAa,iCAAiC,KAAK;AAEnD,QAAI,KAAK,WAAW;AAClB,mBAAa,8BAA8B,KAAK;AAAA,IAClD;AAEA,QAAI,CAAC,KAAK,gBAAgB;AACxB,mBAAa,iCAAiC;AAAA,IAChD;AAEA,QAAI,CAAC,KAAK,eAAe;AACvB,mBAAa,mCAAmC;AAAA,IAClD;AAEA,QAAI,CAAC,KAAK,YAAY;AACpB,mBAAa,gCAAgC;AAAA,IAC/C;AAEA,QAAI,CAAC,KAAK,gBAAgB;AACxB,mBAAa,oCAAoC;AAAA,IACnD;AAEA,QAAI,CAAC,KAAK,wBAAwB;AAChC,mBAAa,8CAA8C;AAAA,IAC7D;AAEA,QAAI,KAAK,UAAU;AACjB,mBAAa,8BAA8B;AAAA,IAC7C;AAEA,WAAO;AAAA,EACT;AACF;AAgBA,SAAS,OAAa;AACpB,MAAI,mBAAmB,EAAE,QAAQ;AACnC;AAEA,KAAK;","names":[]} \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 20dc286..593dafd 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,6 +5,7 @@ import { DetSysAction, inputs } from "detsys-ts"; const EVENT_EXECUTION_FAILURE = "execution_failure"; class FlakeCheckerAction extends DetSysAction { + condition: string | null; flakeLockPath: string; nixpkgsKeys: string; checkOutdated: boolean; @@ -23,6 +24,7 @@ class FlakeCheckerAction extends DetSysAction { requireNix: "ignore", }); + this.condition = inputs.getStringOrNull("condition"); this.flakeLockPath = inputs.getString("flake-lock-path"); this.nixpkgsKeys = inputs.getString("nixpkgs-keys"); this.checkOutdated = inputs.getBool("check-outdated"); @@ -72,6 +74,10 @@ class FlakeCheckerAction extends DetSysAction { executionEnv.NIX_FLAKE_CHECKER_FLAKE_LOCK_PATH = this.flakeLockPath; executionEnv.NIX_FLAKE_CHECKER_NIXPKGS_KEYS = this.nixpkgsKeys; + if (this.condition) { + executionEnv.NIX_FLAKE_CHECKER_CONDITION = this.condition; + } + if (!this.sendStatistics) { executionEnv.NIX_FLAKE_CHECKER_NO_TELEMETRY = "false"; } @@ -103,6 +109,7 @@ class FlakeCheckerAction extends DetSysAction { type ExecutionEnvironment = { // All env vars are strings, no fanciness here. RUST_BACKTRACE?: string; + NIX_FLAKE_CHECKER_CONDITION?: string; NIX_FLAKE_CHECKER_FLAKE_LOCK_PATH?: string; NIX_FLAKE_CHECKER_NIXPKGS_KEYS?: string; NIX_FLAKE_CHECKER_NO_TELEMETRY?: string;