Back to Blog
Lesson 10 of the CI/CD: Continuous Integration from Scratch course
DevOpsJuly 10, 20264 min read

Pull Request Integration: Protecting Main with CI

Learn how to use 'on: pull_request' triggers to run automated tests on feature branches, ensuring code quality before merging to your main branch.

GitHub ActionsCI/CDPull RequestsDevOpsAutomation

Previously in this course, we explored triggering on push to run workflows whenever code hits a branch. While that's great for continuous feedback, it often creates unnecessary noise or runs tests on every tiny commit. Today, we refine our strategy by using pull requests to create a formal "gate" for your code.

By shifting your CI focus to pull requests, you ensure that every line of code is validated before it becomes part of your production-ready main branch.

Why Pull Requests are the Heart of CI

In a professional environment, you rarely push directly to main. Instead, you work in a feature branch and open a pull request (PR). This workflow is the industry standard because it provides a clear boundary: code in main is stable, and code in a PR is "proposed."

When you configure your CI to trigger on a PR, you achieve two goals:

  1. Isolated Validation: You test the specific changes in the branch without polluting the main branch’s history.
  2. Reviewer Confidence: Reviewers can see the green checkmark from your CI pipeline, proving that the code passes all tests before they even start reading it.

Configuring the 'on: pull_request' Trigger

To switch from triggering on every push to triggering on pull requests, you modify the on section of your YAML workflow file.

Open your .github/workflows/ci.yml file (created in our earlier lessons on Anatomy of a Workflow) and update the trigger section:

YAML
name: CI Pipeline

on:
  pull_request:
    branches:
      - main

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
      
      - name: Run tests
        run: npm test # Or your specific test command

Understanding the Configuration

  • on: pull_request: This tells GitHub to run this workflow whenever a PR is opened, synchronized (new commits pushed), or reopened.
  • branches: [main]: This is a filter. The workflow will only trigger if the pull request is targeting the main branch. This prevents your CI from running on PRs that might be merging into other development or feature branches.

Hands-on Exercise: Protect Your Main Branch

  1. Create a new branch: Run git checkout -b feature-test-pr in your local environment.
  2. Modify the workflow: Update your YAML file as shown above.
  3. Commit and Push: Push your changes to GitHub: git push origin feature-test-pr.
  4. Open a PR: Go to your repository on GitHub. You should see a prompt to "Compare & pull request." Open one against main.
  5. Observe: Immediately check the PR page. You will see a "Checks" section where GitHub Actions is running your tests.

Common Pitfalls

  • Forgetting to define branches: If you leave branches empty, the workflow runs on PRs targeting any branch. This can lead to excessive resource usage.
  • Ignoring 'push' vs 'pull_request': You can have both! Many teams use on: [push, pull_request]. The push trigger handles the main branch, while pull_request handles the feature branches.
  • Workflow file location: Remember that the workflow file must exist on the branch you are merging into (main) for the PR to see the configuration correctly. If you add the trigger in a new branch, it won't activate until that change is merged or if the PR is created against a branch that already contains the workflow file.

FAQ

Q: Does 'on: pull_request' run on the source or target branch? A: It runs on a temporary merge commit that represents what the code would look like if the PR were merged right now. This is the ultimate test of "will this break main?"

Q: Can I require these tests to pass before merging? A: Yes, this is known as "Branch Protection." We will cover how to enforce this in a future lesson on branch protection rules.

Q: What if I want to run different tests for PRs versus pushes? A: You can use the github.event_name context in an if condition to skip or run specific steps depending on whether the trigger was a push or a pull_request.

Recap

By transitioning from push to pull_request triggers, you’ve moved from simple automation to quality gatekeeping. You now have a workflow that validates proposed changes in isolation, ensuring that only verified, passing code reaches your main branch. This is the foundation of a professional CI/CD pipeline.

Up next: Interpreting Feedback — how to debug your pipeline when the tests inevitably fail.

Similar Posts