Test against a local Zuplo server before deploying anywhere.
Code
trigger: - mainpool: vmImage: ubuntu-lateststages: - stage: LocalTest displayName: "Local Testing" jobs: - job: Test steps: - task: NodeTool@0 inputs: versionSpec: "24.x" displayName: "Install Node.js" - script: npm install displayName: "Install dependencies" - script: | npx zuplo dev & DEV_PID=$! # Poll until the server answers — never a fixed sleep deadline=$((SECONDS + 60)) until curl --fail --silent --output /dev/null http://localhost:9000/health; do if (( SECONDS >= deadline )); then echo "Local server did not start within 60s" >&2 kill $DEV_PID exit 1 fi sleep 1 done npx zuplo test --endpoint http://localhost:9000 kill $DEV_PID displayName: "Start local server and run tests" - stage: Deploy displayName: "Deploy to Zuplo" dependsOn: LocalTest condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main')) jobs: - job: Deploy steps: - task: NodeTool@0 inputs: versionSpec: "24.x" - script: npm install - script: npx zuplo deploy --api-key $(ZUPLO_API_KEY) displayName: "Deploy to Zuplo"
Local tests run first. Only if they pass does deployment proceed.
The readiness poll replaces a fixed sleep. A sleep is a guess about startup
time that is wrong in both directions, and it is the most common reason a
gateway test suite "needs" a retry. The example polls /health — add an
unauthenticated health route if your gateway does not have one. See
health checks.