Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 86 additions & 0 deletions .github/workflows/docker-smoke-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
name: CI — Docker smoke test

on:
pull_request:
branches: [master]
push:
branches: [master]

jobs:
smoke:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Build Docker image
run: docker build -t codex-proxy-test .

- name: Run container on default port (8080)
run: |
docker run -d --name codex-proxy-test-default -p 8080:8080 codex-proxy-test

# Wait for healthcheck (up to 30s)
echo "Waiting for container to become healthy..."
for i in $(seq 1 15); do
STATUS=$(docker inspect --format='{{.State.Health.Status}}' codex-proxy-test-default 2>/dev/null || echo "starting")
if [ "$STATUS" = "healthy" ]; then
echo "Container is healthy"
break
fi
sleep 2
done

if [ "$STATUS" != "healthy" ]; then
echo "::error::Container did not become healthy within 30s"
docker logs codex-proxy-test-default
exit 1
fi

# Verify /health returns 200
HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:8080/health)
if [ "$HTTP_STATUS" != "200" ]; then
echo "::error::Expected HTTP 200 from /health, got $HTTP_STATUS"
exit 1
fi
echo "/health returned 200"

- name: Cleanup default container
if: always()
run: docker rm -f codex-proxy-test-default || true

- name: Test custom port (8090)
run: |
# Modify config/default.yaml to use port 8090
sed -i 's/port: 8080/port: 8090/' config/default.yaml

# Run container with modified config mounted
docker run -d --name codex-proxy-test-custom -p 8090:8090 -v $(pwd)/config/default.yaml:/app/config/default.yaml codex-proxy-test

# Wait for healthcheck (up to 30s)
echo "Waiting for container to become healthy on custom port..."
for i in $(seq 1 15); do
STATUS=$(docker inspect --format='{{.State.Health.Status}}' codex-proxy-test-custom 2>/dev/null || echo "starting")
if [ "$STATUS" = "healthy" ]; then
echo "Container is healthy"
break
fi
sleep 2
done

if [ "$STATUS" != "healthy" ]; then
echo "::error::Container did not become healthy within 30s"
docker logs codex-proxy-test-custom
exit 1
fi

# Verify /health returns 200 on 8090
HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:8090/health)
if [ "$HTTP_STATUS" != "200" ]; then
echo "::error::Expected HTTP 200 from /health on port 8090, got $HTTP_STATUS"
exit 1
fi
echo "/health returned 200 on port 8090"

- name: Cleanup custom container
if: always()
run: docker rm -f codex-proxy-test-custom || true
45 changes: 45 additions & 0 deletions .github/workflows/electron-smoke-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: CI — Electron smoke test

on:
pull_request:
branches: [master]
paths:
- 'packages/electron/**'
push:
branches: [master]
paths:
- 'packages/electron/**'

jobs:
smoke:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
cache: npm

- name: Install dependencies
run: npm ci

- name: Build root
run: npm run build

- name: Build Electron desktop frontend
run: cd packages/electron && npm run build

- name: Prepare packaging
run: cd packages/electron && node electron/prepare-pack.mjs

- name: Package with electron-builder
run: cd packages/electron && npx electron-builder --linux --dir

- name: Install Playwright Chromium dependencies
run: npx playwright install --with-deps chromium

- name: Test launch and close cleanly
run: xvfb-run npm test -- packages/electron/__tests__/launch/smoke.test.ts
29 changes: 29 additions & 0 deletions .github/workflows/web-smoke-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: CI — Web smoke test

on:
pull_request:
branches: [master]
push:
branches: [master]

jobs:
smoke:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
cache: npm

- name: Install dependencies
run: npm ci

- name: Build
run: npm run build

- name: Test frontend build and server
run: npm test -- src/__tests__/web-smoke.test.ts
73 changes: 69 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

44 changes: 44 additions & 0 deletions packages/electron/__tests__/launch/smoke.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { test, expect } from "vitest";
import { _electron } from "playwright";
import { resolve } from "path";
import { readdirSync } from "fs";

// Increase timeout for the launch test
test("Electron app packages and launches main window", async () => {
// Find the linux unpacked directory
const unpackedDir = resolve(import.meta.dirname, "../../release/linux-unpacked");

// Find the actual executable dynamically
const files = readdirSync(unpackedDir);
const executableName = files.find(file => {
return !file.includes(".") && !["locales", "resources"].includes(file) && !file.includes("chrome-sandbox") && !file.includes("chrome_crashpad_handler");
});

if (!executableName) {
throw new Error("Could not find executable in linux-unpacked directory");
}

const executablePath = resolve(unpackedDir, executableName);

// Launch the app
const electronApp = await _electron.launch({
executablePath,
args: ["--no-sandbox", "--disable-gpu", "--disable-dev-shm-usage"],
});

// Verify app launched correctly by waiting for the first window
const window = await electronApp.firstWindow();

// Verify it exists (it resolves to a Playwright Page object)
expect(window).toBeDefined();

// Wait for it to be ready
await window.waitForLoadState("domcontentloaded");

// Get window title to verify it loaded our app
const title = await window.title();
expect(title).toBe("Codex Proxy Developer Dashboard");

// Close cleanly
await electronApp.close();
}, 60000);
4 changes: 3 additions & 1 deletion packages/electron/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@
"electron-updater": "^6.3.0"
},
"devDependencies": {
"@playwright/test": "^1.58.2",
"electron": "^35.7.5",
"electron-builder": "^26.0.0",
"esbuild": "^0.25.12"
"esbuild": "^0.25.12",
"playwright": "^1.58.2"
}
}
Loading
Loading