The orchestration of continuous integration and continuous deployment (CI/CD) within GitLab necessitates a granular understanding of how pipelines are triggered, retried, and managed, particularly when dealing with manual interventions and merge request events. In a professional DevOps environment, the ability to rerun a pipeline is not merely a convenience but a critical requirement for validating flaky tests, reacting to external environment changes, or managing manual deployment gates. When a pipeline is executed, GitLab creates a unique instance of the CI/CD configuration defined in the .gitlab-ci.yml file, which is then mapped to a specific commit or merge request. However, the mechanics of rerunning these pipelines vary significantly depending on whether the user is attempting to retry a failed job, trigger a new pipeline for an existing merge request, or force a full pipeline restart via a manual job trigger.
The complexity of pipeline re-execution is most evident when attempting to bridge the gap between a manual job—often used as a "Deploy" button for non-technical stakeholders—and the need to execute the entire pipeline sequence again. In standard GitLab behavior, clicking a manual job button only triggers that specific job and its downstream dependencies; it does not inherently reset the pipeline to the initial stage. This creates a technical friction point for teams seeking a "one-click" full rerun experience. Furthermore, the interaction between fork projects and parent projects introduces additional layers of security and permission constraints, as the execution context shifts between the source and target environments. Understanding these nuances is essential for architects designing robust deployment workflows that balance ease of use for non-technical users with the strict security requirements of corporate infrastructure.
Manual Job Triggers and the Full Pipeline Rerun Dilemma
A common challenge encountered by DevOps engineers is the limitation of manual jobs when used as triggers for environment deployments. In a standard GitLab CI/CD configuration, a manual job acts as a gate. When a user clicks the "play" button for a manual job, GitLab executes that specific job.
The impact of this behavior is that if a deployment job is set to manual, triggering it will not rerun the preceding build, test, or security scanning stages. For users who require the entire pipeline to be validated again before a deployment occurs, this creates a fragmented experience. The consequence is that the "deployment" is not actually a fresh deployment of the latest validated state, but merely the execution of a single job within an existing, potentially stale, pipeline.
To address this, some users attempt to use the needs relationship. The needs keyword allows a job to start as soon as its dependencies are complete, regardless of the stage. However, as noted in community discussions, using needs does not change the fundamental outcome of a manual trigger; it still only executes the targeted job and its immediate requirements, rather than restarting the entire pipeline from the first stage.
Another attempted workaround involves the use of child pipelines. In this scenario, a user might try to define the environment only for a trigger job that launches a child pipeline. However, this approach is forbidden by GitLab's current architectural constraints. Consequently, the only viable method to force a complete pipeline rerun from a manual job is to integrate the GitLab API. By writing a script within the manual job that calls the Pipelines API, the job can programmatically trigger a new pipeline instance for the current ref.
Merge Request Pipeline Mechanics
Merge request pipelines are specialized pipelines that run specifically in the context of a merge request. These are distinct from branch pipelines and are essential for validating code before it is merged into a target branch.
These pipelines are triggered under specific conditions:
- The creation of a new merge request from a source branch containing one or more commits.
- The pushing of a new commit to a source branch that is already associated with an active merge request.
- The manual selection of "Run pipeline" from the Pipelines tab within a merge request.
The impact of using merge request pipelines is that they isolate the testing environment to the source branch only, ignoring the target branch's content until a merged results pipeline is utilized. This prevents the "pollution" of the target branch's state during the validation phase.
To implement these pipelines, the .gitlab-ci.yml file must be configured with specific rules. The primary requirement is the use of the CI_PIPELINE_SOURCE variable.
- The configuration must include rules or workflow rules that match
CI_PIPELINE_SOURCE == "merge_request_event". - It is critical to note that rules defined within an
include:componentblock do not satisfy this requirement; the rules must be explicitly defined in the main configuration or included files that are processed as part of the primary pipeline logic.
The requirements for executing these pipelines include:
- The user must possess the Developer, Maintainer, or Owner role for the source project.
- The repository must be a native GitLab repository, as external repositories do not support this specific pipeline trigger logic.
Pipeline Execution in Forked Projects
When dealing with external contributors who work in forks, GitLab implements a strict security model to protect the parent project's secrets and runners. The behavior of the pipeline depends on who triggers it and where it is configured to run.
By default, a merge request from a fork triggers a pipeline that:
- Is created and executed within the fork (source) project.
- Utilizes the CI/CD configuration and variables defined in the fork project.
- Uses the fork project's own runners and resources.
This isolation is a security measure. Because fork merge requests can contain malicious code, allowing them to run in the parent project by default would risk the exposure of sensitive CI/CD variables (secrets).
However, members of the parent project can choose to run the pipeline in the parent project. When this occurs:
- The pipeline is created and run in the target (parent) project.
- It uses the CI/CD configuration present in the fork project's branch.
- It leverages the parent project's CI/CD settings, resources, and variables.
- It uses the permissions of the parent project member who triggered the action.
The impact of this shift is significant for security. Running the pipeline in the parent project allows the use of trusted runners, ensuring that the code is executed in a controlled environment. Because of the risks associated with malicious code in forks, GitLab displays a mandatory warning that the user must accept before the pipeline runs, unless the trigger is performed via the API or the /rebase quick action.
Advanced Triggering and Custom Inputs
For complex pipelines, GitLab allows the use of custom inputs to modify the pipeline's behavior at runtime. This is particularly useful for merge request pipelines where different configurations may be needed for different test suites.
To use custom inputs, the .gitlab-ci.yml file must define a spec: inputs section. The process for triggering these pipelines is as follows:
- Navigate to the project in the left sidebar.
- Go to Code > Merge requests and open the specific merge request.
- Select the Pipelines tab.
- Click the Run pipeline dropdown list.
- Select "Run pipeline with modified values".
This opens a form pre-filled with the source branch, allowing the user to modify input values and set CI/CD variables before selecting "Run pipeline". This provides a layer of flexibility that standard triggers lack, allowing for parameterized builds within the MR context.
The Pipelines API and Programmatic Re-execution
When the UI limitations of GitLab prevent a specific re-execution flow—such as the need to trigger a full pipeline from a manual job—the Pipelines API serves as the primary solution. This API is available across all tiers (Free, Premium, Ultimate) and all offerings (GitLab.com, Self-Managed, Dedicated).
The API allows for the interaction with pipelines through various endpoints. One of the most critical capabilities is the ability to list and retrieve pipeline data.
The endpoint GET /projects/:id/pipelines allows users to list pipelines. By default, child pipelines are omitted from these results. To include them, the source parameter must be set to parent_pipeline.
The available parameters for filtering and ordering these results are:
- id: The project ID or URL-encoded path.
- name: Filter by pipeline name.
- orderby: Order by id, status, ref, updatedat, or user_id.
- ref: Filter by specific branch or tag.
- scope: Filter by running, pending, finished, branches, or tags.
- sha: Filter by commit SHA.
- sort: Ascending or descending order.
- source: Filter by the pipeline source.
- status: Filter by created, waitingforresource, preparing, pending, running, success, failed, canceled, skipped, or manual.
- updated_after: Filter by ISO 8601 format date.
Additionally, the API allows for the retrieval of pipeline variables via GET /projects/:id/pipelines/:pipeline_id/variables. This is essential for scripts that need to verify the state of a pipeline before triggering a rerun.
Example of a request to retrieve pipeline variables using curl:
bash
curl --request GET \
--header "PRIVATE-TOKEN: <your_access_token>" \
--url "https://gitlab.example.com/api/v4/projects/1/pipelines/46/variables"
The response from this API provides a JSON array of variables, including the key, value, and variable type (e.g., env_var).
Analysis of the Retry Button Limitation
A significant point of contention in the GitLab community is the availability of the "Retry" button for successful pipelines. Currently, GitLab typically provides the retry option for failed jobs. However, there are numerous technical scenarios where a successful pipeline must be rerun.
These scenarios include:
- Unreliable tests (flaky tests) where the user is skeptical that the success is repeatable.
- Jobs that depend on external factors, such as an external API or a remote resource that may have changed.
- Jobs that rely on predefined CI variables which can be modified without a change to the code itself.
The current limitation is that the "Retry" button is not always available for successful pipelines. The suggested workaround is to use the "Run Pipeline" feature under CI/CD > Pipelines. However, this workaround often fails for merge request pipelines. If all jobs are defined specifically for merge_requests, the "Run Pipeline" action may return an error stating "No stages / jobs for this pipeline".
This occurs because the "Run Pipeline" button in the general CI/CD menu does not always correctly pass the merge_request_event context required by the job rules in the .gitlab-ci.yml file. This creates a gap where the only way to truly rerun a successful merge request pipeline is through the specific "Run pipeline" button within the Merge Request's own Pipelines tab, or by using the API.
Summary of Pipeline Triggering and Rerun Methods
The following table summarizes the different methods of triggering or rerunning pipelines based on the context and requirements.
| Method | Context | Trigger Requirement | Result |
|---|---|---|---|
| Manual Job Button | Existing Pipeline | User clicks "play" | Only the specific job and its dependencies run |
| Pipelines Tab "Run" | Merge Request | Developer+ Role | New pipeline for the MR source branch |
| API Call | Programmatic | Private Token | New pipeline instance for the specified ref |
| Fork MR Trigger | Forked Project | Parent Project Member | Pipeline runs in parent project with trusted runners |
| Modified Values Run | Custom Inputs | spec: inputs in YAML |
Pipeline runs with user-defined parameters |
Conclusion
The process of rerunning pipelines in GitLab is a multifaceted operation that depends heavily on the project's configuration and the user's permissions. While the platform provides intuitive buttons for retrying failed jobs, the requirement to rerun a successful pipeline or to trigger a full pipeline sequence from a manual deployment gate requires a more advanced technical approach. The reliance on CI_PIPELINE_SOURCE == "merge_request_event" ensures that merge request pipelines are isolated and validated correctly, but it also introduces complexities when using the global "Run Pipeline" interface.
For organizations seeking a seamless deployment experience for non-technical users, the native manual job button is insufficient for full pipeline restarts. The integration of the Pipelines API is the only definitive way to achieve a programmatic "full rerun" from within a job. Furthermore, the security considerations regarding forked projects highlight the necessity of running pipelines in the parent project to ensure that trusted runners are used and secrets are protected. Ultimately, a robust GitLab CI/CD strategy must combine precise YAML rule definitions, a clear understanding of the API's capabilities, and a conscious approach to managing the lifecycle of merge request pipelines to ensure both security and operational efficiency.