GitLab pipeline is running twice on release-cli image - gitlab

When running a release job via the GitLab function based on the registry.gitlab.com/gitlab-org/release-cli:latest image, it is always run twice, for a very simple example.
job:
image: registry.gitlab.com/gitlab-org/release-cli:latest
script:
- echo 'Execution tag generation...'
release:
tag_name: '$CI_COMMIT_BRANCH-$CI_COMMIT_SHORT_SHA'
name: 'Generated tag on $CI_COMMIT_BRANCH branch on $CI_COMMIT_TIMESTAMP with Git Short Id $CI_COMMIT_SHORT_SHA'
description: 'Tag is generated through CI/CD pipeline'
I tried to prevent this with a rule, but then the pipeline is not triggered at all.
job:
image: registry.gitlab.com/gitlab-org/release-cli:latest
rules:
- if: $CI_COMMIT_TAG
when: never
script:
- echo 'Execution tag generation...'
release:
tag_name: '$CI_COMMIT_BRANCH-$CI_COMMIT_SHORT_SHA'
name: 'Generated tag on $CI_COMMIT_BRANCH branch on $CI_COMMIT_TIMESTAMP with Git Short Id $CI_COMMIT_SHORT_SHA'
description: 'Tag is generated through CI/CD pipeline'
Any help would be great, I tried to highlight only this aspect, my whole pipeline itself is much bigger ;).

Related

How to Automatically run the Deploy (No manual action) with Gitlab CI and Terraform?

My gitlab ci pipeline always blocks the terraform deploy, requiring manual action to start it. Is it possible to make it automatic instead?
From terraform gitlab yaml example
stages:
- validate
- test
- build
- deploy
- cleanup
sast:
stage: test
include:
- template: Terraform/Base.gitlab-ci.yml # https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/ci/templates/Terraform/Base.gitlab-ci.yml
fmt:
extends: .terraform:fmt
needs: []
validate:
extends: .terraform:validate
needs: []
build:
extends: .terraform:build
deploy:
extends: .terraform:deploy
dependencies:
- build
environment:
name: $TF_STATE_NAME
action: start
when: on_success
destroy:
extends: .terraform:destroy
environment:
name: $TF_STATE_NAME
action: stop
when: manual
Based on the documentation, when: on_success should automatically run the deploy command when the build stage succeeds. However, it still requires manual actions. Removing the when command is the same, it always requires a manual action to start the deploy.
Given I'm using gitlab's terraform template, is this hard coded to require manual actions to enable a deploy?
It's been a little while since I've worked on GitLab, but the template you reference has it as a rule:
.terraform:deploy: &terraform_deploy
stage: deploy
script:
- cd "${TF_ROOT}"
- gitlab-terraform apply
resource_group: ${TF_STATE_NAME}
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
when: manual
Which is different from just the when keyword that you're using.
What if you tried overriding with with your own rule?
deploy:
extends: .terraform:deploy
dependencies:
- build
environment:
name: $TF_STATE_NAME
action: start
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
when: on_success
Or better yet, just create/manage your own template from a repo of your own. Then you can modify the rules in there and delete the when: manual piece.

Scaffold out a job policy pattern that uses feature branches and tags in Gitlab

I have a task:
Scaffold out a job policy pattern that uses feature branches and tags
to gate review, release and staging/production job execution
but I don't really understand this question - what should be done here?
#Edit
There was an answer from #live but now it's removed for some reason.
Anyway, he wrote:
Use GitLab's feature branching and tagging features to manage the
different versions of your code. Whenever you start working on a new
feature, create a new feature branch in GitLab and push your code
changes to that branch. When the feature is complete and ready to be
merged into the main branch, create a new tag in GitLab to mark the
point in the code where the feature was added.
Use the .gitlab-ci.yml file to define rules for when each job should
be run. For example, you might specify that the build job should only
be run when code is pushed to a feature branch, and the deploy job
should only be run when a new tag is created.
Does it mean just to create a feature branch and then in gitlab-ci.yml file add e.g
only:
- master
To run some stage only for e.g master or other specified branch?
I found: https://about.gitlab.com/handbook/customer-success/professional-services-engineering/education-services/gitlabcicdhandsonlab6.html
there is example:
deploy review:
stage: review
# only:
# - branches
# except:
# - master
script:
- echo "Do your average deploy here"
rules:
- if: '$CI_COMMIT_REF_NAME == "master"'
when: never
- if: '$CI_COMMIT_TAG'
when: never
- when: always
environment:
name: review/$CI_COMMIT_REF_NAME
deploy release:
stage: deploy
# only:
# - tags
# except:
# - master
script:
- echo "Deploy to a production environment"
rules:
- if: '$CI_COMMIT_REF_NAME != "master" && $CI_COMMIT_TAG'
when: manual
environment:
name: production
deploy staging:
stage: deploy
# only:
# - master
script:
- echo "Deploy to a staging environment"
rules:
- if: '$CI_COMMIT_REF_NAME == "master"'
when: always
- when: never
environment:
name: staging
what was expected

How to exclude the master branch from the GitLab 13 ci build process?

I want the build process to run for all branches when I add a tag. Except for the master branch.
deploy_qas:
stage: deploy
script:
- echo "Implatado em QAS"
environment:
name: qas
url: https://env.br
only:
- tags
except:
- master
This way it is not working.
I am using GitLab 13 ce.
The new Gitlab syntax uses rules.
only and except are not being actively developed. rules is the preferred keyword to control when to add jobs to pipelines.
Solution with rules:
deploy_qas:
stage: deploy
script:
- echo "Implatado em QAS"
environment:
name: qas
url: https://env.br
rules:
- if: $CI_COMMIT_BRANCH == 'master'
when: never
- if: $CI_COMMIT_TAG
# `when: always` is implied here

Accept merge request without running manual stages

I have a pipeline with 3 stages: build, deploy-test and deploy-prod. I want stages to have following behavior:
always run build
run deploy-test automatically when on master or manually when on other branches
run deploy-prod manually, only available on master branch
My pipeline configuration seems to achieve that but I have a problem when trying to merge branches into master. I don't want to execute deploy-test stage on every branch before doing merge. Right now I am required to do that as the merge button is disabled with a message Pipeline blocked. The pipeline for this merge request requires a manual action to proceed. The setting Pipelines must succeed in project is disabled.
I tried adding additional rule to prevent deploy-test stage from running in merge requests but it didn't change anything:
rules:
- if: '$CI_MERGE_REQUEST_ID'
when: never
- if: '$CI_COMMIT_BRANCH == "master"'
when: on_success
- when: manual
Full pipeline configuration:
stages:
- build
- deploy-test
- deploy-prod
build:
stage: build
script:
- echo "build"
deploy-test:
stage: deploy-test
script:
- echo "deploy-test"
rules:
- if: '$CI_COMMIT_BRANCH == "master"'
when: on_success
- when: manual
deploy-prod:
stage: deploy-prod
script:
- echo "deploy-prod"
only:
- master
The only way I got it to work was to set ☑️ Skipped pipelines are considered successful in Setttings > General > Merge requests > Merge Checks
and marking the manual step as "allow_failure"
upload:
stage: 'upload'
rules:
# Only allow uploads for a pipeline source whitelisted here.
# See: https://docs.gitlab.com/ee/ci/jobs/job_control.html#common-if-clauses-for-rules
- if: $CI_COMMIT_BRANCH
when: 'manual'
allow_failure: true
After this clicking the Merge when Pipeline succeeds button …
… will merge the MR without any manual interaction:
I've opened a merge request from branch "mybranch" into "master" with the following .gitlab-ci.yml:
image: alpine
stages:
- build
- deploy-test
- deploy-prod
build:
stage: build
script:
- echo "build"
# run deploy-test automatically when on master or manually when on other branches
# Don't run on merge requests
deploy-test:
stage: deploy-test
script:
- echo "deploy-test"
rules:
- if: $CI_MERGE_REQUEST_ID
when: never
- if: '$CI_COMMIT_BRANCH == "master"'
when: on_success
- when: manual
# run deploy-prod manually, only available on master branch
deploy-prod:
stage: deploy-prod
script:
- echo "deploy-prod"
rules:
- if: '$CI_COMMIT_BRANCH == "master"'
when: manual
Notes:
only is deprecated, so I replaced it with if
I added Alpine image to make the jobs run faster (slimmer container); it doesn't affect the logic
When I pushed changes to branch "mybranch", GitLab did the following:
showed a blue "Merge when pipeline succeeds" button on my MR
ran "build" stage
skipped "deploy-prod" stage (only available on "master" branch)
gave me a manual "play" button to run the job on "mybranch"
at this point, the pipeline status is "blocked" and the MR is showing "Pipeline blocked. The pipeline for this merge request requires a manual action to proceed"
now I manually start the "deploy-test" stage by selecting the Play icon in the Pipelines screen
pipeline status indicator changes to "running" and then to "passed"
my merge request shows the pipeline passed and gives me the green "Merge" button
There are a number of variables that are available to the pipeline on runtime - Predefined variables reference
Some are available specifically for pipelines associated with merge requests - Predefined variables for merge request pipelines
You can utilize one or more of these variables to determine if you would want to run the deploy-test job for that merge request.
For example, you could use mention the phrase "skip_cicd" in your merge request title, access it with CI_MERGE_REQUEST_TITLE variable and create a rule. Your pipeline would look somewhat like this (please do test the rule, I have edited the pipeline off the top of my head and could be wrong) -
stages:
- build
- deploy-test
- deploy-prod
build:
stage: build
script:
- echo "build"
deploy-test:
stage: deploy-test
script:
- echo "deploy-test"
rules:
- if: '$CI_MERGE_REQUEST_TITLE == *"skip_cicd"*'
when: never
- if: '$CI_COMMIT_BRANCH == "master"'
when: on_success
- when: manual
deploy-prod:
stage: deploy-prod
script:
- echo "deploy-prod"
only:
- master

Attach pipeline artifact to release in GitLab

In my repo only source files are checked in — the code is tested and the dist files are generated in a pipeline. I then want to be able to tag a specific version and attach the artifacts generated by this pipeline to it. Ideally this should all happen with as little manual intervention as possible.
What is the best way to reference pipeline artifacts from a release?
You can use the release-cli in a stage after the job you built your app, to upload to a release a file form a previous job you'll need that build job id that you can store in a file in the artifacts:
build:
stage: build
script:
- echo "Build your app"
- echo "${CI_JOB_ID}" > CI_JOB_ID.txt # This way you know the job id in the next stage
artifacts:
paths:
- your_app.exe
- CI_JOB_ID.txt
expire_in: never
rules:
- if: $CI_COMMIT_TAG
release:
stage: release
image: registry.gitlab.com/gitlab-org/release-cli:latest
script:
- |
release-cli create --name "Release $CI_COMMIT_TAG" --tag-name $CI_COMMIT_TAG \
--assets-link "{\"name\":\"Executable file\",\"url\":\"https://gitlab.com/some/repo/-/jobs/`cat CI_JOB_ID.txt`/artifacts/file/your_app.exe\"}"
rules:
- if: $CI_COMMIT_TAG
This way every time you tag your repo, it will create a release if the pipeline succeed.

Resources