Mock inference in CI
This commit is contained in:
@@ -56,20 +56,51 @@ jobs:
|
|||||||
id: checkout
|
id: checkout
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@v5
|
||||||
|
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version-file: .node-version
|
||||||
|
|
||||||
|
- name: Start Mock Inference Server
|
||||||
|
id: mock-server
|
||||||
|
run: |
|
||||||
|
node script/mock-inference-server.mjs &
|
||||||
|
echo "pid=$!" >> $GITHUB_OUTPUT
|
||||||
|
# Wait for server to be ready
|
||||||
|
for i in {1..10}; do
|
||||||
|
if curl -s http://localhost:3456/health > /dev/null; then
|
||||||
|
echo "Mock server is ready"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
|
||||||
- name: Test Local Action
|
- name: Test Local Action
|
||||||
id: test-action
|
id: test-action
|
||||||
continue-on-error: true
|
|
||||||
uses: ./
|
uses: ./
|
||||||
with:
|
with:
|
||||||
prompt: hello
|
prompt: hello
|
||||||
|
endpoint: http://localhost:3456
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ github.token }}
|
GITHUB_TOKEN: ${{ github.token }}
|
||||||
|
|
||||||
- name: Print Output
|
- name: Print Output
|
||||||
id: output
|
id: output
|
||||||
continue-on-error: true
|
|
||||||
run: echo "${{ steps.test-action.outputs.response }}"
|
run: echo "${{ steps.test-action.outputs.response }}"
|
||||||
|
|
||||||
|
- name: Verify Output
|
||||||
|
run: |
|
||||||
|
response="${{ steps.test-action.outputs.response }}"
|
||||||
|
if [[ -z "$response" ]]; then
|
||||||
|
echo "Error: No response received"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "Response received: $response"
|
||||||
|
|
||||||
|
- name: Stop Mock Server
|
||||||
|
if: always()
|
||||||
|
run: kill ${{ steps.mock-server.outputs.pid }} || true
|
||||||
|
|
||||||
test-action-prompt-file:
|
test-action-prompt-file:
|
||||||
name: GitHub Actions Test with Prompt File
|
name: GitHub Actions Test with Prompt File
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -79,6 +110,25 @@ jobs:
|
|||||||
id: checkout
|
id: checkout
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@v5
|
||||||
|
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version-file: .node-version
|
||||||
|
|
||||||
|
- name: Start Mock Inference Server
|
||||||
|
id: mock-server
|
||||||
|
run: |
|
||||||
|
node script/mock-inference-server.mjs &
|
||||||
|
echo "pid=$!" >> $GITHUB_OUTPUT
|
||||||
|
# Wait for server to be ready
|
||||||
|
for i in {1..10}; do
|
||||||
|
if curl -s http://localhost:3456/health > /dev/null; then
|
||||||
|
echo "Mock server is ready"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
|
||||||
- name: Create Prompt File
|
- name: Create Prompt File
|
||||||
run: echo "hello" > prompt.txt
|
run: echo "hello" > prompt.txt
|
||||||
|
|
||||||
@@ -87,16 +137,33 @@ jobs:
|
|||||||
|
|
||||||
- name: Test Local Action with Prompt File
|
- name: Test Local Action with Prompt File
|
||||||
id: test-action-prompt-file
|
id: test-action-prompt-file
|
||||||
continue-on-error: true
|
|
||||||
uses: ./
|
uses: ./
|
||||||
with:
|
with:
|
||||||
prompt-file: prompt.txt
|
prompt-file: prompt.txt
|
||||||
system-prompt-file: system-prompt.txt
|
system-prompt-file: system-prompt.txt
|
||||||
|
endpoint: http://localhost:3456
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ github.token }}
|
GITHUB_TOKEN: ${{ github.token }}
|
||||||
|
|
||||||
- name: Print Output
|
- name: Print Output
|
||||||
continue-on-error: true
|
|
||||||
run: |
|
run: |
|
||||||
echo "Response saved to: ${{ steps.test-action-prompt-file.outputs.response-file }}"
|
echo "Response saved to: ${{ steps.test-action-prompt-file.outputs.response-file }}"
|
||||||
cat "${{ steps.test-action-prompt-file.outputs.response-file }}"
|
cat "${{ steps.test-action-prompt-file.outputs.response-file }}"
|
||||||
|
|
||||||
|
- name: Verify Output
|
||||||
|
run: |
|
||||||
|
response_file="${{ steps.test-action-prompt-file.outputs.response-file }}"
|
||||||
|
if [[ ! -f "$response_file" ]]; then
|
||||||
|
echo "Error: Response file not found"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
content=$(cat "$response_file")
|
||||||
|
if [[ -z "$content" ]]; then
|
||||||
|
echo "Error: Response file is empty"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "Response file content: $content"
|
||||||
|
|
||||||
|
- name: Stop Mock Server
|
||||||
|
if: always()
|
||||||
|
run: kill ${{ steps.mock-server.outputs.pid }} || true
|
||||||
|
|||||||
@@ -0,0 +1,71 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
/**
|
||||||
|
* A simple mock OpenAI-compatible inference server for CI testing.
|
||||||
|
* This returns predictable responses without needing real API credentials.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import http from 'http'
|
||||||
|
|
||||||
|
const PORT = process.env.MOCK_SERVER_PORT || 3456
|
||||||
|
|
||||||
|
const server = http.createServer((req, res) => {
|
||||||
|
let body = ''
|
||||||
|
|
||||||
|
req.on('data', chunk => {
|
||||||
|
body += chunk.toString()
|
||||||
|
})
|
||||||
|
|
||||||
|
req.on('end', () => {
|
||||||
|
console.log(`[Mock Server] ${req.method} ${req.url}`)
|
||||||
|
|
||||||
|
// Handle chat completions endpoint
|
||||||
|
if (req.url === '/chat/completions' && req.method === 'POST') {
|
||||||
|
const request = JSON.parse(body)
|
||||||
|
const userMessage = request.messages?.find(m => m.role === 'user')?.content || 'No prompt'
|
||||||
|
|
||||||
|
const response = {
|
||||||
|
id: 'mock-completion-id',
|
||||||
|
object: 'chat.completion',
|
||||||
|
created: Date.now(),
|
||||||
|
model: request.model || 'mock-model',
|
||||||
|
choices: [
|
||||||
|
{
|
||||||
|
index: 0,
|
||||||
|
message: {
|
||||||
|
role: 'assistant',
|
||||||
|
content: `Mock response to: "${userMessage.slice(0, 50)}..."`,
|
||||||
|
},
|
||||||
|
finish_reason: 'stop',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
usage: {
|
||||||
|
prompt_tokens: 10,
|
||||||
|
completion_tokens: 20,
|
||||||
|
total_tokens: 30,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
res.writeHead(200, {'Content-Type': 'application/json'})
|
||||||
|
res.end(JSON.stringify(response))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Health check endpoint
|
||||||
|
if (req.url === '/health' || req.url === '/') {
|
||||||
|
res.writeHead(200, {'Content-Type': 'application/json'})
|
||||||
|
res.end(JSON.stringify({status: 'ok'}))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 404 for unknown routes
|
||||||
|
res.writeHead(404, {'Content-Type': 'application/json'})
|
||||||
|
res.end(JSON.stringify({error: 'Not found'}))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
server.listen(PORT, () => {
|
||||||
|
console.log(`[Mock Server] Listening on http://localhost:${PORT}`)
|
||||||
|
console.log('[Mock Server] Endpoints:')
|
||||||
|
console.log(' POST /chat/completions - Mock chat completion')
|
||||||
|
console.log(' GET /health - Health check')
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user