Gitlab CI: do not trigger pipeline when commit done by certain user - gitlab

We have an automated process that commits a status file at the end of every merge request. We would like to configure a pipeline that runs on every commit except for commits by this user. Currently the pipeline is configured like so:
test:
stage: test
script:
- make test
except:
changes:
- "the_status_file"
However, sometimes the status file doesn't change at all. In that case, the pipeline runs.
Instead, we would like to configure the pipeline to ignore commits by a certain user (this user being the automated one we created). Is this possible in gitlab ci?

I am not aware of such feature in Gitlab CI. However if your user is a script creating and pushing commits and you have control over it, you could decide whether to trigger the CI pipeline or not by inserting (or not) [ci skip] or [skip ci] in your commit message.
See: https://docs.gitlab.com/ee/ci/pipelines/#skip-a-pipeline

That could be done with rules
rules:
- if: '$GITLAB_USER_LOGIN == "username"'
when: never
- when: on_success

Related

Is it possible to run a gitlab pipeline job only once, when a merge request is created?

Is it possible to configure a job in a gitlab pipeline to only run once, when a merge request is created?
Using the rule "
'$CI_PIPELINE_SOURCE == "merge_request_event"'
" does not work, as it will also be triggered when there are new commits to the branch with the open merge request.

Detect a build requested by pull request and one run by any updates to the PR

I currently have a task that I intend to run only once when a PR is created. Any pipeline runs due to new commits should not trigger the task. I was wondering if there is a way to detect the runs triggered by changes to code in the PR? When I use the predefined variable $(Build.Reason) I get back PullRequest for both builds(One triggered when PR is created and other when updates are made to PR).
This is what I have in my pipeline and I have enabled build validation for my pipeline.
trigger:
- master
pr:
- master
I don't think there's a way to differentiate the "PR is created" and "PR is updated" build reasons based only on the predefined variables.
However, you can choose a different route depending on what this task you should only run once is. If it is something that can be wrapped into a service with a public endpoint, you can try leveraging the Webhooks.
So, if this is an option for you, try the following:
wrap the functionality required to run only on the PR creation into the service with the public endpoint
create a webhook, choose "Pull request created" event type and enter the public URL of your service
As a result, your build logic won't branch depending on the build reason, and that specific action will be run by the webhook.
I understand it all sounds like a hack and unnecessary complexity, but it's up to you to decide whether it fits your case. At least, this is possible technically.

GitLab CI: MERGE_REQUEST_EVENT not triggered by update?

I'm testing GitLab CI pipelines.
I have created a merge request named "TEST" that have its gitlab-ci.yml with a rule like below:
if '$CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TITLE == "TEST"'
It worked fine as I expected. Create event triggered the merge_request_event.
However, if I create a merge request have another title and then I update it to "TEST", It doesn't seems to trigger the merge_request_event.
According to this document, merge_request_event is supposed to be triggered by updated too.
For pipelines created when a merge request is created or updated. Required to enable merge request pipelines, merged results pipelines, and merge trains.
Do I take it wrong or missed important information or documents?
Pushing to a branch will trigger a pipeline, and if that branch has an associated Merge Request, then the variable CI_PIPELINE_SOURCE will be equal to merge_request_event.
On the other hand, afaik just editing the title of a Merge Request on the GitLab UI will not trigger a pipeline, so your logic will never be evaluated unless you also push to the branch.
The documentation is correct, but perhaps the meaning is not 100% clear.
For pipelines created when a merge request is created or updated.
Stated more precisely:
When an MR action creates a pipeline, $CI_PIPELINE_SOURCE will be equal to merge_request_event
However, it does not mean to imply that any update will create a pipeline. Updating the MR title does not create a pipeline, so this is not applicable to that scenario.
However, after you have changed the title, if some other event creates a new pipeline (specifically: push events to the MR source branch or manually running a new pipeline on the MR), the rule will evaluate to true and the job will be included in the created pipeline.
Per the docs:
Merge request pipelines:
Run when you:
Create a new merge request.
Push a new commit to the source branch for a merge request.
Select Run pipeline from the Pipelines tab in a merge request.
There appears to be an existing bug with the CI/CD env vars for Merge Requests, where the subsequent pipelines after the initial MR is opened are relegated to push rather than merge_request_event for the CI_PIPELINE_SOURCE.
https://gitlab.com/gitlab-org/gitlab/-/issues/369383#note_1239166213

How to run a job after MR is approved, but reject MR, if the job failed?

I would like some automated checks were done after MR is approved, because for those checks pipeline has to access protected variables.
If these checks fail, MR should be rejected.
In other words the desired sequence should be this:
MR created -> build -> run tests -> MR approved (no malicious exposure of protected variables)-> merged to protected branch -> run checks -> rollback on failure.
Is this possible?
You can do this by using the Gitlab API and adding two new jobs at the end of the pipeline.
The when keyword is one of the many ways to control which jobs are executed in a pipeline. Two of the available when options will be useful here. The first job to put at the end of your pipeline will be for the success condition:
approve_merge_request:
stage: approve_merge_request
when: on_success
script:
- # this will call the Gitlab Merge Requests API and approve it. More on this below
This parameter to when is actually the default, so you could leave the when off of this step and it would still work. I added it here for clarity. What it means is that this job will only run if every other job in the pipeline passed. However, if a job fails but has the allow_failure: true attribute, it is still considered a pass and this job will run (there's currently no way to detect that some jobs were allowed to fail in a when condition). In addition, jobs with when: manual that haven't run are considered passed, even though it could later fail. when: manual means the job has to be started by an API call or UI interaction by a user.
The second job will handle our failure condition:
reject_merge_request:
stage: approve_merge_request
when: on_failure
script:
- # this will call the Gitlab Merge Requests API and reject it. More on this below
This parameter to when means that this job will only run if at least one job prior to this has failed, and doesn't have allow_failure: true.
The Merge Requests API can be used to approve, reject, comment on, and merge a Merge Request, among other options. The full documentation is available here: https://docs.gitlab.com/ee/api/merge_requests.html. Unfortunately, the API to use the "approvals" feature of merge requests is available only to paying customers, but you can still get a similar result without the approvals.
You can approve a Merge Request (note, this doesn't merge it, that's "accepting" the merge request. Also, this is a paid feature so is only available to Starter or Bronze customers and above) with the API operation here: https://docs.gitlab.com/ee/api/merge_request_approvals.html#approve-merge-request. After you approve the Merge Request, you probably want to accept it, which will merge the source branch into the target branch. That operation is outlined below.
You can get all of the required ids from the predefined variables Gitlab CI gives you. The project ID can be retrieved from the variable $CI_PROJECT_ID. The Merge Request IID is different from the Merge Request ID. The "ID" version is a unique ID across your entire Gitlab instance, and the "IID" version is specific to the project it's in. For this operation we need the IID. You can get that with the variable $CI_MERGE_REQUEST_IID. You should check that each variable exists before trying to use it as it will cause issues in your API call. It will exist for all pipelines associated with a Merge Request that is open.
There isn't equivalent functionality in Gitlab Merge Requests to "reject" other than commenting and closing, which I outline below.
If you're not a paid customer, or you want to accept and merge the request, you want to use the Accept Merge Request operation here: https://docs.gitlab.com/ee/api/merge_requests.html#accept-mr. This uses the same variables from above.
Finally, if you're not a paid user but still want to "reject" the merge request, you can use the Notes API to add a comment to the Merge Request. The operation to add a comment to a merge request is here: https://docs.gitlab.com/ee/api/merge_requests.html#accept-mr.
After commenting, if you want to close the merge request, you can do so with the Update MR operation and setting the state_event to close: https://docs.gitlab.com/ee/api/merge_requests.html#update-mr

Tear Down Resource Groups on PR Completion

I am using Pull Request Builds as outlined below to create a resource group with contained resources
https://learn.microsoft.com/en-us/azure/devops/pipelines/release/deploy-pull-request-builds?view=azure-devops
This all works as expected and I am using the SourceBranch of the Pull Request to name by new Resource Group.
My intention is to then delete the Resource Group automatically on completion of the PR. I believed this could be achieved by using another Release pipeline triggered on the build triggered by the PR merge to Master. The issue is that I have no reference to the Branch name in this new Release, the SourceBranch is 'master'
Can anyone come up with a solution? Essentially I need to delete a Resource Group named after a Branch on completion of a PR which merges said branch to master.
There may be multiple PRs in review at any one time so I would prefer that the solution does not queue any stages.
The issue is that I have no reference to the Branch name in this new Release, the SourceBranch is 'master'
The Pull Request triggered release pipeline is triggered by refs/pull/x/merge. This is related with the Pull Request. Then the Pull Request information can be obtained through environment variables.
When the Pull Request Completes, the reason for running the release pipeline is that the master branch has changed. The trigger branch is master.
In this case, the variable BUILD_SOURCEBRANCHNAME is master.
Based on my test, I couldn't find the environment variables related to Pull Request Source Branch.
So I am afraid that there is no such variable could meet your requirements.
For a workaround:
If you want to get the expected source branch name , you may need to use the target branch to run the release pipeline again(Manual or Continuous deployment trigger).You need to make sure that the trigger branch is pull request source branch. Then the BUILD_SOURCEBRANCHNAME variable could be the expected one.
not queue any stages.
You could try to set the Artifacts filters (include and exclude) in Release Pipeline stages.
For example:
Result:
Hope this helps.

Resources