- Introduction
- Prerequisites
- Setting up Continuous Integration (CI) for PHP Project
- Testing the CI Pipeline
- Visualizing the CI Process in GitLab
- Pre-Merge Checks and Bypassing CI Checks
- Troubleshooting and Advanced Configuration
- Sample Repository
- Conclusion
The purpose of this document is to provide a step-by-step guide for setting up a Continuous Integration (CI) pipeline for a PHP project in GitLab. The CI pipeline will automate the linting and code analysis processes to ensure code quality and reliability.
This document covers the basic setup of a CI pipeline for a PHP project in GitLab, focusing on linting and code analysis stage. More advanced topics, such as deployment and additional stages, are outside the scope of this guide.
Before setting up the CI pipeline, ensure you have the following prerequisites:
- A GitLab account with access to your target repository
- An existing or new repository with the PHP project hosted on GitLab
- All required configurations done as per PHP coding standards: Enforcing tools and config
-
Open your project repository and click on Build->Pipeline editor. Then click on the Configure pipeline button.
-
A new page will open for editing and creating the
.gitlab-ci.yml
file. Remove all the content that exists in the file. -
Follow the steps from Defining Stages and onwards to understand the creation and configuration of this file. Alternatively, paste the configuration in Complete
.gitlab-ci.yml
Configuration and make changes as required. -
Add or edit the commit message, choose the main branch of your project and click on Commit changes. You should get a banner message like follows to signify that the file has been created successfully.
The creation of this
.gitlab-ci.yml
file can also be verified by checking in the root of the project.
- Create or clone the repository on your system. Alternatively, open the repository on GitLab.
- In the root of your project, create a file
.gitlab-ci.yml
and open it. - Follow the steps from Defining Stages and onwards to understand the creation and configuration of this file. Alternatively, paste the configuration in Complete
.gitlab-ci.yml
Configuration and make changes as required. - Commit and push this file to the main branch of your repository. The workflow file should now be created in your project.
Define the stages for your CI pipeline. In this guide, we will use one stage: lint
.
stages:
- lint
Define variables that specify the branches on which you want to execute your CI job.
variables:
push_branches: "/^main|dev$/"
merge_request_branches: "/^main|release$/"
These variables define regex patterns for the names of the branches for push or merge requests for which the job should run. In its current state, this job will run only when the commit branch is 'main' or 'dev' (i.e., a commit is made to the 'main' or 'dev' branch), or a merge request is created for the 'main' or 'release' branch.
To add more branches, it can be done as follows:
variables:
push_branches: "/^main|dev|feature$/"
merge_request_branches: "/^main|release|dev$/"
This regex is evaluated as follows in the rules
section of the job (see Writing Job for Lint):
- If the commit branch matches 'main' or 'dev' or 'feature', run the job.
- If a merge request is created and the target branch is 'main' or 'release' or 'dev', run the job.
While adding new branch names, it should be kept in mind that the names will be evaluated in a regex pattern, and as such, escaping of any required characters should be done.
Create the job to perform the linting and code analysis tasks.
lint:
stage: lint
tags:
- PHP-8.1
rules:
# Run pipeline if a commit is made to these branches
- if: $CI_COMMIT_BRANCH =~ $push_branches
# Run pipeline if a merge request is created for these branches
- if: $CI_MERGE_REQUEST_TARGET_BRANCH_NAME =~ $merge_request_branches
script:
- echo "Installing dependencies"
- composer install --prefer-dist --no-progress
- echo "Linting code"
- composer run lint
- echo "Running static code analysis"
- composer run phan
In the above job, note that we also define the following two things:
-
tags: - PHP-8.1
This value specifies which runner to use for running this pipeline job. It is possible that the value of this may need to be updated in case of multiple runners.
-
rules: # Run pipeline if a commit is made to these branches - if: $CI_COMMIT_BRANCH =~ $push_branches # Run pipeline if a merge request is created for these branches - if: $CI_MERGE_REQUEST_TARGET_BRANCH_NAME =~ $merge_request_branches
This section defines
rules
that must be met in order for this job to run. Rules have been defined to run this job in case the commit branch names or merge request target branch names match the names in regex patterns in respective variables as defined in Defining Variables above.
Here is the complete configuration for the .gitlab-ci.yml
file:
stages:
- lint
variables:
push_branches: "/^main|dev$/"
merge_request_branches: "/^main|release$/"
lint:
stage: lint
tags:
- PHP-8.1
rules:
# Run pipeline if a commit is made to these branches
- if: $CI_COMMIT_BRANCH =~ $push_branches
# Run pipeline if a merge request is created for these branches
- if: $CI_MERGE_REQUEST_TARGET_BRANCH_NAME =~ $merge_request_branches
script:
- echo "Installing dependencies"
- composer install --prefer-dist --no-progress
- echo "Linting code"
- composer run lint
- echo "Running static code analysis"
- composer run phan
- On the 'main' or 'dev' branch, make changes to your code.
- Commit and push the made changes to GitLab.
- Create a new branch in your PHP project repository.
- Make changes to your code and push the branch to GitLab.
- Create a merge request (MR) targeting the 'main' or 'release' branch.
- Navigate to your Merge Request/commit on GitLab.
- Observe the pipeline execution as it runs the
lint
stage. - Check the job logs for any errors or warnings.
- Ensure that the pipeline status reflects the success or failure of the
lint
stage.
In this section, we will visually explain the Continuous Integration (CI) process in GitLab and how it works for your PHP project.
When a developer works on a feature or bug fix, they create a new branch in the GitLab repository. Then, they make changes to the code and create a Merge Request (MR) for code review.
Developers may also make commits to branches that are covered by the rules
as described in the CI pipeline.
Upon MR creation/commit, GitLab's CI pipeline is automatically triggered. The .gitlab-ci.yml
configuration file you've set up defines the stages and jobs to be executed in the pipeline. In our case, there is only one stage, lint
.
The lint
stage will install the required dependencies using composer
. It then runs the linting process, followed by code analysis on the codebase to check for any coding standards violations or errors.
If lint
fails
- The CI pipeline reports issues in the job logs.
- The Merge Request/commit status is updated to indicate that the pipeline failed.
- Developers review the errors in the job logs and make necessary code changes and fixes.
If lint
passes
- The Merge Request/commit status is updated to indicate that the pipeline passed.
All the Pipelines and Jobs can be seen and reviewed under the Build menu of GitLab:
The maintainer can now review the lint
results in the Merge Request itself. If the pipeline indicates passed
, it signifies that the code adheres to coding standards and no violations or errors were found. This reduces the risk of merging code that may cause errors or disrupt the application.
Before merging any changes into the main codebase, it's essential to ensure that the Continuous Integration (CI) checks have been successfully completed. These checks verify that code changes adhere to coding standards, pass tests, and no error is encountered. To enforce this, follow these steps:
-
Review pipeline status: When a Merge Request (MR) is created or a commit is made, monitor the pipeline's progress and results. Ensure that all stages, such as
lint
, complete successfully. -
Merge only after success: As a maintainer, it's crucial to enforce the policy of merging changes only when the pipeline passes without errors. If the pipeline fails, work with the contributor to address the issues before proceeding with the merge.
-
Bypass pipeline check: In certain scenarios, there may be valid reasons for bypassing the CI checks temporarily. It's recommended that leads add a comment in the MR describing the reason for bypassing the CI checks. This helps maintain a record of the decision and the context behind it.
Please note that bypassing CI checks should be used sparingly and only in exceptional cases. The goal is to maintain code quality and ensure that the CI process is an integral part of our development workflow.
If your Merge Request encounters Merge Conflicts during the auto-merge stage, manual intervention may be required to resolve the conflicts before the pipeline can proceed.
Modify the script in the .gitlab-ci.yml
file to match your specific linting and code analysis commands and any additional requirements of your PHP project.
Explore this for practical demonstration of CI setups.
Setting up a CI pipeline for your PHP project offers several benefits:
- Improved code quality through automated linting and code analysis
- Early detection of errors and issues
- Streamlined collaboration through automated testing of Merge Requests and commits
Consider enhancing your CI pipeline by adding additional stages such as unit testing, integration testing, and deployment to further improve the quality and reliability of your PHP project.