Skip to content

build(deps): bump the prod-cargo-major-dependencies group across 1 directory with 5 updates #2495

build(deps): bump the prod-cargo-major-dependencies group across 1 directory with 5 updates

build(deps): bump the prod-cargo-major-dependencies group across 1 directory with 5 updates #2495

Workflow file for this run

name: CI check
on:
pull_request:
branches:
- main
- "[0-9]+.[0-9]+.x"
paths-ignore:
- "docs/**"
types:
- opened
- reopened
- synchronize
- ready_for_review
pull_request_review:
types:
- submitted
push:
branches:
- main
- trigger-ci-workflow
paths-ignore:
- "docs/**"
workflow_dispatch:
permissions:
contents: write
actions: read
pull-requests: write
env:
CARGO_TERM_COLOR: always
RUST_BACKTRACE: 1
RUST_LOG: debug
concurrency:
group: ci-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
defaults:
run:
shell: bash
jobs:
changesets:
if: ${{ github.event_name != 'pull_request' || (!startsWith(github.head_ref,
'release/') && !github.event.pull_request.draft) }}
uses: ./.github/workflows/changesets.yaml
name: Changesets
typos:
name: Typos
if: github.event.pull_request.draft != true && (github.event_name !=
'pull_request' || !startsWith(github.head_ref, 'release/'))
runs-on: ${{ github.repository == 'oxy-hq/oxy-internal' && 'ubuntu-slim' ||
'ubuntu-latest' }}
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Check typos
uses: crate-ci/typos@v1.45.1
fmt-web:
name: Format web
needs: [ changesets, typos ]
concurrency:
group: fmt-web-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
if: needs.changesets.outputs.web-app == 'true'
runs-on: ${{ github.repository == 'oxy-hq/oxy-internal' && 'ubuntu-slim' ||
'ubuntu-latest' }}
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- uses: pnpm/action-setup@v5
with:
run_install: false
- name: Install Node.js
uses: actions/setup-node@v6
id: setup-node
with:
node-version: 24.x
cache: "pnpm"
- name: Run pnpm install
run: pnpm install --frozen-lockfile --prefer-offline
- name: Run lint-staged
shell: bash
run: |
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
pnpm lint-staged --diff="origin/${{ github.base_ref }}...origin/${{ github.head_ref }}"
elif [[ "${{ github.event_name }}" == "push" ]]; then
pnpm lint-staged --diff="${{ github.event.before }}...${{ github.event.after }}"
fi
build-web:
name: Build web
needs: [ changesets, typos ]
concurrency:
group: build-web-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
if: needs.changesets.outputs.web-app == 'true'
runs-on: "ubuntu-latest"
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- uses: pnpm/action-setup@v5
with:
run_install: false
- name: Install Node.js
uses: actions/setup-node@v6
id: setup-node
with:
node-version: 24.x
cache: "pnpm"
# Cache TypeScript build info for incremental compilation
# Key on tsconfig only — tsbuildinfo handles incremental source changes internally
- name: Cache TypeScript build info
uses: actions/cache@v5
with:
path: |
web-app/tsconfig.app.tsbuildinfo
web-app/tsconfig.node.tsbuildinfo
key: typescript-${{ runner.os }}-${{ hashFiles('web-app/tsconfig*.json') }}
restore-keys: |
typescript-${{ runner.os }}-
# Cache Vite pre-bundled deps (only invalidates when dependencies change, not source)
- name: Cache Vite
uses: actions/cache@v5
with:
path: |
web-app/node_modules/.vite
web-app/.vite
key: vite-${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml',
'web-app/vite.config.*') }}
restore-keys: |
vite-${{ runner.os }}-
# Cache Turbo for monorepo builds
- name: Cache Turbo
uses: actions/cache@v5
with:
path: .turbo
key: turbo-${{ runner.os }}-${{ github.sha }}
restore-keys: |
turbo-${{ runner.os }}-
- name: Install dependencies & Build web-app
env:
NODE_OPTIONS: "--max-old-space-size=8192"
# Enable Turbo remote caching (optional - configure if using Turbo remote cache)
# TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
# TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
run: |
# Install with frozen lockfile for reproducibility
pnpm install --frozen-lockfile --prefer-offline
# Build using Turbo for better caching
pnpm build
cargo-check-and-test:
concurrency:
group: cargo-check-and-test-${{ matrix.task }}-${{
github.event.pull_request.number || github.ref }}
cancel-in-progress: true
needs: [ changesets, typos ]
if: needs.changesets.outputs.oxy == 'true'
name: Format cargo, check & test (${{ matrix.task }})
runs-on: "ubuntu-latest"
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
BIGQUERY_SAMPLE_KEY: ${{ secrets.BIGQUERY_SAMPLE_KEY }}
GEMINI_API_KEY: "empty"
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
DOMO_DEVELOPER_TOKEN: "empty"
# line-tables-only debug: sufficient for llvm-cov, ~60% smaller than default debug = 2
CARGO_PROFILE_DEV_DEBUG: "1"
strategy:
fail-fast: true
matrix:
task: [ check, test ]
services:
postgres:
image: postgres:18-alpine
env:
POSTGRES_USER: admin
POSTGRES_PASSWORD: password
POSTGRES_DB: default
ports:
- 5432:5432
options: >-
--health-cmd "pg_isready -U admin -d default" --health-interval 10s
--health-timeout 5s --health-retries 5
steps:
# - name: Free disk space
# if: matrix.task == 'test'
# uses: jlumbroso/free-disk-space@main
# with:
# tool-cache: false
# android: true
# dotnet: true
# haskell: true
# large-packages: true
# docker-images: true
# swap-storage: true
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Collect Workflow Telemetry
uses: catchpoint/workflow-telemetry-action@v2
with:
theme: dark
metric_frequency: 3
comment_on_pr: false
- uses: rui314/setup-mold@v1
if: runner.os == 'Linux'
with:
make-default: true
- name: Prep Rust
uses: dtolnay/rust-toolchain@stable
with:
components: clippy, rustfmt
- name: Install cargo tools
uses: taiki-e/install-action@v2
with:
tool: nextest
- name: Prep cargo cache
uses: Swatinem/rust-cache@v2
with:
shared-key: ${{ matrix.task }}
# protobuf is required by lance https://github.com/lancedb/lance/issues/3073
- name: Install Protoc
uses: arduino/setup-protoc@v3
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Install PostgreSQL client
run: |
sudo apt-get update
sudo apt-get install -y postgresql-client
- name: Wait for Postgres
run: |
until pg_isready -h localhost -p 5432 -U admin; do
echo "Waiting for Postgres..."
sleep 2
done
echo "Postgres is ready!"
env:
PGPASSWORD: password
- name: Run task
env:
OXY_DATABASE_URL: "postgresql://admin:password@localhost:5432/default"
OXY_BIN: "${{ github.workspace }}/target/ci/oxy"
run: |
if [[ "${{ matrix.task }}" == "check" ]]; then
cargo clippy --profile ci --verbose --workspace --fix
elif [[ "${{ matrix.task }}" == "test" ]]; then
touch examples/bigquery-sample.key
echo $BIGQUERY_SAMPLE_KEY > examples/bigquery-sample.key
cargo build --profile ci
./target/ci/oxy migrate
# Run tests (no coverage instrumentation)
cargo nextest run --cargo-profile ci --workspace --no-fail-fast
./target/ci/oxy gen-config-schema --check
fi
- name: Upload oxy binary artifact
if: matrix.task == 'test'
uses: actions/upload-artifact@v7
with:
name: oxy-binary-ci
path: target/ci/oxy
retention-days: 1
smoke-test-enterprise:
name: Smoke test (oxy start --enterprise)
needs: [ changesets, typos, cargo-check-and-test ]
concurrency:
group: smoke-test-enterprise-${{ github.event.pull_request.number || github.ref
}}
cancel-in-progress: true
if: github.repository == 'oxy-hq/oxy-internal' && needs.changesets.outputs.oxy
== 'true'
runs-on: ubuntu-latest
timeout-minutes: 20
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
BIGQUERY_SAMPLE_KEY: ${{ secrets.BIGQUERY_SAMPLE_KEY }}
GEMINI_API_KEY: "empty"
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
DOMO_DEVELOPER_TOKEN: "empty"
OXY_LOG_LEVEL: debug
steps:
- uses: actions/checkout@v6
- uses: gacts/install-hurl@v1
- name: Download oxy binary
uses: actions/download-artifact@v8
with:
name: oxy-binary-ci
path: ./bin
- name: Make binary executable
run: |
chmod +x ./bin/oxy
echo "$GITHUB_WORKSPACE/bin" >> $GITHUB_PATH
- name: Start oxy
working-directory: examples
run: |
oxy start --enterprise --clean &
echo "OXY_PID=$!" >> $GITHUB_ENV
# Wait for server (max 10 min)
for i in {1..120}; do
curl -sf --max-time 10 http://localhost:3000/api/health > /dev/null && break
[ $i -eq 120 ] && { docker ps -a; docker logs oxy-postgres 2>&1 | tail -50; exit 1; }
sleep 5
done
- name: Verify containers
run: |
for c in oxy-postgres; do
docker ps --format "{{.Names}}" | grep -q "^${c}$" || { echo "::error::$c not running"; exit 1; }
done
- name: Smoke test - CLI
working-directory: examples
run: |
oxy status
oxy sync -o
oxy build
oxy validate
oxy run data_fruit/example_food_calories.sql
- name: Smoke test - HTTP (Hurl)
run: |
set -o pipefail
echo '## Smoke Test Results' >> $GITHUB_STEP_SUMMARY
hurl --test tests/smoke/smoke.hurl 2>&1 | tee -a $GITHUB_STEP_SUMMARY
- name: Test restart (data persistence)
working-directory: examples
run: |
kill -TERM $OXY_PID 2>/dev/null || true
for i in {1..30}; do kill -0 $OXY_PID 2>/dev/null || break; sleep 1; done
sleep 2
docker volume ls | grep -q oxy || { echo "::error::Volumes not persisted"; exit 1; }
oxy start --enterprise &
echo "OXY_PID=$!" >> $GITHUB_ENV
for i in {1..60}; do
curl -sf --max-time 10 http://localhost:3000/api/health > /dev/null && break
[ $i -eq 60 ] && { docker ps -a; exit 1; }
sleep 5
done
- name: Verify restart
run: |
for c in oxy-postgres; do
docker ps --format "{{.Names}}" | grep -q "^${c}$" || { echo "::error::$c not running after restart"; exit 1; }
done
set -o pipefail
hurl --test tests/smoke/smoke.hurl 2>&1 | tee -a $GITHUB_STEP_SUMMARY
- name: Cleanup
if: always()
run: |
kill -TERM $OXY_PID 2>/dev/null || true; sleep 3
docker rm -f oxy-postgres 2>/dev/null || true
e2e-tests:
name: E2E Tests (Playwright)
needs: [ changesets, typos, cargo-check-and-test ]
# 💰 COST SAVING: Only run on approved PRs, pushes to oxy-hq/oxy main, or manual trigger
if: |
needs.changesets.outputs.oxy == 'true' && (
github.event_name == 'workflow_dispatch' ||
(
github.event_name == 'push' &&
(needs.changesets.outputs.web-app == 'true' || needs.changesets.outputs.oxy == 'true')
) ||
(
github.event_name == 'pull_request_review' &&
github.event.review.state == 'approved' &&
(needs.changesets.outputs.web-app == 'true' || needs.changesets.outputs.oxy == 'true')
)
)
runs-on: ubuntu-latest
concurrency:
group: e2e-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
env:
OXY_STATE_DIR: ${{ github.workspace }}/examples
OXY_DATABASE_URL: postgresql://admin:password@localhost:5432/default
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
BIGQUERY_SAMPLE_KEY: ${{ secrets.BIGQUERY_SAMPLE_KEY }}
GEMINI_API_KEY: "empty"
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
DOMO_DEVELOPER_TOKEN: "empty"
services:
postgres:
image: postgres:18-alpine
env:
POSTGRES_USER: admin
POSTGRES_PASSWORD: password
POSTGRES_DB: default
ports:
- 5432:5432
options: >-
--health-cmd "pg_isready -U admin -d default" --health-interval 10s
--health-timeout 5s --health-retries 5
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Collect Workflow Telemetry
uses: catchpoint/workflow-telemetry-action@v2
with:
theme: dark
metric_frequency: 3
comment_on_pr: false
# Download pre-built binary (shared artifact!)
- name: Download oxy binary
uses: actions/download-artifact@v8
with:
name: oxy-binary-ci
path: ./bin
- name: Make binary executable
run: |
chmod +x ./bin/oxy
echo "$GITHUB_WORKSPACE/bin" >> $GITHUB_PATH
# Setup Node.js and pnpm for web-app tests
- name: Setup pnpm
uses: pnpm/action-setup@v5
with:
run_install: false
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: 24.x
cache: "pnpm"
# Cache Playwright browsers - significant time saver!
- name: Cache Playwright browsers
uses: actions/cache@v5
id: playwright-cache
with:
path: ~/.cache/ms-playwright
key: playwright-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}
restore-keys: |
playwright-${{ runner.os }}-
# Cache Turbo for monorepo builds
- name: Cache Turbo
uses: actions/cache@v5
with:
path: .turbo
key: turbo-${{ runner.os }}-${{ github.sha }}
restore-keys: |
turbo-${{ runner.os }}-
- name: Install dependencies
env:
NODE_OPTIONS: "--max-old-space-size=8192"
run: pnpm install --frozen-lockfile --prefer-offline
- name: Install Playwright browsers
if: steps.playwright-cache.outputs.cache-hit != 'true'
working-directory: web-app
run: pnpm exec playwright install --with-deps chromium
- name: Install Playwright system dependencies only
if: steps.playwright-cache.outputs.cache-hit == 'true'
working-directory: web-app
run: pnpm exec playwright install-deps chromium
# Setup BigQuery credentials if needed
- name: Setup BigQuery credentials
if: env.BIGQUERY_SAMPLE_KEY
run: |
touch examples/bigquery-sample.key
echo "$BIGQUERY_SAMPLE_KEY" > examples/bigquery-sample.key
# Run consistency tests using pre-built binary
- name: Run consistency tests
working-directory: demo_project
run: |
echo "Running consistency tests for default.agent.yml..."
oxy sync -o
oxy build
oxy test default.agent.yml \
--format json \
--min-accuracy 0.8 \
--threshold-mode average \
| tee consistency-test-results.json
echo "Consistency tests completed successfully!"
- name: Upload consistency test results
uses: actions/upload-artifact@v7
if: always()
with:
name: consistency-test-results
path: demo_project/consistency-test-results.json
retention-days: 1
- name: Show consistency test summary
if: always()
run: |
if [ -f demo_project/consistency-test-results.json ]; then
echo "=== Consistency Test Results ==="
echo ""
cat demo_project/consistency-test-results.json
echo ""
echo "Full results available in artifacts: consistency-test-results"
else
echo "No consistency test results file found"
fi
# Start backend server in background
- name: Start Oxy backend server
working-directory: examples
run: |
# Using pre-built binary - no compilation needed!
nohup oxy serve > ../oxy-server.log 2>&1 &
echo $! > /tmp/oxy-server.pid
echo "Backend server started with PID: $(cat /tmp/oxy-server.pid)"
# Wait for backend to be ready
- name: Wait for backend server
id: wait-backend
run: |
echo "Waiting for backend server to be ready..."
timeout 10 bash -c 'until curl -k -s http://localhost:3000/api/health > /dev/null 2>&1; do echo "Waiting for health endpoint..."; sleep 2; done'
echo "Backend health endpoint is responding!"
# Give the backend additional time to scan and load apps from the examples directory
echo "Waiting for backend to initialize apps..."
sleep 10
echo "Backend server should now be fully ready!"
- name: Show backend server logs if wait failed
if: steps.wait-backend.outcome == 'failure'
run: |
echo "=== Backend Server Logs (from wait failure) ==="
if [ -f oxy-server.log ]; then
tail -n 200 oxy-server.log || true
else
echo "No server logs found at oxy-server.log"
ls -la || true
fi
# Run E2E tests
- name: Run Playwright tests
id: run-playwright
timeout-minutes: 20
env:
PLAYWRIGHT_WORKERS: 2
run: |
cd web-app
pnpm test:e2e
# Upload test results and traces
- name: Upload Playwright report
uses: actions/upload-artifact@v7
if: always()
with:
name: playwright-report
path: web-app/playwright-report/
retention-days: 1
- name: Upload test results with traces
uses: actions/upload-artifact@v7
if: failure()
with:
name: playwright-results
path: web-app/test-results/
retention-days: 1
- name: Show trace instructions
if: failure()
run: |
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "📹 Test traces, screenshots, and videos have been captured!"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
echo "To view the test traces:"
echo " 1. Download the 'playwright-results' artifact from this workflow run"
echo " 2. Extract the zip file"
echo " 3. Run: npx playwright show-trace path/to/trace.zip"
echo ""
echo "The trace viewer will open in your browser with:"
echo " • Full test execution timeline"
echo " • Screenshots at each step"
echo " • Network requests/responses"
echo " • Console logs"
echo " • DOM snapshots"
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
# Cleanup
- name: Stop backend server
if: always()
run: |
if [ -f /tmp/oxy-server.pid ]; then
kill $(cat /tmp/oxy-server.pid) || true
echo "Backend server stopped"
fi
- name: Show server logs
if: failure()
run: |
echo "=== Backend Server Logs ==="
if [ -f oxy-server.log ]; then
tail -n 200 oxy-server.log
else
echo "No server logs found at oxy-server.log"
fi
echo ""
echo "=== Checking if server process is still running ==="
if [ -f /tmp/oxy-server.pid ]; then
ps -p $(cat /tmp/oxy-server.pid) || echo "Server process not running"
fi
# Send Slack notification on push failure to oxy main
- name: Find Slack user
if: failure() && steps.run-playwright.outcome == 'failure' && github.event_name
== 'push' && github.repository == 'oxy-hq/oxy'
id: find-slack-user
uses: scribd/find-slack-user-action@v1
continue-on-error: true
with:
slack-token: ${{ secrets.SLACK_BOT_TOKEN }}
email: ${{ github.event.head_commit.author.email }}
- name: Prepare Slack notification message
if: failure() && steps.run-playwright.outcome == 'failure' && github.event_name
== 'push' && github.repository == 'oxy-hq/oxy'
id: prepare-slack
run: |
GITHUB_USER="${{ github.event.head_commit.author.username || github.actor }}"
AUTHOR_NAME="${{ github.event.head_commit.author.name || github.actor }}"
SLACK_MEMBER_ID="${{ steps.find-slack-user.outputs.member-id }}"
echo "GitHub user: $GITHUB_USER"
echo "Slack member ID: ${SLACK_MEMBER_ID:-not found}"
if [ -n "$SLACK_MEMBER_ID" ]; then
echo "✓ Found Slack user for $GITHUB_USER"
AUTHOR_TEXT="*Author:*\n<@${SLACK_MEMBER_ID}> (${AUTHOR_NAME})"
MENTION_TEXT="<@${SLACK_MEMBER_ID}> - E2E tests failed on your commit"
else
echo "✗ No Slack user found for $GITHUB_USER"
AUTHOR_TEXT="*Author:*\n${AUTHOR_NAME} (@${GITHUB_USER})"
MENTION_TEXT=""
fi
# Export for next step
echo "author_text<<EOF" >> $GITHUB_OUTPUT
echo "$AUTHOR_TEXT" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
echo "mention_text<<EOF" >> $GITHUB_OUTPUT
echo "$MENTION_TEXT" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: Send Slack notification
if: failure() && steps.run-playwright.outcome == 'failure' && github.event_name
== 'push' && github.repository == 'oxy-hq/oxy'
uses: slackapi/slack-github-action@v3.0.1
with:
method: chat.postMessage
token: ${{ secrets.SLACK_BOT_TOKEN }}
payload: |
{
"channel": "eng-events-e2e",
"text": "🚨 E2E Tests Failed on oxy Main Branch - ${{ steps.prepare-slack.outputs.mention_text || github.event.head_commit.author.name }}",
"blocks": [
{
"type": "header",
"text": {
"type": "plain_text",
"text": "🚨 E2E Tests Failed on oxy Main Branch"
}
},
${{ steps.prepare-slack.outputs.mention_text && format('{{ "type": "section", "text": {{ "type": "mrkdwn", "text": "{0}" }} }},', steps.prepare-slack.outputs.mention_text) || '' }}
{
"type": "section",
"fields": [
{
"type": "mrkdwn",
"text": "*Repository:*\noxy-hq/oxy"
},
{
"type": "mrkdwn",
"text": "*Branch:*\nmain"
},
{
"type": "mrkdwn",
"text": "*Commit:*\n<${{ github.event.head_commit.url }}|${{ github.sha }}>"
},
{
"type": "mrkdwn",
"text": "${{ steps.prepare-slack.outputs.author_text }}"
}
]
},
{
"type": "actions",
"elements": [
{
"type": "button",
"text": {
"type": "plain_text",
"text": "View Workflow Run"
},
"url": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
},
{
"type": "button",
"text": {
"type": "plain_text",
"text": "View Commit"
},
"url": "${{ github.event.head_commit.url }}"
}
]
}
]
}