Skip to content

Commit 4065439

Browse files
authored
fix(nix): align watchdog Linux feature profile (#1021)
* Align watchdog and Nix Linux feature profile * Allow non-pin flake changes during rollout * Move watchdog Nix verification override to workflow
1 parent ce179dd commit 4065439

8 files changed

Lines changed: 141 additions & 27 deletions

File tree

.github/workflows/cachix.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ jobs:
5656
.#codex-desktop-computer-use-ui \
5757
.#codex-desktop-remote-mobile-control \
5858
.#codex-desktop-computer-use-ui-remote-mobile-control \
59-
.#checks.x86_64-linux.nix-linux-features-multi-feature \
59+
.#checks.x86_64-linux.watchdog-linux-features \
6060
.#installer \
6161
--no-link \
6262
--print-build-logs
@@ -68,6 +68,6 @@ jobs:
6868
echo "- Built: \`.#codex-desktop-computer-use-ui\`"
6969
echo "- Built: \`.#codex-desktop-remote-mobile-control\`"
7070
echo "- Built: \`.#codex-desktop-computer-use-ui-remote-mobile-control\`"
71-
echo "- Built: \`.#checks.x86_64-linux.nix-linux-features-multi-feature\`"
71+
echo "- Built: \`.#checks.x86_64-linux.watchdog-linux-features\`"
7272
echo "- Built: \`.#installer\`"
7373
} >> "$GITHUB_STEP_SUMMARY"

.github/workflows/ci.yml

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@ jobs:
134134
env:
135135
GH_TOKEN: ${{ github.token }}
136136
PR_NUMBER: ${{ github.event.pull_request.number }}
137+
PR_BASE_SHA: ${{ github.event.pull_request.base.sha }}
138+
PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }}
137139
run: |
138140
set -euo pipefail
139141
changed=false
@@ -143,14 +145,24 @@ jobs:
143145
"repos/${GITHUB_REPOSITORY}/pulls/${PR_NUMBER}/files" \
144146
--paginate \
145147
--jq '.[].filename' | tee "$changed_files"
146-
if grep -Eq '^(flake\.nix|flake\.lock|nix/native-modules/package\.json|nix/native-modules/package-lock\.json|scripts/ci/update-nix-hashes\.sh|scripts/ci/validate-nix-pins\.sh)$' "$changed_files"; then
148+
guarded_paths='^(flake\.lock|nix/native-modules/package\.json|nix/native-modules/package-lock\.json|scripts/ci/update-nix-hashes\.sh|scripts/ci/validate-nix-pins\.sh)$'
149+
if grep -Eq "$guarded_paths" "$changed_files"; then
147150
changed=true
151+
elif grep -qx 'flake.nix' "$changed_files"; then
152+
git fetch --no-tags --depth=1 origin "$PR_BASE_SHA" "$PR_HEAD_SHA"
153+
if git diff --unified=0 "$PR_BASE_SHA" "$PR_HEAD_SHA" -- flake.nix \
154+
| grep -Eq '^[+-][[:space:]]*(codexVersion|electronVersion|hash) = '; then
155+
changed=true
156+
fi
157+
fi
158+
159+
if [ "$changed" = "true" ]; then
148160
{
149161
echo "## Nix Pin File Changes"
150162
echo ""
151-
echo "- Rollout skip is disabled because this PR changes Nix pin source-of-truth files."
163+
echo "- Rollout skip is disabled because this PR changes Nix pin source-of-truth content."
152164
echo "- Changed guarded files:"
153-
grep -E '^(flake\.nix|flake\.lock|nix/native-modules/package\.json|nix/native-modules/package-lock\.json|scripts/ci/update-nix-hashes\.sh|scripts/ci/validate-nix-pins\.sh)$' "$changed_files" | sed 's/^/ - `/' | sed 's/$/`/'
165+
grep -E "$guarded_paths|^flake\.nix$" "$changed_files" | sed 's/^/ - `/' | sed 's/$/`/'
154166
} >> "$GITHUB_STEP_SUMMARY"
155167
fi
156168
fi
@@ -202,7 +214,7 @@ jobs:
202214
.#codex-desktop-computer-use-ui
203215
.#codex-desktop-remote-mobile-control
204216
.#codex-desktop-computer-use-ui-remote-mobile-control
205-
.#checks.x86_64-linux.nix-linux-features-multi-feature
217+
.#checks.x86_64-linux.watchdog-linux-features
206218
)
207219
for output in "${outputs[@]}"; do
208220
build_log="$(mktemp)"

.github/workflows/update-codex-hash.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@ jobs:
3030
NIX_CONFIG: experimental-features = nix-command flakes
3131
CACHIX_CACHE_NAME: codex-desktop-linux
3232
CACHIX_AUTH_TOKEN: ${{ secrets.CACHIX_AUTH_TOKEN }}
33+
NIX_VERIFY_OUTPUTS: |
34+
.#codex-desktop
35+
.#codex-desktop-computer-use-ui
36+
.#codex-desktop-remote-mobile-control
37+
.#codex-desktop-computer-use-ui-remote-mobile-control
38+
.#checks.x86_64-linux.watchdog-linux-features
39+
.#installer
3340
steps:
3441
- uses: actions/checkout@v7
3542
with:

flake.nix

Lines changed: 42 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -464,10 +464,25 @@ PY
464464
fi
465465
'';
466466

467+
linuxFeaturesConfigFile = config:
468+
pkgs.writeText "codex-linux-features.json" (builtins.toJSON config);
469+
467470
linuxFeaturesConfig = linuxFeatureIds:
468-
pkgs.writeText "codex-linux-features.json" (builtins.toJSON {
471+
linuxFeaturesConfigFile {
469472
enabled = linuxFeatureIds;
470-
});
473+
};
474+
475+
normalizeLinuxFeaturesConfig = config:
476+
let
477+
enabled = nixLinuxFeatures.normalize (config.enabled or [ ]);
478+
in
479+
config // {
480+
inherit enabled;
481+
};
482+
483+
watchdogLinuxFeaturesConfig = normalizeLinuxFeaturesConfig (
484+
builtins.fromJSON (builtins.readFile ./scripts/ci/watchdog-linux-features.json)
485+
);
471486

472487
enabledFeatureIds = { enableComputerUseUi ? false, linuxFeatureIds ? [ ] }:
473488
pkgs.lib.optionals enableComputerUseUi [ "computer-use-ui" ]
@@ -479,9 +494,17 @@ PY
479494
in
480495
if featureIds == [ ] then "" else "-${pkgs.lib.concatStringsSep "-" featureIds}";
481496

482-
mkCodexDesktopPayload = { enableComputerUseUi ? false, linuxFeatureIds ? [ ] }:
497+
mkCodexDesktopPayload = { enableComputerUseUi ? false, linuxFeatureIds ? [ ], linuxFeaturesConfigOverride ? null }:
498+
let
499+
effectiveLinuxFeaturesConfig =
500+
if linuxFeaturesConfigOverride == null then
501+
normalizeLinuxFeaturesConfig { enabled = linuxFeatureIds; }
502+
else
503+
normalizeLinuxFeaturesConfig linuxFeaturesConfigOverride;
504+
effectiveLinuxFeatureIds = effectiveLinuxFeaturesConfig.enabled;
505+
in
483506
pkgs.stdenv.mkDerivation {
484-
pname = "codex-desktop${packageSuffix { inherit enableComputerUseUi linuxFeatureIds; }}-payload";
507+
pname = "codex-desktop${packageSuffix { inherit enableComputerUseUi; linuxFeatureIds = effectiveLinuxFeatureIds; }}-payload";
485508
version = codexVersion;
486509
src = sourceRoot;
487510
__structuredAttrs = true;
@@ -528,7 +551,7 @@ PY
528551
export CXXFLAGS="''${CXXFLAGS:-} -ffile-prefix-map=$TMPDIR=/build -fdebug-prefix-map=$TMPDIR=/build -fmacro-prefix-map=$TMPDIR=/build"
529552
export RUSTFLAGS="''${RUSTFLAGS:-} --remap-path-prefix=$TMPDIR=/build -C link-arg=-Wl,--build-id=none"
530553
export CODEX_MANAGED_NODE_SOURCE="${pkgs.nodejs}"
531-
export CODEX_LINUX_FEATURES_CONFIG="${linuxFeaturesConfig linuxFeatureIds}"
554+
export CODEX_LINUX_FEATURES_CONFIG="${linuxFeaturesConfigFile effectiveLinuxFeaturesConfig}"
532555
export CODEX_ELECTRON_ZIP_SOURCE="${electronZip}"
533556
export CODEX_NATIVE_MODULES_SOURCE="${codexNativeModules}"
534557
${pkgs.lib.optionalString (browserUseNodeRepl != null) ''
@@ -538,10 +561,10 @@ PY
538561
export CODEX_LINUX_COMPUTER_USE_COSMIC_SOURCE="${codexComputerUseBinaries}/bin/codex-computer-use-cosmic"
539562
export CODEX_CHROME_EXTENSION_HOST_SOURCE="${codexComputerUseBinaries}/bin/codex-chrome-extension-host"
540563
export CODEX_NOTIFICATION_ACTIONS_SOURCE="${codexNotificationActionsBinary}/bin/codex-notification-actions-linux"
541-
${pkgs.lib.optionalString (builtins.elem "mcp-helper-reaper" linuxFeatureIds) ''
564+
${pkgs.lib.optionalString (builtins.elem "mcp-helper-reaper" effectiveLinuxFeatureIds) ''
542565
export CODEX_MCP_HELPER_REAPER_SOURCE="${codexMcpHelperReaper}/bin/codex-mcp-helper-reaper"
543566
''}
544-
${pkgs.lib.optionalString (builtins.elem "global-dictation" linuxFeatureIds) ''
567+
${pkgs.lib.optionalString (builtins.elem "global-dictation" effectiveLinuxFeatureIds) ''
545568
export CODEX_GLOBAL_DICTATION_LINUX_SOURCE="${codexGlobalDictationBinary}/bin/codex-global-dictation-linux"
546569
''}
547570
mkdir -p "$HOME" "$npm_config_cache" "$CARGO_HOME"
@@ -571,16 +594,22 @@ PY
571594
'';
572595
};
573596

574-
buildCodexDesktop = { enableComputerUseUi ? false, linuxFeatureIds ? [ ] }:
597+
buildCodexDesktop = { enableComputerUseUi ? false, linuxFeatureIds ? [ ], linuxFeaturesConfigOverride ? null }:
575598
let
576-
normalizedLinuxFeatureIds = nixLinuxFeatures.normalize linuxFeatureIds;
599+
effectiveLinuxFeaturesConfig =
600+
if linuxFeaturesConfigOverride == null then
601+
normalizeLinuxFeaturesConfig { enabled = linuxFeatureIds; }
602+
else
603+
normalizeLinuxFeaturesConfig linuxFeaturesConfigOverride;
604+
normalizedLinuxFeatureIds = effectiveLinuxFeaturesConfig.enabled;
577605
featureArgs = {
578606
inherit enableComputerUseUi;
579607
linuxFeatureIds = normalizedLinuxFeatureIds;
580608
};
581609
payload = mkCodexDesktopPayload {
582610
inherit enableComputerUseUi;
583611
linuxFeatureIds = normalizedLinuxFeatureIds;
612+
linuxFeaturesConfigOverride = effectiveLinuxFeaturesConfig;
584613
};
585614
payloadLauncherPath = launcherPath + pkgs.lib.optionalString
586615
(builtins.elem "global-dictation" normalizedLinuxFeatureIds)
@@ -696,16 +725,8 @@ PY
696725
linuxFeatureIds = [ "remote-mobile-control" ];
697726
};
698727

699-
codexDesktopNixFeatureCheck = codexDesktop.override {
700-
linuxFeatureIds = [
701-
"appshots"
702-
"frameless-titlebar"
703-
"global-dictation"
704-
"mcp-helper-reaper"
705-
"node-repl-reaper"
706-
"open-target-discovery"
707-
"persistent-status-panel"
708-
];
728+
codexDesktopWatchdogFeatureCheck = codexDesktop.override {
729+
linuxFeaturesConfigOverride = watchdogLinuxFeaturesConfig;
709730
};
710731

711732
installer = pkgs.writeShellApplication {
@@ -769,7 +790,8 @@ PY
769790
nix-linux-features-evaluation = import ./nix/linux-features-test.nix {
770791
inherit pkgs self system;
771792
};
772-
nix-linux-features-multi-feature = codexDesktopNixFeatureCheck;
793+
watchdog-linux-features = codexDesktopWatchdogFeatureCheck;
794+
nix-linux-features-multi-feature = codexDesktopWatchdogFeatureCheck;
773795
};
774796

775797
apps.default = {

nix/linux-features-test.nix

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,23 +13,43 @@ let
1313
testFeatureIds = [
1414
"persistent-status-panel"
1515
"appshots"
16+
"codex-wrapper-updater"
1617
"frameless-titlebar"
1718
"global-dictation"
1819
"mcp-helper-reaper"
1920
"remote-mobile-control"
2021
"pet-overlay"
2122
"open-target-discovery"
23+
"remote-control-ui"
24+
"ui-tweaks"
2225
"appshots"
2326
];
2427
normalizedTestFeatureIds = [
2528
"appshots"
29+
"codex-wrapper-updater"
2630
"frameless-titlebar"
2731
"global-dictation"
2832
"mcp-helper-reaper"
2933
"open-target-discovery"
3034
"persistent-status-panel"
3135
"pet-overlay"
36+
"remote-control-ui"
3237
"remote-mobile-control"
38+
"ui-tweaks"
39+
];
40+
watchdogFeatureIds = (builtins.fromJSON (builtins.readFile ../scripts/ci/watchdog-linux-features.json)).enabled;
41+
normalizedWatchdogFeatureIds = [
42+
"appshots"
43+
"codex-wrapper-updater"
44+
"frameless-titlebar"
45+
"global-dictation"
46+
"mcp-helper-reaper"
47+
"node-repl-reaper"
48+
"open-target-discovery"
49+
"persistent-status-panel"
50+
"remote-control-ui"
51+
"remote-mobile-control"
52+
"ui-tweaks"
3353
];
3454

3555
evalHomeManager = moduleConfig:
@@ -126,11 +146,14 @@ let
126146
linuxFeatureIds = [
127147
"remote-mobile-control"
128148
"frameless-titlebar"
149+
"codex-wrapper-updater"
129150
"global-dictation"
130151
"persistent-status-panel"
131152
"mcp-helper-reaper"
132153
"pet-overlay"
133154
"open-target-discovery"
155+
"remote-control-ui"
156+
"ui-tweaks"
134157
"appshots"
135158
"appshots"
136159
];
@@ -260,6 +283,9 @@ in
260283
assert lib.assertMsg
261284
(linuxFeatures.normalize testFeatureIds == normalizedTestFeatureIds)
262285
"Nix Linux feature IDs must be sorted and deduplicated";
286+
assert lib.assertMsg
287+
(linuxFeatures.normalize watchdogFeatureIds == normalizedWatchdogFeatureIds)
288+
"the committed watchdog Linux feature profile drifted from the Nix-supported profile";
263289
assert lib.assertMsg
264290
((homePackage defaultConfig).drvPath == packages.codex-desktop.drvPath)
265291
"the Home Manager default package changed";

nix/linux-features.nix

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,17 @@
22
let
33
supportedFeatureIds = [
44
"appshots"
5+
"codex-wrapper-updater"
56
"frameless-titlebar"
67
"global-dictation"
78
"mcp-helper-reaper"
89
"node-repl-reaper"
910
"open-target-discovery"
1011
"persistent-status-panel"
1112
"pet-overlay"
13+
"remote-control-ui"
1214
"remote-mobile-control"
15+
"ui-tweaks"
1316
];
1417

1518
sortAndDeduplicate = featureIds:

scripts/ci/upstream-dmg-acceptance.test.js

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,9 +202,37 @@ test("Nix hash refresh accepts a validated focused output override", () => {
202202
path.resolve(__dirname, "update-nix-hashes.sh"),
203203
"utf8",
204204
);
205-
205+
const workflow = fs.readFileSync(
206+
path.resolve(__dirname, "../../.github/workflows/ci.yml"),
207+
"utf8",
208+
);
209+
const refreshWorkflow = fs.readFileSync(
210+
path.resolve(__dirname, "../../.github/workflows/update-codex-hash.yml"),
211+
"utf8",
212+
);
213+
const watchdogProfile = JSON.parse(fs.readFileSync(
214+
path.resolve(__dirname, "watchdog-linux-features.json"),
215+
"utf8",
216+
));
217+
218+
assert.deepEqual(watchdogProfile.enabled, [
219+
"appshots",
220+
"codex-wrapper-updater",
221+
"frameless-titlebar",
222+
"global-dictation",
223+
"mcp-helper-reaper",
224+
"node-repl-reaper",
225+
"open-target-discovery",
226+
"persistent-status-panel",
227+
"remote-control-ui",
228+
"remote-mobile-control",
229+
"ui-tweaks",
230+
]);
206231
assert.match(script, /NIX_VERIFY_OUTPUTS/);
207232
assert.match(script, /NIX_COMPARE_REF/);
233+
assert.match(workflow, /\.#checks\.x86_64-linux\.watchdog-linux-features/);
234+
assert.match(refreshWorkflow, /NIX_VERIFY_OUTPUTS/);
235+
assert.match(refreshWorkflow, /\.#checks\.x86_64-linux\.watchdog-linux-features/);
208236
assert.match(script, /Invalid Nix verification output/);
209237
assert.match(script, /run_nix_build "\$VERIFY_LOG" "\$\{PACKAGE_OUTPUTS\[@\]\}"/);
210238
});
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"enabled": [
3+
"appshots",
4+
"codex-wrapper-updater",
5+
"frameless-titlebar",
6+
"global-dictation",
7+
"mcp-helper-reaper",
8+
"node-repl-reaper",
9+
"open-target-discovery",
10+
"persistent-status-panel",
11+
"remote-control-ui",
12+
"remote-mobile-control",
13+
"ui-tweaks"
14+
],
15+
"settings": {}
16+
}

0 commit comments

Comments
 (0)