
Adding E2E Testing to Your CI/CD Pipeline Without a Platform Engineer
The Part That Actually Needs a Platform Engineer
Most CI/CD pipelines already run unit tests and linting without any special infrastructure — those run in the CI runner itself. E2E tests are different: they need something real to run against, a deployed instance of the actual application, not just the CI container.
That "something real to run against" is where platform engineering time historically went. Someone had to build the provisioning logic, wire it into the pipeline, handle teardown, and keep the whole thing from breaking every time the app's dependencies changed. None of that is CI/CD configuration — it's infrastructure engineering wrapped around CI/CD configuration.
Nadia ran engineering at a 13-person martech startup using GitHub Actions for everything — lint, unit tests, deploys. Adding E2E testing meant, in her CTO's words, "we need someone who actually knows Kubernetes to build the environment step." That request sat in the backlog for four months because nobody wanted to make a platform-engineering hire just to unblock one pipeline step.
What a CI/CD Pipeline With E2E Testing Actually Needs
Strip away the infrastructure-building problem and the pipeline logic itself is simple — five steps, most of which any CI tool already handles natively.
- Trigger. A
pull_requestevent (GitHub Actions) ormerge_requestpipeline (GitLab CI) fires when a feature branch opens a PR. - Provision. One step calls the environment platform's API or CLI, passing the PR's branch/commit. This is the step that used to need a platform engineer to build.
- Wait for ready. The pipeline polls or waits for the environment to report healthy before proceeding.
- Test. The existing E2E suite (Playwright, Cypress, whatever's already in place) runs against the environment's URL — passed in as an environment variable or output from step 2.
- Report and teardown. Results post back to the PR. A separate step (or an automatic policy) destroys the environment when the PR closes.
Steps 1, 4, and 5's reporting are things GitHub Actions, GitLab CI, and Jenkins already do natively. Step 2 and the teardown half of step 5 are what a managed environment platform's built-in pipelines take over — dependency-aware Deploy/Destroy/Start/Stop workflows, auto-generated from your environment definition, with queuing and retries so quick-succession commits don't collide.
See the environment step without building it yourself.
Provisioning and teardown handled by built-in pipelines — wired into the CI/CD you already run.
Wiring It Into GitHub Actions, GitLab CI, or Jenkins
The integration point is the same regardless of which CI tool triggers it — a step that calls the environment platform, and a variable that carries the resulting URL into the test step.
GitHub Actions:
1name: E2E Tests
2on: [pull_request]
3jobs:
4 e2e:
5 runs-on: ubuntu-latest
6 steps:
7 - uses: bunnyshell/deploy@v2
8 - run: npx playwright test
9 env:
10 BASE_URL: ${{ steps.bns.outputs.url }}
11 - uses: bunnyshell/destroy@v2GitLab CI: the same pattern using a merge_request pipeline trigger — one job provisions and exposes the URL as an artifact or variable, the next job consumes it for the test run.
Jenkins: a pipeline stage calls the environment platform's REST API directly (curl -X POST .../environments/{id}/deploy), polls for ready status, then runs the existing test stage against the returned URL.
None of these replace the CI tool. They add one provisioning step and one teardown step around a test step that was probably already there, just pointed at localhost or a shared staging URL before. See Preview Environments for CI/CD for the full picture of what gets automated.
Why This Is Environment Lifecycle, Not General CI/CD
Worth being precise about scope here, because "Bunnyshell has built-in pipelines" can sound like it replaces GitHub Actions or Jenkins. It doesn't.
What a general CI/CD tool does: runs arbitrary build steps, arbitrary test steps, arbitrary deploy steps, for your entire software delivery process, in whatever order and combination you define.
What Bunnyshell's built-in pipelines do: automate the environment lifecycle specifically — Deploy, Destroy, Start, Stop — as dependency-aware workflows auto-generated from your environment definition, with built-in queuing and retries so concurrent PR activity doesn't collide. No pipeline YAML to hand-write for the environment step itself.
The practical split: your existing CI/CD tool still owns the overall pipeline — when tests run, what counts as passing, what blocks a merge. Bunnyshell's pipelines own what happens to the environment underneath that one test step. Most teams end up running both together, not choosing between them.
Handling Concurrent PRs Without Collisions
A CI/CD pipeline that works fine for one PR at a time can fall over with five open simultaneously, if the environment step wasn't built to handle concurrency. This is a common failure point in homegrown environment-provisioning scripts.
Built-in queuing means simultaneous PR activity doesn't try to provision conflicting resources or overwrite an in-progress deploy. Each PR's environment provisions independently — ten PRs open means ten environments running in parallel, not ten pipeline runs competing for one.
Retries matter for the same reason. A transient cluster hiccup shouldn't fail an entire CI run. Built-in retry logic on the provisioning step absorbs that without requiring custom retry code in every pipeline definition.
Scaling the Same Pipeline for AI-Generated Code
Teams using Cursor, Copilot, or Claude Code open more PRs per week, which means the CI/CD pipeline's environment step runs more often, in more parallel instances. The pipeline logic itself doesn't need to change, five steps stays five steps, but the underlying platform needs to handle that concurrency without becoming the new bottleneck. See how to test a pull request before merging for the full workflow this plugs into.
Getting This Running This Week
Adding E2E testing to a CI/CD pipeline without a platform engineer comes down to outsourcing exactly one thing: the environment provisioning and teardown that used to require someone who "actually knows Kubernetes." Your CI tool, your test framework, and your pipeline logic all stay the same.
For a team with an existing E2E suite and CI pipeline, wiring in the provisioning step typically takes a few hours, not the multi-month backlog item Nadia's team had.
✅ Key Takeaways
- The part of E2E-in-CI/CD that needs a platform engineer is environment provisioning and teardown — not the pipeline logic itself
- A working pipeline is five steps: trigger, provision, wait for ready, test, report and teardown — most CI tools already handle three of them natively
- Bunnyshell's built-in pipelines automate environment lifecycle (Deploy/Destroy/Start/Stop) specifically — they plug into GitHub Actions, GitLab CI, or Jenkins, they don't replace them
- Built-in queuing and retries prevent concurrent PR activity from colliding on the environment step
- For a team with an existing E2E suite, wiring in the provisioning step typically takes hours, not a platform-engineering project
FAQ
Can I add E2E testing to my CI/CD pipeline without hiring a platform engineer?
Yes. The part that used to require platform engineering time was building and maintaining the environment each E2E run needs. A managed environment platform with built-in pipelines handles that provisioning and teardown, so your existing CI/CD tool (GitHub Actions, GitLab CI, Jenkins) only needs one extra step before tests run and one after.
Does Bunnyshell replace GitHub Actions or GitLab CI?
No. Bunnyshell provides environment lifecycle pipelines — dependency-aware workflows that provision, deploy, start, and stop environments — but it's not a general-purpose CI/CD system for building and testing arbitrary code. It plugs into whatever CI you already run rather than replacing it.
What does a CI/CD pipeline with E2E testing actually look like?
A pull request triggers the pipeline. One step calls the environment platform to provision a full-stack environment from your existing config. The pipeline waits for it to be ready, runs the E2E suite against its URL, and reports results back to the PR. A final step tears the environment down after the PR closes.
How long does it take to add E2E testing to an existing CI/CD pipeline?
For a team with an existing E2E suite and CI pipeline, adding the environment-provisioning step typically takes a few hours to a day, not a multi-week platform engineering project. The test suite itself doesn't change — only what it points at does.
What's the difference between Bunnyshell pipelines and Jenkins/CircleCI pipelines?
Jenkins, CircleCI, GitHub Actions, and GitLab CI run arbitrary build, test, and deploy steps for your whole software delivery process. Bunnyshell pipelines are scoped specifically to environment lifecycle — deploy, destroy, start, stop — auto-generated from your environment definition with built-in queuing and retries. Most teams run both together: their existing CI tool for the overall pipeline, Bunnyshell for the environment step inside it.
Add the environment step, not a platform team.
Wire E2E testing into your existing CI/CD pipeline without building the provisioning layer yourself.

