Compare commits

...

1 Commits

Author SHA1 Message Date
Affaan Mustafa
d728312b58 fix(ci): resolve cross-platform test failures
- Sanity check script (check-codex-global-state.sh) now falls back to
  grep -E when ripgrep is not available, fixing the codex-hooks sync
  test on all CI platforms. Patterns converted to POSIX ERE for
  portability.
- Unicode safety test accepts both / and \ path separators so the
  executable-file assertion passes on Windows.
- Gacha test sets PYTHONUTF8=1 so Python uses UTF-8 stdout encoding on
  Windows instead of cp1252, preventing UnicodeEncodeError on box-drawing
  characters.
- Quoted-hook-path test skipped on Windows where NTFS disallows
  double-quote characters in filenames.
2026-03-31 01:38:00 -04:00
4 changed files with 25 additions and 12 deletions

View File

@@ -8,6 +8,14 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
CODEX_HOME="${CODEX_HOME:-$HOME/.codex}" CODEX_HOME="${CODEX_HOME:-$HOME/.codex}"
# Use rg if available, otherwise fall back to grep -E.
# All patterns in this script must be POSIX ERE compatible.
if command -v rg >/dev/null 2>&1; then
search_file() { rg -n "$1" "$2" >/dev/null 2>&1; }
else
search_file() { grep -En "$1" "$2" >/dev/null 2>&1; }
fi
CONFIG_FILE="$CODEX_HOME/config.toml" CONFIG_FILE="$CODEX_HOME/config.toml"
AGENTS_FILE="$CODEX_HOME/AGENTS.md" AGENTS_FILE="$CODEX_HOME/AGENTS.md"
PROMPTS_DIR="$CODEX_HOME/prompts" PROMPTS_DIR="$CODEX_HOME/prompts"
@@ -48,7 +56,7 @@ require_file() {
check_config_pattern() { check_config_pattern() {
local pattern="$1" local pattern="$1"
local label="$2" local label="$2"
if rg -n "$pattern" "$CONFIG_FILE" >/dev/null 2>&1; then if search_file "$pattern" "$CONFIG_FILE"; then
ok "$label" ok "$label"
else else
fail "$label" fail "$label"
@@ -58,7 +66,7 @@ check_config_pattern() {
check_config_absent() { check_config_absent() {
local pattern="$1" local pattern="$1"
local label="$2" local label="$2"
if rg -n "$pattern" "$CONFIG_FILE" >/dev/null 2>&1; then if search_file "$pattern" "$CONFIG_FILE"; then
fail "$label" fail "$label"
else else
ok "$label" ok "$label"
@@ -73,13 +81,13 @@ require_file "$CONFIG_FILE" "Global config.toml"
require_file "$AGENTS_FILE" "Global AGENTS.md" require_file "$AGENTS_FILE" "Global AGENTS.md"
if [[ -f "$AGENTS_FILE" ]]; then if [[ -f "$AGENTS_FILE" ]]; then
if rg -n '^# Everything Claude Code \(ECC\) — Agent Instructions' "$AGENTS_FILE" >/dev/null 2>&1; then if search_file '^# Everything Claude Code \(ECC\)' "$AGENTS_FILE"; then
ok "AGENTS contains ECC root instructions" ok "AGENTS contains ECC root instructions"
else else
fail "AGENTS missing ECC root instructions" fail "AGENTS missing ECC root instructions"
fi fi
if rg -n '^# Codex Supplement \(From ECC \.codex/AGENTS\.md\)' "$AGENTS_FILE" >/dev/null 2>&1; then if search_file '^# Codex Supplement \(From ECC \.codex/AGENTS\.md\)' "$AGENTS_FILE"; then
ok "AGENTS contains ECC Codex supplement" ok "AGENTS contains ECC Codex supplement"
else else
fail "AGENTS missing ECC Codex supplement" fail "AGENTS missing ECC Codex supplement"
@@ -87,11 +95,11 @@ if [[ -f "$AGENTS_FILE" ]]; then
fi fi
if [[ -f "$CONFIG_FILE" ]]; then if [[ -f "$CONFIG_FILE" ]]; then
check_config_pattern '^multi_agent\s*=\s*true' "multi_agent is enabled" check_config_pattern '^multi_agent[[:space:]]*=[[:space:]]*true' "multi_agent is enabled"
check_config_absent '^\s*collab\s*=' "deprecated collab flag is absent" check_config_absent '^[[:space:]]*collab[[:space:]]*=' "deprecated collab flag is absent"
# persistent_instructions is recommended but optional; warn instead of fail # persistent_instructions is recommended but optional; warn instead of fail
# so users who rely on AGENTS.md alone are not blocked (#967). # so users who rely on AGENTS.md alone are not blocked (#967).
if rg -n '^[[:space:]]*persistent_instructions\s*=' "$CONFIG_FILE" >/dev/null 2>&1; then if search_file '^[[:space:]]*persistent_instructions[[:space:]]*=' "$CONFIG_FILE"; then
ok "persistent_instructions is configured" ok "persistent_instructions is configured"
else else
warn "persistent_instructions is not set (recommended but optional)" warn "persistent_instructions is not set (recommended but optional)"
@@ -105,7 +113,7 @@ if [[ -f "$CONFIG_FILE" ]]; then
'mcp_servers.sequential-thinking' \ 'mcp_servers.sequential-thinking' \
'mcp_servers.context7' 'mcp_servers.context7'
do do
if rg -n "^\[$section\]" "$CONFIG_FILE" >/dev/null 2>&1; then if search_file "^\[$section\]" "$CONFIG_FILE"; then
ok "MCP section [$section] exists" ok "MCP section [$section] exists"
else else
fail "MCP section [$section] missing" fail "MCP section [$section] missing"
@@ -115,11 +123,11 @@ if [[ -f "$CONFIG_FILE" ]]; then
has_context7_legacy=0 has_context7_legacy=0
has_context7_current=0 has_context7_current=0
if rg -n '^\[mcp_servers\.context7\]' "$CONFIG_FILE" >/dev/null 2>&1; then if search_file '^\[mcp_servers\.context7\]' "$CONFIG_FILE"; then
has_context7_legacy=1 has_context7_legacy=1
fi fi
if rg -n '^\[mcp_servers\.context7-mcp\]' "$CONFIG_FILE" >/dev/null 2>&1; then if search_file '^\[mcp_servers\.context7-mcp\]' "$CONFIG_FILE"; then
has_context7_current=1 has_context7_current=1
fi fi

View File

@@ -89,7 +89,7 @@ if (
const result = runCheck(root, ['--write']); const result = runCheck(root, ['--write']);
assert.notStrictEqual(result.status, 0, result.stdout + result.stderr); assert.notStrictEqual(result.status, 0, result.stdout + result.stderr);
assert.match(result.stderr, /scripts\/sample\.js:1:23 emoji U\+1F680/); assert.match(result.stderr, /scripts[/\\]sample\.js:1:23 emoji U\+1F680/);
assert.strictEqual(fs.readFileSync(scriptFile, 'utf8'), original); assert.strictEqual(fs.readFileSync(scriptFile, 'utf8'), original);
}) })
) )

View File

@@ -66,7 +66,11 @@ function makeHermeticCodexEnv(homeDir, codexDir, extraEnv = {}) {
let passed = 0; let passed = 0;
let failed = 0; let failed = 0;
if ( // Windows NTFS does not allow double-quote characters in file paths,
// so the quoted-path shell-injection test is only meaningful on Unix.
if (os.platform() === 'win32') {
console.log(' - install-global-git-hooks.sh quoted paths (skipped on Windows)');
} else if (
test('install-global-git-hooks.sh handles quoted hook paths without shell injection', () => { test('install-global-git-hooks.sh handles quoted hook paths without shell injection', () => {
const homeDir = createTempDir('codex-hooks-home-'); const homeDir = createTempDir('codex-hooks-home-');
const weirdHooksDir = path.join(homeDir, 'git-hooks "quoted"'); const weirdHooksDir = path.join(homeDir, 'git-hooks "quoted"');

View File

@@ -30,6 +30,7 @@ function runGacha(pythonBin, arg) {
return spawnSync(pythonBin, [SCRIPT, arg], { return spawnSync(pythonBin, [SCRIPT, arg], {
encoding: 'utf8', encoding: 'utf8',
maxBuffer: 10 * 1024 * 1024, maxBuffer: 10 * 1024 * 1024,
env: { ...process.env, PYTHONUTF8: '1' },
}); });
} }