In modern web development, “CI/CD pipelines” that automate the entire process from development to production release by connecting tools like GitHub and Vercel have become the standard.
While this system may seem complex at first glance, its structure is highly logical when understood through its ultimate goal: “never break the production environment.” In this article, we will look at how the actual release process works in development teams and the underlying mechanisms that ensure its safety.
1. The Core Premise: Protecting Production with Two Branches (Environments)
First, let’s clarify the foundational Git branch structure. In development teams, “branches” act as parallel code universes that isolate and establish distinct environments.
| Branch Name | Corresponding Environment & Role |
|---|---|
| main branch | Production Environment: The live code that actual users access. It must always be kept free of bugs. |
| feature branch | Working Environment: An isolated space where a developer works locally on their PC to build new features or fix bugs. |
To prevent breaking the live site, it is a strict rule that developers must never work directly on or push to the main branch.
Instead, developers always write code in a feature branch (working environment). Once the work is complete, they submit a request on GitHub to merge their code into the main branch (production environment). This request is called a “Pull Request (PR).”
2. The 5 Steps from Development to Production Release
The process from creating a pull request to the final production release involves a seamless combination of automated tool processing and manual human validation, executed in the following order:
- [Developer] Creating the Pull Request: The developer finishes working on the
featurebranch, pushes the code to GitHub, and opens a pull request. - [Vercel] Automatic Preview Deployment: Vercel detects the new pull request and automatically spins up an isolated, temporary “Preview Environment (URL)” specifically for that PR.
- [GitHub Actions] Running Automated Tests: Triggered by the completion of the preview environment, GitHub Actions launches automated E2E tests (such as Playwright) and displays the results (Pass ✅ or Fail ❌) directly on the pull request screen.
- [QA Engineer] Manual Testing: Once the automated tests pass, a human QA engineer opens the Vercel preview URL to manually verify the actual behavior, layout, and user experience.
- [Development Leader] Merging into Production: After confirming that all automated and manual tests have passed, the development leader clicks the “Merge” button on GitHub to combine the code into the
mainbranch. Vercel then automatically updates the live production website.
3. How Merge Conflicts Work and When Tests Re-run
In team environments, “merge conflicts” can occur when your changes clash with someone else’s modifications.
A common misconception is that the development leader reviewing the pull request will just fix the conflict directly on GitHub and merge it. This is incorrect. In reality, the developer who opened the pull request must completely resolve the conflict locally on their own machine before the development leader can even click the merge button.
So, when a conflict occurs and the developer fixes it, when do the automated tests run?
The Test Timeline During Conflict Resolution
The rule is simple: automated tests re-run every single time a developer pushes a code modification.
- Conflict Occurs: A conflict is detected either when the PR is first opened or while waiting for review (because another team member’s
featurebranch was merged intomainfirst), locking the merge button. - Local Fix: The developer pulls the latest
mainbranch onto their local PC and safely resolves the conflicting lines of code. - Re-push (Re-running Tests): When the developer pushes the resolved code back to GitHub, both Vercel and GitHub Actions independently detect the new push event. Vercel overwrites the existing preview environment with the latest code, and GitHub Actions automatically kicks off the automated tests (Playwright) for a second time.
Because the tests run again on the post-conflict-resolution code, the team can be 100% certain that fixing the conflict did not inadvertently break another part of the application.
4. Pull Requests Link to Branches, Not Individual Commits
When you push a conflict fix, the existing pull request on GitHub automatically updates to reflect the latest state. There is absolutely no need for a human to close the old PR and open a new one.
This seamless update happens because pull requests and merges are tied to the feature branch container itself, rather than a fixed snapshot of code (a specific commit).
Since GitHub constantly monitors the branch as a whole, any new push from the developer seamlessly shifts the PR’s focus to the newest state. This allows teams to complete the entire cycle within a single pull request screen without wasting time on redundant administrative steps.
5. Why Can You Open a Pull Request with Existing Conflicts?
GitHub does not block you from opening a pull request even if it has active conflicts. This is because a pull request also serves as a “discussion room” for your code.
It allows developers to look at the diff together and communicate: “Hey, this part conflicted with your change. What’s the best way to merge these?” While the platform keeps the communication channel completely open, it rationally keeps the final production merge button locked until safety is proven through conflict resolution and passing tests.
Summary
The design philosophy behind GitHub and Vercel revolves around a rigorous balance between freedom and safety. Developers have full freedom to collaborate, discuss, and continuously refine code via pushes. However, when it comes to merging—an operation that risks breaking the production environment—the system enforces a strict guardrail that yields only to green test suites. This logical harmony is what allows modern development teams to maintain rapid shipping speeds without sacrificing stability.