Skip to content

Commit d566d0c

Browse files
committed
fix
Signed-off-by: Junpu Fan <[email protected]>
1 parent ba6f57d commit d566d0c

File tree

4 files changed

+866
-842
lines changed

4 files changed

+866
-842
lines changed
Lines changed: 321 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,321 @@
1+
name: 'Test Execution'
2+
description: 'Execute tests in container or local mode with comprehensive configuration options'
3+
inputs:
4+
test-name:
5+
description: 'Name of the test (for identification)'
6+
required: true
7+
test-category:
8+
description: 'Category of test (e.g., unit, integration, e2e, benchmark)'
9+
required: false
10+
default: 'test'
11+
aws-account-id:
12+
description: 'AWS Account ID for ECR authentication'
13+
required: false
14+
image-uri:
15+
description: 'Container image URI to test (required for container mode)'
16+
required: false
17+
workflow-id:
18+
description: 'Unique workflow identifier (e.g., PR number, branch name)'
19+
required: true
20+
run-id:
21+
description: 'GitHub run ID'
22+
required: true
23+
run-attempt:
24+
description: 'GitHub run attempt'
25+
required: true
26+
# Test execution mode
27+
execution-mode:
28+
description: 'Test execution mode: "container" (default), "local"'
29+
required: false
30+
default: 'container'
31+
# Container test execution style
32+
container-execution-style:
33+
description: 'How to execute tests in container mode: "exec" (run inside container via docker exec), "external" (run from outside, container as service)'
34+
required: false
35+
default: 'exec'
36+
# External repository
37+
external-repo:
38+
description: 'External repository to checkout (optional)'
39+
required: false
40+
external-repo-ref:
41+
description: 'External repository ref/branch/tag to checkout'
42+
required: false
43+
external-repo-path:
44+
description: 'Path to checkout external repository to'
45+
required: false
46+
default: 'external_source'
47+
# Pre-setup commands (run on runner before test execution)
48+
pre-setup-commands:
49+
description: 'Commands to run on runner before starting test execution (optional)'
50+
required: false
51+
default: ''
52+
# Test setup and execution commands
53+
setup-commands:
54+
description: 'Commands to run for test setup'
55+
required: false
56+
default: ''
57+
test-commands:
58+
description: 'Commands to run for the actual tests'
59+
required: false
60+
default: ''
61+
# Local mode specific commands
62+
local-setup-commands:
63+
description: 'Commands to run for local setup (used in local mode, overrides setup-commands)'
64+
required: false
65+
default: ''
66+
local-test-commands:
67+
description: 'Commands to run for local tests (used in local mode, overrides test-commands)'
68+
required: false
69+
default: ''
70+
# Container configuration
71+
container-gpus:
72+
description: 'GPU configuration for container (e.g., "all", "device=0,1"). Leave empty to disable GPU support.'
73+
required: false
74+
default: ''
75+
container-entrypoint:
76+
description: 'Container entrypoint (used only in exec execution style)'
77+
required: false
78+
default: '/bin/bash'
79+
container-volumes:
80+
description: 'Container volume mounts (JSON array of strings)'
81+
required: false
82+
default: '[".:/workspace"]'
83+
container-environment:
84+
description: 'Container environment variables (JSON array of strings)'
85+
required: false
86+
default: '[]'
87+
container-environment-secrets:
88+
description: 'Container environment variables from secrets (JSON array of secret names)'
89+
required: false
90+
default: '[]'
91+
container-workdir:
92+
description: 'Container working directory (used only in exec execution style)'
93+
required: false
94+
default: '/workspace'
95+
container-ports:
96+
description: 'Container port mappings (JSON array of strings like ["8080:8080", "3000:3000"])'
97+
required: false
98+
default: '[]'
99+
container-additional-args:
100+
description: 'Additional docker run arguments (optional)'
101+
required: false
102+
default: ''
103+
# Container startup configuration
104+
container-startup-delay:
105+
description: 'Seconds to wait after starting container (useful for services that need time to initialize)'
106+
required: false
107+
default: '0'
108+
container-health-check:
109+
description: 'Command to check if container/service is ready (optional)'
110+
required: false
111+
default: ''
112+
show-container-logs:
113+
description: 'Whether to show container logs after startup'
114+
required: false
115+
default: 'false'
116+
# Authentication
117+
ecr-authenticate:
118+
description: 'Whether to authenticate with ECR (set to false for public images)'
119+
required: false
120+
default: 'true'
121+
# Secrets
122+
aws-region:
123+
description: 'AWS region for ECR authentication'
124+
required: false
125+
hugging-face-hub-token:
126+
description: 'Hugging Face Hub token for model downloads'
127+
required: false
128+
129+
runs:
130+
using: 'composite'
131+
steps:
132+
- name: Checkout source code
133+
uses: actions/checkout@v5
134+
shell: bash
135+
136+
- name: Authenticate with ECR
137+
if: inputs.ecr-authenticate == 'true' && inputs.execution-mode == 'container'
138+
uses: ./.github/actions/ecr-authenticate
139+
with:
140+
aws-account-id: ${{ inputs.aws-account-id }}
141+
aws-region: ${{ inputs.aws-region }}
142+
image-uri: ${{ inputs.image-uri }}
143+
144+
- name: Checkout external repository
145+
if: inputs.external-repo != ''
146+
uses: actions/checkout@v5
147+
with:
148+
repository: ${{ inputs.external-repo }}
149+
ref: ${{ inputs.external-repo-ref }}
150+
path: ${{ inputs.external-repo-path }}
151+
152+
- name: Run pre-setup commands
153+
if: inputs.pre-setup-commands != ''
154+
shell: bash
155+
run: |
156+
echo "Running pre-setup commands..."
157+
${{ inputs.pre-setup-commands }}
158+
159+
# ===== CONTAINER EXECUTION MODE =====
160+
- name: Start container
161+
if: inputs.execution-mode == 'container'
162+
shell: bash
163+
run: |
164+
# Build volume arguments
165+
VOLUME_ARGS=""
166+
for volume in $(echo '${{ inputs.container-volumes }}' | jq -r '.[]'); do
167+
# Expand environment variables in volume paths
168+
expanded_volume=$(eval echo "$volume")
169+
VOLUME_ARGS="$VOLUME_ARGS -v $expanded_volume"
170+
done
171+
172+
# Build environment arguments
173+
ENV_ARGS=""
174+
for env in $(echo '${{ inputs.container-environment }}' | jq -r '.[]'); do
175+
ENV_ARGS="$ENV_ARGS -e $env"
176+
done
177+
178+
# Build environment arguments from secrets
179+
for secret_name in $(echo '${{ inputs.container-environment-secrets }}' | jq -r '.[]'); do
180+
case "$secret_name" in
181+
"HF_TOKEN")
182+
if [ -n "${{ inputs.hugging-face-hub-token }}" ]; then
183+
ENV_ARGS="$ENV_ARGS -e HF_TOKEN=${{ inputs.hugging-face-hub-token }}"
184+
fi
185+
;;
186+
"AWS_REGION")
187+
if [ -n "${{ inputs.aws-region }}" ]; then
188+
ENV_ARGS="$ENV_ARGS -e AWS_REGION=${{ inputs.aws-region }}"
189+
fi
190+
;;
191+
*)
192+
echo "Warning: Unknown secret name: $secret_name"
193+
;;
194+
esac
195+
done
196+
197+
# Build port arguments
198+
PORT_ARGS=""
199+
for port in $(echo '${{ inputs.container-ports }}' | jq -r '.[]'); do
200+
PORT_ARGS="$PORT_ARGS -p $port"
201+
done
202+
203+
# Build GPU arguments (optional)
204+
GPU_ARGS=""
205+
if [ -n "${{ inputs.container-gpus }}" ]; then
206+
GPU_ARGS="--gpus=${{ inputs.container-gpus }}"
207+
fi
208+
209+
# Additional arguments
210+
ADDITIONAL_ARGS="${{ inputs.container-additional-args }}"
211+
212+
# Set entrypoint and workdir for exec execution style only
213+
ENTRYPOINT_ARGS=""
214+
WORKDIR_ARGS=""
215+
if [ "${{ inputs.container-execution-style }}" = "exec" ]; then
216+
ENTRYPOINT_ARGS="--entrypoint ${{ inputs.container-entrypoint }}"
217+
WORKDIR_ARGS="--workdir ${{ inputs.container-workdir }}"
218+
fi
219+
220+
echo "Starting container with image: ${{ inputs.image-uri }}"
221+
echo "Container execution style: ${{ inputs.container-execution-style }}"
222+
223+
CONTAINER_ID=$(docker run -d -it --rm \
224+
$GPU_ARGS \
225+
$ENTRYPOINT_ARGS \
226+
$WORKDIR_ARGS \
227+
$VOLUME_ARGS \
228+
$ENV_ARGS \
229+
$PORT_ARGS \
230+
$ADDITIONAL_ARGS \
231+
${{ inputs.image-uri }})
232+
echo "Container started with ID: $CONTAINER_ID"
233+
echo "CONTAINER_ID=$CONTAINER_ID" >> $GITHUB_ENV
234+
235+
- name: Wait for container startup
236+
if: inputs.execution-mode == 'container' && inputs.container-startup-delay != '0'
237+
shell: bash
238+
run: |
239+
echo "Waiting for container startup (${{ inputs.container-startup-delay }} seconds)..."
240+
sleep ${{ inputs.container-startup-delay }}
241+
242+
- name: Show container logs
243+
if: inputs.execution-mode == 'container' && inputs.show-container-logs == 'true'
244+
shell: bash
245+
run: |
246+
echo "Container logs:"
247+
docker logs ${CONTAINER_ID}
248+
249+
- name: Health check container
250+
if: inputs.execution-mode == 'container' && inputs.container-health-check != ''
251+
shell: bash
252+
run: |
253+
echo "Running container health check..."
254+
${{ inputs.container-health-check }}
255+
256+
- name: Setup test environment (container exec style)
257+
if: inputs.execution-mode == 'container' && inputs.container-execution-style == 'exec' && inputs.setup-commands != ''
258+
shell: bash
259+
run: |
260+
echo "Running setup commands inside container for ${{ inputs.test-name }}..."
261+
docker exec ${CONTAINER_ID} sh -c '
262+
set -eux
263+
${{ inputs.setup-commands }}
264+
'
265+
266+
- name: Execute tests (container exec style)
267+
if: inputs.execution-mode == 'container' && inputs.container-execution-style == 'exec' && inputs.test-commands != ''
268+
shell: bash
269+
run: |
270+
echo "Running ${{ inputs.test-category }} tests inside container: ${{ inputs.test-name }}..."
271+
docker exec ${CONTAINER_ID} sh -c '
272+
set -eux
273+
${{ inputs.test-commands }}
274+
'
275+
276+
- name: Setup test environment (container external style)
277+
if: inputs.execution-mode == 'container' && inputs.container-execution-style == 'external' && inputs.setup-commands != ''
278+
shell: bash
279+
run: |
280+
echo "Running setup commands on runner for ${{ inputs.test-name }}..."
281+
${{ inputs.setup-commands }}
282+
283+
- name: Execute tests (container external style)
284+
if: inputs.execution-mode == 'container' && inputs.container-execution-style == 'external' && inputs.test-commands != ''
285+
shell: bash
286+
run: |
287+
echo "Running ${{ inputs.test-category }} tests on runner against container: ${{ inputs.test-name }}..."
288+
${{ inputs.test-commands }}
289+
290+
# ===== LOCAL EXECUTION MODE =====
291+
- name: Setup test environment (local mode)
292+
if: inputs.execution-mode == 'local' && (inputs.local-setup-commands != '' || inputs.setup-commands != '')
293+
shell: bash
294+
run: |
295+
echo "Running local setup commands for ${{ inputs.test-name }}..."
296+
SETUP_CMD="${{ inputs.local-setup-commands }}"
297+
if [ -z "$SETUP_CMD" ]; then
298+
SETUP_CMD="${{ inputs.setup-commands }}"
299+
fi
300+
eval "$SETUP_CMD"
301+
302+
- name: Execute tests (local mode)
303+
if: inputs.execution-mode == 'local' && (inputs.local-test-commands != '' || inputs.test-commands != '')
304+
shell: bash
305+
run: |
306+
echo "Running ${{ inputs.test-category }} tests locally: ${{ inputs.test-name }}..."
307+
TEST_CMD="${{ inputs.local-test-commands }}"
308+
if [ -z "$TEST_CMD" ]; then
309+
TEST_CMD="${{ inputs.test-commands }}"
310+
fi
311+
eval "$TEST_CMD"
312+
313+
# ===== CLEANUP =====
314+
- name: Cleanup container
315+
if: always() && inputs.execution-mode == 'container'
316+
shell: bash
317+
run: |
318+
if [ -n "${CONTAINER_ID:-}" ]; then
319+
echo "Stopping container: $CONTAINER_ID"
320+
docker stop $CONTAINER_ID || true
321+
fi

0 commit comments

Comments
 (0)