PR feedback
parent
69731babfc
commit
956b2e4324
|
|
@ -85,58 +85,31 @@ jobs:
|
||||||
# Show available disk space
|
# Show available disk space
|
||||||
df -h
|
df -h
|
||||||
- run: yarn install --frozen-lockfile
|
- run: yarn install --frozen-lockfile
|
||||||
- name: Run K8s tests sequentially
|
- name: Clean up K8s test resources
|
||||||
timeout-minutes: 180
|
|
||||||
run: |
|
run: |
|
||||||
# List of K8s tests to run sequentially
|
# Clean up K8s resources before each test (only test resources, not system pods)
|
||||||
tests=(
|
echo "Cleaning up K8s test resources..."
|
||||||
"cloud-runner-end2end-caching"
|
# Only clean up resources in default namespace and resources matching our test patterns
|
||||||
"cloud-runner-end2end-retaining"
|
kubectl delete jobs --all --ignore-not-found=true -n default || true
|
||||||
"cloud-runner-hooks"
|
# Delete completed/failed pods in default namespace (not system pods)
|
||||||
)
|
kubectl get pods -n default -o name 2>/dev/null | grep -E "(unity-builder-job-|helper-pod-)" | while read pod; do
|
||||||
|
kubectl delete "$pod" --ignore-not-found=true || true
|
||||||
failed_tests=()
|
done || true
|
||||||
|
# Only delete PVCs that match our naming pattern (unity-builder-pvc-*)
|
||||||
for test in "${tests[@]}"; do
|
kubectl get pvc -n default -o name 2>/dev/null | grep "unity-builder-pvc-" | while read pvc; do
|
||||||
echo "========================================="
|
kubectl delete "$pvc" --ignore-not-found=true || true
|
||||||
echo "Running test: $test"
|
done || true
|
||||||
echo "========================================="
|
# Only delete secrets that match our naming pattern (build-credentials-*)
|
||||||
|
kubectl get secrets -n default -o name 2>/dev/null | grep "build-credentials-" | while read secret; do
|
||||||
# Clean up K8s resources before each test
|
kubectl delete "$secret" --ignore-not-found=true || true
|
||||||
echo "Cleaning up K8s resources before test..."
|
done || true
|
||||||
kubectl delete jobs --all --ignore-not-found=true --all-namespaces || true
|
sleep 3
|
||||||
kubectl delete pods --all --ignore-not-found=true --all-namespaces || true
|
# Clean up disk space
|
||||||
kubectl delete pvc --all --ignore-not-found=true --all-namespaces || true
|
rm -rf ./cloud-runner-cache/* || true
|
||||||
kubectl delete secrets --all --ignore-not-found=true --all-namespaces || true
|
docker system prune -f || true
|
||||||
sleep 3
|
- name: Run cloud-runner-end2end-caching test
|
||||||
|
timeout-minutes: 60
|
||||||
# Clean up disk space before each test
|
run: yarn run test "cloud-runner-end2end-caching" --detectOpenHandles --forceExit --runInBand
|
||||||
rm -rf ./cloud-runner-cache/* || true
|
|
||||||
docker system prune -f || true
|
|
||||||
|
|
||||||
# Run the test
|
|
||||||
if yarn run test "$test" --detectOpenHandles --forceExit --runInBand; then
|
|
||||||
echo "✓ Test $test passed"
|
|
||||||
else
|
|
||||||
echo "✗ Test $test failed"
|
|
||||||
failed_tests+=("$test")
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
done
|
|
||||||
|
|
||||||
# Report results
|
|
||||||
if [ ${#failed_tests[@]} -eq 0 ]; then
|
|
||||||
echo "========================================="
|
|
||||||
echo "All tests passed!"
|
|
||||||
echo "========================================="
|
|
||||||
exit 0
|
|
||||||
else
|
|
||||||
echo "========================================="
|
|
||||||
echo "Failed tests: ${failed_tests[*]}"
|
|
||||||
echo "========================================="
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
env:
|
env:
|
||||||
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
|
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
|
||||||
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
|
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
|
||||||
|
|
@ -160,6 +133,86 @@ jobs:
|
||||||
AWS_EC2_METADATA_DISABLED: 'true'
|
AWS_EC2_METADATA_DISABLED: 'true'
|
||||||
GIT_PRIVATE_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }}
|
GIT_PRIVATE_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }}
|
||||||
GITHUB_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }}
|
||||||
|
- name: Clean up K8s test resources
|
||||||
|
run: |
|
||||||
|
kubectl delete jobs --all --ignore-not-found=true -n default || true
|
||||||
|
kubectl get pods -n default -o name 2>/dev/null | grep -E "(unity-builder-job-|helper-pod-)" | while read pod; do
|
||||||
|
kubectl delete "$pod" --ignore-not-found=true || true
|
||||||
|
done || true
|
||||||
|
kubectl get pvc -n default -o name 2>/dev/null | grep "unity-builder-pvc-" | while read pvc; do
|
||||||
|
kubectl delete "$pvc" --ignore-not-found=true || true
|
||||||
|
done || true
|
||||||
|
kubectl get secrets -n default -o name 2>/dev/null | grep "build-credentials-" | while read secret; do
|
||||||
|
kubectl delete "$secret" --ignore-not-found=true || true
|
||||||
|
done || true
|
||||||
|
sleep 3
|
||||||
|
rm -rf ./cloud-runner-cache/* || true
|
||||||
|
docker system prune -f || true
|
||||||
|
- name: Run cloud-runner-end2end-retaining test
|
||||||
|
timeout-minutes: 60
|
||||||
|
run: yarn run test "cloud-runner-end2end-retaining" --detectOpenHandles --forceExit --runInBand
|
||||||
|
env:
|
||||||
|
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
|
||||||
|
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
|
||||||
|
UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }}
|
||||||
|
PROJECT_PATH: test-project
|
||||||
|
TARGET_PLATFORM: StandaloneWindows64
|
||||||
|
cloudRunnerTests: true
|
||||||
|
versioning: None
|
||||||
|
KUBE_STORAGE_CLASS: local-path
|
||||||
|
PROVIDER_STRATEGY: k8s
|
||||||
|
containerCpu: '512'
|
||||||
|
containerMemory: '512'
|
||||||
|
AWS_ACCESS_KEY_ID: test
|
||||||
|
AWS_SECRET_ACCESS_KEY: test
|
||||||
|
AWS_S3_ENDPOINT: http://localhost:4566
|
||||||
|
AWS_ENDPOINT: http://localhost:4566
|
||||||
|
INPUT_AWSS3ENDPOINT: http://localhost:4566
|
||||||
|
INPUT_AWSENDPOINT: http://localhost:4566
|
||||||
|
AWS_S3_FORCE_PATH_STYLE: 'true'
|
||||||
|
AWS_EC2_METADATA_DISABLED: 'true'
|
||||||
|
GIT_PRIVATE_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }}
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }}
|
||||||
|
- name: Clean up K8s test resources
|
||||||
|
run: |
|
||||||
|
kubectl delete jobs --all --ignore-not-found=true -n default || true
|
||||||
|
kubectl get pods -n default -o name 2>/dev/null | grep -E "(unity-builder-job-|helper-pod-)" | while read pod; do
|
||||||
|
kubectl delete "$pod" --ignore-not-found=true || true
|
||||||
|
done || true
|
||||||
|
kubectl get pvc -n default -o name 2>/dev/null | grep "unity-builder-pvc-" | while read pvc; do
|
||||||
|
kubectl delete "$pvc" --ignore-not-found=true || true
|
||||||
|
done || true
|
||||||
|
kubectl get secrets -n default -o name 2>/dev/null | grep "build-credentials-" | while read secret; do
|
||||||
|
kubectl delete "$secret" --ignore-not-found=true || true
|
||||||
|
done || true
|
||||||
|
sleep 3
|
||||||
|
rm -rf ./cloud-runner-cache/* || true
|
||||||
|
docker system prune -f || true
|
||||||
|
- name: Run cloud-runner-hooks test
|
||||||
|
timeout-minutes: 60
|
||||||
|
run: yarn run test "cloud-runner-hooks" --detectOpenHandles --forceExit --runInBand
|
||||||
|
env:
|
||||||
|
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
|
||||||
|
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
|
||||||
|
UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }}
|
||||||
|
PROJECT_PATH: test-project
|
||||||
|
TARGET_PLATFORM: StandaloneWindows64
|
||||||
|
cloudRunnerTests: true
|
||||||
|
versioning: None
|
||||||
|
KUBE_STORAGE_CLASS: local-path
|
||||||
|
PROVIDER_STRATEGY: k8s
|
||||||
|
containerCpu: '512'
|
||||||
|
containerMemory: '512'
|
||||||
|
AWS_ACCESS_KEY_ID: test
|
||||||
|
AWS_SECRET_ACCESS_KEY: test
|
||||||
|
AWS_S3_ENDPOINT: http://localhost:4566
|
||||||
|
AWS_ENDPOINT: http://localhost:4566
|
||||||
|
INPUT_AWSS3ENDPOINT: http://localhost:4566
|
||||||
|
INPUT_AWSENDPOINT: http://localhost:4566
|
||||||
|
AWS_S3_FORCE_PATH_STYLE: 'true'
|
||||||
|
AWS_EC2_METADATA_DISABLED: 'true'
|
||||||
|
GIT_PRIVATE_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }}
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }}
|
||||||
localstack:
|
localstack:
|
||||||
name: Cloud Runner Tests (LocalStack)
|
name: Cloud Runner Tests (LocalStack)
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
@ -188,58 +241,230 @@ jobs:
|
||||||
# Show available disk space
|
# Show available disk space
|
||||||
df -h
|
df -h
|
||||||
- run: yarn install --frozen-lockfile
|
- run: yarn install --frozen-lockfile
|
||||||
- name: Run LocalStack tests sequentially
|
- name: Clean up disk space
|
||||||
timeout-minutes: 300
|
|
||||||
run: |
|
run: |
|
||||||
# List of LocalStack tests to run sequentially
|
rm -rf ./cloud-runner-cache/* || true
|
||||||
tests=(
|
docker system prune -f || true
|
||||||
"cloud-runner-end2end-locking"
|
df -h
|
||||||
"cloud-runner-end2end-caching"
|
- name: Run cloud-runner-end2end-locking test
|
||||||
"cloud-runner-end2end-retaining"
|
timeout-minutes: 60
|
||||||
"cloud-runner-caching"
|
run: yarn run test "cloud-runner-end2end-locking" --detectOpenHandles --forceExit --runInBand
|
||||||
"cloud-runner-environment"
|
env:
|
||||||
"cloud-runner-image"
|
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
|
||||||
"cloud-runner-hooks"
|
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
|
||||||
"cloud-runner-local-persistence"
|
UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }}
|
||||||
"cloud-runner-locking-core"
|
PROJECT_PATH: test-project
|
||||||
"cloud-runner-locking-get-locked"
|
TARGET_PLATFORM: StandaloneWindows64
|
||||||
)
|
cloudRunnerTests: true
|
||||||
|
versioning: None
|
||||||
failed_tests=()
|
KUBE_STORAGE_CLASS: local-path
|
||||||
|
PROVIDER_STRATEGY: aws
|
||||||
for test in "${tests[@]}"; do
|
AWS_ACCESS_KEY_ID: test
|
||||||
echo "========================================="
|
AWS_SECRET_ACCESS_KEY: test
|
||||||
echo "Running test: $test"
|
AWS_ENDPOINT: http://localhost:4566
|
||||||
echo "========================================="
|
AWS_ENDPOINT_URL: http://localhost:4566
|
||||||
|
GIT_PRIVATE_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }}
|
||||||
# Clean up disk space before each test
|
GITHUB_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }}
|
||||||
rm -rf ./cloud-runner-cache/* || true
|
- name: Clean up disk space
|
||||||
docker system prune -f || true
|
run: |
|
||||||
df -h
|
rm -rf ./cloud-runner-cache/* || true
|
||||||
|
docker system prune -f || true
|
||||||
# Run the test
|
df -h
|
||||||
if yarn run test "$test" --detectOpenHandles --forceExit --runInBand; then
|
- name: Run cloud-runner-end2end-caching test
|
||||||
echo "✓ Test $test passed"
|
timeout-minutes: 60
|
||||||
else
|
run: yarn run test "cloud-runner-end2end-caching" --detectOpenHandles --forceExit --runInBand
|
||||||
echo "✗ Test $test failed"
|
env:
|
||||||
failed_tests+=("$test")
|
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
|
||||||
fi
|
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
|
||||||
|
UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }}
|
||||||
echo ""
|
PROJECT_PATH: test-project
|
||||||
done
|
TARGET_PLATFORM: StandaloneWindows64
|
||||||
|
cloudRunnerTests: true
|
||||||
# Report results
|
versioning: None
|
||||||
if [ ${#failed_tests[@]} -eq 0 ]; then
|
KUBE_STORAGE_CLASS: local-path
|
||||||
echo "========================================="
|
PROVIDER_STRATEGY: aws
|
||||||
echo "All tests passed!"
|
AWS_ACCESS_KEY_ID: test
|
||||||
echo "========================================="
|
AWS_SECRET_ACCESS_KEY: test
|
||||||
exit 0
|
AWS_ENDPOINT: http://localhost:4566
|
||||||
else
|
AWS_ENDPOINT_URL: http://localhost:4566
|
||||||
echo "========================================="
|
GIT_PRIVATE_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }}
|
||||||
echo "Failed tests: ${failed_tests[*]}"
|
GITHUB_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }}
|
||||||
echo "========================================="
|
- name: Clean up disk space
|
||||||
exit 1
|
run: |
|
||||||
fi
|
rm -rf ./cloud-runner-cache/* || true
|
||||||
|
docker system prune -f || true
|
||||||
|
df -h
|
||||||
|
- name: Run cloud-runner-end2end-retaining test
|
||||||
|
timeout-minutes: 60
|
||||||
|
run: yarn run test "cloud-runner-end2end-retaining" --detectOpenHandles --forceExit --runInBand
|
||||||
|
env:
|
||||||
|
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
|
||||||
|
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
|
||||||
|
UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }}
|
||||||
|
PROJECT_PATH: test-project
|
||||||
|
TARGET_PLATFORM: StandaloneWindows64
|
||||||
|
cloudRunnerTests: true
|
||||||
|
versioning: None
|
||||||
|
KUBE_STORAGE_CLASS: local-path
|
||||||
|
PROVIDER_STRATEGY: aws
|
||||||
|
AWS_ACCESS_KEY_ID: test
|
||||||
|
AWS_SECRET_ACCESS_KEY: test
|
||||||
|
AWS_ENDPOINT: http://localhost:4566
|
||||||
|
AWS_ENDPOINT_URL: http://localhost:4566
|
||||||
|
GIT_PRIVATE_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }}
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }}
|
||||||
|
- name: Clean up disk space
|
||||||
|
run: |
|
||||||
|
rm -rf ./cloud-runner-cache/* || true
|
||||||
|
docker system prune -f || true
|
||||||
|
df -h
|
||||||
|
- name: Run cloud-runner-caching test
|
||||||
|
timeout-minutes: 60
|
||||||
|
run: yarn run test "cloud-runner-caching" --detectOpenHandles --forceExit --runInBand
|
||||||
|
env:
|
||||||
|
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
|
||||||
|
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
|
||||||
|
UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }}
|
||||||
|
PROJECT_PATH: test-project
|
||||||
|
TARGET_PLATFORM: StandaloneWindows64
|
||||||
|
cloudRunnerTests: true
|
||||||
|
versioning: None
|
||||||
|
KUBE_STORAGE_CLASS: local-path
|
||||||
|
PROVIDER_STRATEGY: aws
|
||||||
|
AWS_ACCESS_KEY_ID: test
|
||||||
|
AWS_SECRET_ACCESS_KEY: test
|
||||||
|
AWS_ENDPOINT: http://localhost:4566
|
||||||
|
AWS_ENDPOINT_URL: http://localhost:4566
|
||||||
|
GIT_PRIVATE_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }}
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }}
|
||||||
|
- name: Clean up disk space
|
||||||
|
run: |
|
||||||
|
rm -rf ./cloud-runner-cache/* || true
|
||||||
|
docker system prune -f || true
|
||||||
|
df -h
|
||||||
|
- name: Run cloud-runner-environment test
|
||||||
|
timeout-minutes: 60
|
||||||
|
run: yarn run test "cloud-runner-environment" --detectOpenHandles --forceExit --runInBand
|
||||||
|
env:
|
||||||
|
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
|
||||||
|
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
|
||||||
|
UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }}
|
||||||
|
PROJECT_PATH: test-project
|
||||||
|
TARGET_PLATFORM: StandaloneWindows64
|
||||||
|
cloudRunnerTests: true
|
||||||
|
versioning: None
|
||||||
|
KUBE_STORAGE_CLASS: local-path
|
||||||
|
PROVIDER_STRATEGY: aws
|
||||||
|
AWS_ACCESS_KEY_ID: test
|
||||||
|
AWS_SECRET_ACCESS_KEY: test
|
||||||
|
AWS_ENDPOINT: http://localhost:4566
|
||||||
|
AWS_ENDPOINT_URL: http://localhost:4566
|
||||||
|
GIT_PRIVATE_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }}
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }}
|
||||||
|
- name: Clean up disk space
|
||||||
|
run: |
|
||||||
|
rm -rf ./cloud-runner-cache/* || true
|
||||||
|
docker system prune -f || true
|
||||||
|
df -h
|
||||||
|
- name: Run cloud-runner-image test
|
||||||
|
timeout-minutes: 60
|
||||||
|
run: yarn run test "cloud-runner-image" --detectOpenHandles --forceExit --runInBand
|
||||||
|
env:
|
||||||
|
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
|
||||||
|
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
|
||||||
|
UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }}
|
||||||
|
PROJECT_PATH: test-project
|
||||||
|
TARGET_PLATFORM: StandaloneWindows64
|
||||||
|
cloudRunnerTests: true
|
||||||
|
versioning: None
|
||||||
|
KUBE_STORAGE_CLASS: local-path
|
||||||
|
PROVIDER_STRATEGY: aws
|
||||||
|
AWS_ACCESS_KEY_ID: test
|
||||||
|
AWS_SECRET_ACCESS_KEY: test
|
||||||
|
AWS_ENDPOINT: http://localhost:4566
|
||||||
|
AWS_ENDPOINT_URL: http://localhost:4566
|
||||||
|
GIT_PRIVATE_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }}
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }}
|
||||||
|
- name: Clean up disk space
|
||||||
|
run: |
|
||||||
|
rm -rf ./cloud-runner-cache/* || true
|
||||||
|
docker system prune -f || true
|
||||||
|
df -h
|
||||||
|
- name: Run cloud-runner-hooks test
|
||||||
|
timeout-minutes: 60
|
||||||
|
run: yarn run test "cloud-runner-hooks" --detectOpenHandles --forceExit --runInBand
|
||||||
|
env:
|
||||||
|
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
|
||||||
|
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
|
||||||
|
UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }}
|
||||||
|
PROJECT_PATH: test-project
|
||||||
|
TARGET_PLATFORM: StandaloneWindows64
|
||||||
|
cloudRunnerTests: true
|
||||||
|
versioning: None
|
||||||
|
KUBE_STORAGE_CLASS: local-path
|
||||||
|
PROVIDER_STRATEGY: aws
|
||||||
|
AWS_ACCESS_KEY_ID: test
|
||||||
|
AWS_SECRET_ACCESS_KEY: test
|
||||||
|
AWS_ENDPOINT: http://localhost:4566
|
||||||
|
AWS_ENDPOINT_URL: http://localhost:4566
|
||||||
|
GIT_PRIVATE_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }}
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }}
|
||||||
|
- name: Clean up disk space
|
||||||
|
run: |
|
||||||
|
rm -rf ./cloud-runner-cache/* || true
|
||||||
|
docker system prune -f || true
|
||||||
|
df -h
|
||||||
|
- name: Run cloud-runner-local-persistence test
|
||||||
|
timeout-minutes: 60
|
||||||
|
run: yarn run test "cloud-runner-local-persistence" --detectOpenHandles --forceExit --runInBand
|
||||||
|
env:
|
||||||
|
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
|
||||||
|
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
|
||||||
|
UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }}
|
||||||
|
PROJECT_PATH: test-project
|
||||||
|
TARGET_PLATFORM: StandaloneWindows64
|
||||||
|
cloudRunnerTests: true
|
||||||
|
versioning: None
|
||||||
|
KUBE_STORAGE_CLASS: local-path
|
||||||
|
PROVIDER_STRATEGY: aws
|
||||||
|
AWS_ACCESS_KEY_ID: test
|
||||||
|
AWS_SECRET_ACCESS_KEY: test
|
||||||
|
AWS_ENDPOINT: http://localhost:4566
|
||||||
|
AWS_ENDPOINT_URL: http://localhost:4566
|
||||||
|
GIT_PRIVATE_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }}
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }}
|
||||||
|
- name: Clean up disk space
|
||||||
|
run: |
|
||||||
|
rm -rf ./cloud-runner-cache/* || true
|
||||||
|
docker system prune -f || true
|
||||||
|
df -h
|
||||||
|
- name: Run cloud-runner-locking-core test
|
||||||
|
timeout-minutes: 60
|
||||||
|
run: yarn run test "cloud-runner-locking-core" --detectOpenHandles --forceExit --runInBand
|
||||||
|
env:
|
||||||
|
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
|
||||||
|
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
|
||||||
|
UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }}
|
||||||
|
PROJECT_PATH: test-project
|
||||||
|
TARGET_PLATFORM: StandaloneWindows64
|
||||||
|
cloudRunnerTests: true
|
||||||
|
versioning: None
|
||||||
|
KUBE_STORAGE_CLASS: local-path
|
||||||
|
PROVIDER_STRATEGY: aws
|
||||||
|
AWS_ACCESS_KEY_ID: test
|
||||||
|
AWS_SECRET_ACCESS_KEY: test
|
||||||
|
AWS_ENDPOINT: http://localhost:4566
|
||||||
|
AWS_ENDPOINT_URL: http://localhost:4566
|
||||||
|
GIT_PRIVATE_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }}
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }}
|
||||||
|
- name: Clean up disk space
|
||||||
|
run: |
|
||||||
|
rm -rf ./cloud-runner-cache/* || true
|
||||||
|
docker system prune -f || true
|
||||||
|
df -h
|
||||||
|
- name: Run cloud-runner-locking-get-locked test
|
||||||
|
timeout-minutes: 60
|
||||||
|
run: yarn run test "cloud-runner-locking-get-locked" --detectOpenHandles --forceExit --runInBand
|
||||||
env:
|
env:
|
||||||
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
|
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
|
||||||
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
|
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
|
||||||
|
|
|
||||||
|
|
@ -3861,6 +3861,7 @@ class KubernetesJobSpecFactory {
|
||||||
backoffLimit: 0,
|
backoffLimit: 0,
|
||||||
template: {
|
template: {
|
||||||
spec: {
|
spec: {
|
||||||
|
terminationGracePeriodSeconds: 90,
|
||||||
volumes: [
|
volumes: [
|
||||||
{
|
{
|
||||||
name: 'build-mount',
|
name: 'build-mount',
|
||||||
|
|
@ -3979,19 +3980,40 @@ class KubernetesPods {
|
||||||
if (conditions.length > 0) {
|
if (conditions.length > 0) {
|
||||||
errorDetails.push(`Conditions: ${JSON.stringify(conditions.map((c) => ({ type: c.type, status: c.status, reason: c.reason, message: c.message })), undefined, 2)}`);
|
errorDetails.push(`Conditions: ${JSON.stringify(conditions.map((c) => ({ type: c.type, status: c.status, reason: c.reason, message: c.message })), undefined, 2)}`);
|
||||||
}
|
}
|
||||||
|
let containerExitCode;
|
||||||
|
let containerSucceeded = false;
|
||||||
if (containerStatuses.length > 0) {
|
if (containerStatuses.length > 0) {
|
||||||
containerStatuses.forEach((cs, idx) => {
|
containerStatuses.forEach((cs, idx) => {
|
||||||
if (cs.state?.waiting) {
|
if (cs.state?.waiting) {
|
||||||
errorDetails.push(`Container ${idx} (${cs.name}) waiting: ${cs.state.waiting.reason} - ${cs.state.waiting.message || ''}`);
|
errorDetails.push(`Container ${idx} (${cs.name}) waiting: ${cs.state.waiting.reason} - ${cs.state.waiting.message || ''}`);
|
||||||
}
|
}
|
||||||
if (cs.state?.terminated) {
|
if (cs.state?.terminated) {
|
||||||
errorDetails.push(`Container ${idx} (${cs.name}) terminated: ${cs.state.terminated.reason} - ${cs.state.terminated.message || ''} (exit code: ${cs.state.terminated.exitCode})`);
|
const exitCode = cs.state.terminated.exitCode;
|
||||||
|
containerExitCode = exitCode;
|
||||||
|
if (exitCode === 0) {
|
||||||
|
containerSucceeded = true;
|
||||||
|
}
|
||||||
|
errorDetails.push(`Container ${idx} (${cs.name}) terminated: ${cs.state.terminated.reason} - ${cs.state.terminated.message || ''} (exit code: ${exitCode})`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (events.length > 0) {
|
if (events.length > 0) {
|
||||||
errorDetails.push(`Recent events: ${JSON.stringify(events.slice(-5), undefined, 2)}`);
|
errorDetails.push(`Recent events: ${JSON.stringify(events.slice(-5), undefined, 2)}`);
|
||||||
}
|
}
|
||||||
|
// Check if only PreStopHook failed but container succeeded
|
||||||
|
const hasPreStopHookFailure = events.some((e) => e.reason === 'FailedPreStopHook');
|
||||||
|
if (containerSucceeded && containerExitCode === 0) {
|
||||||
|
// Container succeeded - PreStopHook failure is non-critical
|
||||||
|
if (hasPreStopHookFailure) {
|
||||||
|
cloud_runner_logger_1.default.logWarning(`Pod ${podName} marked as Failed due to PreStopHook failure, but container exited successfully (exit code 0). This is non-fatal.`);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cloud_runner_logger_1.default.log(`Pod ${podName} container succeeded (exit code 0), but pod phase is Failed. Checking details...`);
|
||||||
|
}
|
||||||
|
cloud_runner_logger_1.default.log(`Pod details: ${errorDetails.join('\n')}`);
|
||||||
|
// Don't throw error - container succeeded, PreStopHook failure is non-critical
|
||||||
|
return false; // Pod is not running, but we don't treat it as a failure
|
||||||
|
}
|
||||||
const errorMessage = `K8s pod failed\n${errorDetails.join('\n')}`;
|
const errorMessage = `K8s pod failed\n${errorDetails.join('\n')}`;
|
||||||
cloud_runner_logger_1.default.log(errorMessage);
|
cloud_runner_logger_1.default.log(errorMessage);
|
||||||
throw new Error(errorMessage);
|
throw new Error(errorMessage);
|
||||||
|
|
@ -6924,6 +6946,10 @@ class ContainerHookService {
|
||||||
if (step.image === undefined) {
|
if (step.image === undefined) {
|
||||||
step.image = `ubuntu`;
|
step.image = `ubuntu`;
|
||||||
}
|
}
|
||||||
|
// Ensure allowFailure defaults to false if not explicitly set
|
||||||
|
if (step.allowFailure === undefined) {
|
||||||
|
step.allowFailure = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (object === undefined) {
|
if (object === undefined) {
|
||||||
throw new Error(`Failed to parse ${steps}`);
|
throw new Error(`Failed to parse ${steps}`);
|
||||||
|
|
@ -7296,7 +7322,22 @@ class CustomWorkflow {
|
||||||
// }
|
// }
|
||||||
for (const step of steps) {
|
for (const step of steps) {
|
||||||
cloud_runner_logger_1.default.log(`Cloud Runner is running in custom job mode`);
|
cloud_runner_logger_1.default.log(`Cloud Runner is running in custom job mode`);
|
||||||
output += await cloud_runner_1.default.Provider.runTaskInWorkflow(cloud_runner_1.default.buildParameters.buildGuid, step.image, step.commands, `/${cloud_runner_folders_1.CloudRunnerFolders.buildVolumeFolder}`, `/${cloud_runner_folders_1.CloudRunnerFolders.projectPathAbsolute}/`, environmentVariables, [...secrets, ...step.secrets]);
|
try {
|
||||||
|
const stepOutput = await cloud_runner_1.default.Provider.runTaskInWorkflow(cloud_runner_1.default.buildParameters.buildGuid, step.image, step.commands, `/${cloud_runner_folders_1.CloudRunnerFolders.buildVolumeFolder}`, `/${cloud_runner_folders_1.CloudRunnerFolders.projectPathAbsolute}/`, environmentVariables, [...secrets, ...step.secrets]);
|
||||||
|
output += stepOutput;
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
const allowFailure = step.allowFailure === true;
|
||||||
|
const stepName = step.name || step.image || 'unknown';
|
||||||
|
if (allowFailure) {
|
||||||
|
cloud_runner_logger_1.default.logWarning(`Hook container "${stepName}" failed but allowFailure is true. Continuing build. Error: ${error?.message || error}`);
|
||||||
|
// Continue to next step
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cloud_runner_logger_1.default.log(`Hook container "${stepName}" failed and allowFailure is false (default). Stopping build.`);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -61,6 +61,7 @@ class KubernetesJobSpecFactory {
|
||||||
backoffLimit: 0,
|
backoffLimit: 0,
|
||||||
template: {
|
template: {
|
||||||
spec: {
|
spec: {
|
||||||
|
terminationGracePeriodSeconds: 90, // Give PreStopHook (60s sleep) time to complete
|
||||||
volumes: [
|
volumes: [
|
||||||
{
|
{
|
||||||
name: 'build-mount',
|
name: 'build-mount',
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,9 @@ class KubernetesPods {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let containerExitCode: number | undefined;
|
||||||
|
let containerSucceeded = false;
|
||||||
|
|
||||||
if (containerStatuses.length > 0) {
|
if (containerStatuses.length > 0) {
|
||||||
containerStatuses.forEach((cs, idx) => {
|
containerStatuses.forEach((cs, idx) => {
|
||||||
if (cs.state?.waiting) {
|
if (cs.state?.waiting) {
|
||||||
|
|
@ -40,10 +43,15 @@ class KubernetesPods {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (cs.state?.terminated) {
|
if (cs.state?.terminated) {
|
||||||
|
const exitCode = cs.state.terminated.exitCode;
|
||||||
|
containerExitCode = exitCode;
|
||||||
|
if (exitCode === 0) {
|
||||||
|
containerSucceeded = true;
|
||||||
|
}
|
||||||
errorDetails.push(
|
errorDetails.push(
|
||||||
`Container ${idx} (${cs.name}) terminated: ${cs.state.terminated.reason} - ${
|
`Container ${idx} (${cs.name}) terminated: ${cs.state.terminated.reason} - ${
|
||||||
cs.state.terminated.message || ''
|
cs.state.terminated.message || ''
|
||||||
} (exit code: ${cs.state.terminated.exitCode})`,
|
} (exit code: ${exitCode})`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -53,6 +61,25 @@ class KubernetesPods {
|
||||||
errorDetails.push(`Recent events: ${JSON.stringify(events.slice(-5), undefined, 2)}`);
|
errorDetails.push(`Recent events: ${JSON.stringify(events.slice(-5), undefined, 2)}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if only PreStopHook failed but container succeeded
|
||||||
|
const hasPreStopHookFailure = events.some((e) => e.reason === 'FailedPreStopHook');
|
||||||
|
|
||||||
|
if (containerSucceeded && containerExitCode === 0) {
|
||||||
|
// Container succeeded - PreStopHook failure is non-critical
|
||||||
|
if (hasPreStopHookFailure) {
|
||||||
|
CloudRunnerLogger.logWarning(
|
||||||
|
`Pod ${podName} marked as Failed due to PreStopHook failure, but container exited successfully (exit code 0). This is non-fatal.`,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
CloudRunnerLogger.log(
|
||||||
|
`Pod ${podName} container succeeded (exit code 0), but pod phase is Failed. Checking details...`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
CloudRunnerLogger.log(`Pod details: ${errorDetails.join('\n')}`);
|
||||||
|
// Don't throw error - container succeeded, PreStopHook failure is non-critical
|
||||||
|
return false; // Pod is not running, but we don't treat it as a failure
|
||||||
|
}
|
||||||
|
|
||||||
const errorMessage = `K8s pod failed\n${errorDetails.join('\n')}`;
|
const errorMessage = `K8s pod failed\n${errorDetails.join('\n')}`;
|
||||||
CloudRunnerLogger.log(errorMessage);
|
CloudRunnerLogger.log(errorMessage);
|
||||||
throw new Error(errorMessage);
|
throw new Error(errorMessage);
|
||||||
|
|
|
||||||
|
|
@ -334,6 +334,10 @@ export class ContainerHookService {
|
||||||
if (step.image === undefined) {
|
if (step.image === undefined) {
|
||||||
step.image = `ubuntu`;
|
step.image = `ubuntu`;
|
||||||
}
|
}
|
||||||
|
// Ensure allowFailure defaults to false if not explicitly set
|
||||||
|
if (step.allowFailure === undefined) {
|
||||||
|
step.allowFailure = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (object === undefined) {
|
if (object === undefined) {
|
||||||
throw new Error(`Failed to parse ${steps}`);
|
throw new Error(`Failed to parse ${steps}`);
|
||||||
|
|
|
||||||
|
|
@ -6,4 +6,5 @@ export class ContainerHook {
|
||||||
public name!: string;
|
public name!: string;
|
||||||
public image: string = `ubuntu`;
|
public image: string = `ubuntu`;
|
||||||
public hook!: string;
|
public hook!: string;
|
||||||
|
public allowFailure: boolean = false; // If true, hook failures won't stop the build
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,15 +32,33 @@ export class CustomWorkflow {
|
||||||
// }
|
// }
|
||||||
for (const step of steps) {
|
for (const step of steps) {
|
||||||
CloudRunnerLogger.log(`Cloud Runner is running in custom job mode`);
|
CloudRunnerLogger.log(`Cloud Runner is running in custom job mode`);
|
||||||
output += await CloudRunner.Provider.runTaskInWorkflow(
|
try {
|
||||||
CloudRunner.buildParameters.buildGuid,
|
const stepOutput = await CloudRunner.Provider.runTaskInWorkflow(
|
||||||
step.image,
|
CloudRunner.buildParameters.buildGuid,
|
||||||
step.commands,
|
step.image,
|
||||||
`/${CloudRunnerFolders.buildVolumeFolder}`,
|
step.commands,
|
||||||
`/${CloudRunnerFolders.projectPathAbsolute}/`,
|
`/${CloudRunnerFolders.buildVolumeFolder}`,
|
||||||
environmentVariables,
|
`/${CloudRunnerFolders.projectPathAbsolute}/`,
|
||||||
[...secrets, ...step.secrets],
|
environmentVariables,
|
||||||
);
|
[...secrets, ...step.secrets],
|
||||||
|
);
|
||||||
|
output += stepOutput;
|
||||||
|
} catch (error: any) {
|
||||||
|
const allowFailure = step.allowFailure === true;
|
||||||
|
const stepName = step.name || step.image || 'unknown';
|
||||||
|
|
||||||
|
if (allowFailure) {
|
||||||
|
CloudRunnerLogger.logWarning(
|
||||||
|
`Hook container "${stepName}" failed but allowFailure is true. Continuing build. Error: ${error?.message || error}`,
|
||||||
|
);
|
||||||
|
// Continue to next step
|
||||||
|
} else {
|
||||||
|
CloudRunnerLogger.log(
|
||||||
|
`Hook container "${stepName}" failed and allowFailure is false (default). Stopping build.`,
|
||||||
|
);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue