real-e2e.yml
1 name: Real E2E Tests 2 3 permissions: 4 contents: read 5 6 on: 7 pull_request: 8 branches: [ main ] 9 paths: 10 - 'server/opensandbox_server/**' 11 - 'components/execd/**' 12 - 'components/egress/**' 13 - 'sdks/**' 14 - 'tests/**' 15 push: 16 branches: [ main ] 17 18 concurrency: 19 group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} 20 cancel-in-progress: true 21 22 jobs: 23 python-e2e: 24 name: Python E2E (docker bridge) 25 runs-on: self-hosted 26 env: 27 UV_BIN: /home/admin/.local/bin 28 steps: 29 - name: Checkout code 30 uses: actions/checkout@v6 31 32 - name: Set up uv PATH and verify 33 run: | 34 echo "${UV_BIN}" >> "$GITHUB_PATH" 35 export PATH="${UV_BIN}:${PATH}" 36 uv --version 37 uv run python --version 38 39 - name: Clean up previous E2E resources 40 run: | 41 docker ps -aq --filter "label=opensandbox" | xargs -r docker rm -f || true 42 # Remove root-owned files from previous sandbox runs by mounting parent dir 43 docker run --rm -v /tmp:/host_tmp alpine rm -rf /host_tmp/opensandbox-e2e || true 44 docker image prune -f || true 45 46 - name: Build local egress image 47 run: docker build -t opensandbox/egress:local -f components/egress/Dockerfile . 48 49 - name: Run tests 50 run: | 51 set -e 52 53 # Create config file 54 cat <<EOF > ~/.sandbox.toml 55 [server] 56 host = "127.0.0.1" 57 port = 8080 58 api_key = "" 59 [log] 60 level = "INFO" 61 [runtime] 62 type = "docker" 63 execd_image = "opensandbox/execd:local" 64 [egress] 65 image = "opensandbox/egress:local" 66 mode = "dns" 67 [docker] 68 network_mode = "bridge" 69 [storage] 70 allowed_host_paths = ["/tmp/opensandbox-e2e"] 71 [renew_intent] 72 enabled = true 73 min_interval_seconds = 60 74 EOF 75 76 ./scripts/python-e2e.sh 77 78 - name: Eval server logs 79 if: ${{ always() }} 80 run: cat server/server.log 81 82 - name: Upload execd logs 83 if: always() 84 uses: actions/upload-artifact@v7 85 with: 86 name: execd-log-for-python-e2e 87 path: /tmp/opensandbox-e2e/logs/ 88 retention-days: 5 89 90 - name: Clean up after E2E 91 if: always() 92 run: | 93 docker ps -aq --filter "label=opensandbox" | xargs -r docker rm -f || true 94 docker run --rm -v /tmp:/host_tmp alpine rm -rf /host_tmp/opensandbox-e2e || true 95 pkill -f "python -m opensandbox_server.main" || true 96 97 java-e2e: 98 name: Java E2E (docker bridge) 99 runs-on: self-hosted 100 env: 101 UV_BIN: /home/admin/.local/bin 102 steps: 103 - name: Checkout code 104 uses: actions/checkout@v6 105 106 - name: Set up uv PATH and verify 107 run: | 108 echo "${UV_BIN}" >> "$GITHUB_PATH" 109 export PATH="${UV_BIN}:${PATH}" 110 uv --version 111 uv run python --version 112 113 - name: Set up JDK 8 114 uses: actions/setup-java@v5 115 with: 116 distribution: temurin 117 java-version: "8" 118 119 - name: Set up JDK 17 120 uses: actions/setup-java@v5 121 with: 122 distribution: temurin 123 java-version: "17" 124 125 - name: Clean up previous E2E resources 126 run: | 127 docker ps -aq --filter "label=opensandbox" | xargs -r docker rm -f || true 128 docker run --rm -v /tmp:/host_tmp alpine rm -rf /host_tmp/opensandbox-e2e || true 129 docker image prune -f || true 130 131 - name: Build local egress image 132 run: docker build -t opensandbox/egress:local -f components/egress/Dockerfile . 133 134 - name: Run tests 135 env: 136 GRADLE_USER_HOME: ${{ github.workspace }}/.gradle-user-home 137 OPENSANDBOX_TEST_SECURE_ACCESS_VERIFIABLE: "false" 138 run: | 139 set -e 140 export GRADLE_OPTS="-Dorg.gradle.java.installations.auto-detect=true -Dorg.gradle.java.installations.auto-download=false -Dorg.gradle.java.installations.paths=${JAVA_HOME_8_X64},${JAVA_HOME_17_X64}" 141 142 # Create config file 143 cat <<EOF > ~/.sandbox.toml 144 [server] 145 host = "127.0.0.1" 146 port = 8080 147 api_key = "" 148 [log] 149 level = "INFO" 150 [runtime] 151 type = "docker" 152 execd_image = "opensandbox/execd:local" 153 [egress] 154 image = "opensandbox/egress:local" 155 mode = "dns+nft" 156 [docker] 157 network_mode = "bridge" 158 [storage] 159 allowed_host_paths = ["/tmp/opensandbox-e2e"] 160 EOF 161 162 bash ./scripts/java-e2e.sh 163 164 - name: Eval server logs 165 if: ${{ always() }} 166 run: cat server/server.log 167 168 - name: Upload Test Report 169 if: always() 170 uses: actions/upload-artifact@v7 171 with: 172 name: java-test-report 173 path: tests/java/build/reports/tests/test/ 174 retention-days: 5 175 176 - name: Upload execd logs 177 if: always() 178 uses: actions/upload-artifact@v7 179 with: 180 name: execd-log-for-java-e2e 181 path: /tmp/opensandbox-e2e/logs/ 182 retention-days: 5 183 184 - name: Clean up after E2E 185 if: always() 186 run: | 187 docker ps -aq --filter "label=opensandbox" | xargs -r docker rm -f || true 188 docker run --rm -v /tmp:/host_tmp alpine rm -rf /host_tmp/opensandbox-e2e || true 189 pkill -f "python -m opensandbox_server.main" || true 190 191 javascript-e2e: 192 name: JavaScript E2E (docker bridge) 193 runs-on: self-hosted 194 env: 195 UV_BIN: /home/admin/.local/bin 196 NODE_VERSION: "20.19.0" 197 steps: 198 - name: Checkout code 199 uses: actions/checkout@v6 200 201 - name: Set up uv PATH and verify 202 run: | 203 echo "${UV_BIN}" >> "$GITHUB_PATH" 204 export PATH="${UV_BIN}:${PATH}" 205 uv --version 206 uv run python --version 207 208 - name: Set up Node.js 209 run: | 210 NODE_DIR="/home/admin/.local/node-v${NODE_VERSION}-linux-x64" 211 if [ -x "${NODE_DIR}/bin/node" ]; then 212 echo "Node.js ${NODE_VERSION} already cached" 213 else 214 echo "Downloading Node.js ${NODE_VERSION}..." 215 mkdir -p /home/admin/.local 216 curl -fsSL "https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64.tar.xz" \ 217 | tar -xJ -C /home/admin/.local/ 218 fi 219 echo "${NODE_DIR}/bin" >> "$GITHUB_PATH" 220 export PATH="${NODE_DIR}/bin:${PATH}" 221 node --version 222 npm --version 223 224 - name: Clean up previous E2E resources 225 run: | 226 docker ps -aq --filter "label=opensandbox" | xargs -r docker rm -f || true 227 docker run --rm -v /tmp:/host_tmp alpine rm -rf /host_tmp/opensandbox-e2e || true 228 docker image prune -f || true 229 230 - name: Build local egress image 231 run: docker build -t opensandbox/egress:local -f components/egress/Dockerfile . 232 233 - name: Run tests 234 run: | 235 set -e 236 237 # Create config file (match other E2E jobs) 238 cat <<EOF > ~/.sandbox.toml 239 [server] 240 host = "127.0.0.1" 241 port = 8080 242 api_key = "" 243 [log] 244 level = "INFO" 245 [runtime] 246 type = "docker" 247 execd_image = "opensandbox/execd:local" 248 [egress] 249 image = "opensandbox/egress:local" 250 [docker] 251 network_mode = "bridge" 252 [storage] 253 allowed_host_paths = ["/tmp/opensandbox-e2e"] 254 EOF 255 256 bash ./scripts/javascript-e2e.sh 257 258 - name: Eval server logs 259 if: ${{ always() }} 260 run: cat server/server.log 261 262 - name: Upload Test Report 263 if: always() 264 uses: actions/upload-artifact@v7 265 with: 266 name: javascript-test-report 267 path: tests/javascript/build/test-results/junit.xml 268 retention-days: 5 269 270 - name: Upload execd logs 271 if: always() 272 uses: actions/upload-artifact@v7 273 with: 274 name: execd-log-for-js-e2e 275 path: /tmp/opensandbox-e2e/logs/ 276 retention-days: 5 277 278 - name: Clean up after E2E 279 if: always() 280 run: | 281 docker ps -aq --filter "label=opensandbox" | xargs -r docker rm -f || true 282 docker run --rm -v /tmp:/host_tmp alpine rm -rf /host_tmp/opensandbox-e2e || true 283 pkill -f "python -m opensandbox_server.main" || true 284 285 csharp-e2e: 286 name: C# E2E (docker bridge) 287 runs-on: self-hosted 288 env: 289 UV_BIN: /home/admin/.local/bin 290 steps: 291 - name: Checkout code 292 uses: actions/checkout@v6 293 294 - name: Set up uv PATH and verify 295 run: | 296 echo "${UV_BIN}" >> "$GITHUB_PATH" 297 export PATH="${UV_BIN}:${PATH}" 298 uv --version 299 uv run python --version 300 301 - name: Set up .NET SDK 302 uses: actions/setup-dotnet@v5 303 env: 304 DOTNET_INSTALL_DIR: /home/admin/.local/dotnet 305 with: 306 dotnet-version: "10.0.x" 307 308 - name: Clean up previous E2E resources 309 run: | 310 docker ps -aq --filter "label=opensandbox" | xargs -r docker rm -f || true 311 docker run --rm -v /tmp:/host_tmp alpine rm -rf /host_tmp/opensandbox-e2e || true 312 docker image prune -f || true 313 314 - name: Build local egress image 315 run: docker build -t opensandbox/egress:local -f components/egress/Dockerfile . 316 317 - name: Run tests 318 run: | 319 set -e 320 321 cat <<EOF > ~/.sandbox.toml 322 [server] 323 host = "127.0.0.1" 324 port = 8080 325 api_key = "" 326 [log] 327 level = "INFO" 328 [runtime] 329 type = "docker" 330 execd_image = "opensandbox/execd:local" 331 [egress] 332 image = "opensandbox/egress:local" 333 [docker] 334 network_mode = "bridge" 335 [storage] 336 allowed_host_paths = ["/tmp/opensandbox-e2e"] 337 EOF 338 339 bash ./scripts/csharp-e2e.sh 340 341 - name: Eval server logs 342 if: ${{ always() }} 343 run: cat server/server.log 344 345 - name: Upload Test Report 346 if: always() 347 uses: actions/upload-artifact@v7 348 with: 349 name: csharp-test-report 350 path: tests/csharp/build/test-results/ 351 retention-days: 5 352 353 - name: Upload execd logs 354 if: always() 355 uses: actions/upload-artifact@v7 356 with: 357 name: execd-log-for-csharp-e2e 358 path: /tmp/opensandbox-e2e/logs/ 359 retention-days: 5 360 361 - name: Clean up after E2E 362 if: always() 363 run: | 364 docker ps -aq --filter "label=opensandbox" | xargs -r docker rm -f || true 365 docker run --rm -v /tmp:/host_tmp alpine rm -rf /host_tmp/opensandbox-e2e || true 366 pkill -f "python -m opensandbox_server.main" || true 367 368 go-e2e: 369 name: Go E2E (docker bridge) 370 runs-on: self-hosted 371 env: 372 UV_BIN: /home/admin/.local/bin 373 HOME: /home/admin/actions-runner 374 GOCACHE: /home/admin/actions-runner/_temp/go-build 375 GOMODCACHE: /home/admin/actions-runner/_temp/go-mod-cache 376 steps: 377 - name: Checkout code 378 uses: actions/checkout@v6 379 380 - name: Set up uv PATH and verify 381 run: | 382 echo "${UV_BIN}" >> "$GITHUB_PATH" 383 export PATH="${UV_BIN}:${PATH}" 384 uv --version 385 uv run python --version 386 387 - name: Set up Go 388 uses: actions/setup-go@v6 389 with: 390 go-version: "1.24" 391 cache: false 392 393 - name: Clean up previous E2E resources 394 run: | 395 docker ps -aq --filter "label=opensandbox" | xargs -r docker rm -f || true 396 docker run --rm -v /tmp:/host_tmp alpine rm -rf /host_tmp/opensandbox-e2e || true 397 docker image prune -f || true 398 399 - name: Build local egress image 400 run: docker build -t opensandbox/egress:local -f components/egress/Dockerfile . 401 402 - name: Run tests 403 run: | 404 set -e 405 406 cat <<EOF > ~/.sandbox.toml 407 [server] 408 host = "127.0.0.1" 409 port = 8080 410 api_key = "" 411 [log] 412 level = "INFO" 413 [runtime] 414 type = "docker" 415 execd_image = "opensandbox/execd:local" 416 [egress] 417 image = "opensandbox/egress:local" 418 [docker] 419 network_mode = "bridge" 420 [storage] 421 allowed_host_paths = ["/tmp/opensandbox-e2e"] 422 EOF 423 424 bash ./scripts/go-e2e.sh 425 426 - name: Eval server logs 427 if: ${{ always() }} 428 run: cat server/server.log 429 430 - name: Upload Test Report 431 if: always() 432 uses: actions/upload-artifact@v7 433 with: 434 name: go-test-report 435 path: tests/go/reports/ 436 retention-days: 5 437 438 - name: Upload execd logs 439 if: always() 440 uses: actions/upload-artifact@v7 441 with: 442 name: execd-log-for-go-e2e 443 path: /tmp/opensandbox-e2e/logs/ 444 retention-days: 5 445 446 - name: Clean up after E2E 447 if: always() 448 run: | 449 docker ps -aq --filter "label=opensandbox" | xargs -r docker rm -f || true 450 docker run --rm -v /tmp:/host_tmp alpine rm -rf /host_tmp/opensandbox-e2e || true 451 pkill -f "python -m opensandbox_server.main" || true