Run pipeline if the branch starts with - Regexp - regex

I need to run the pipeline in gitlab only when the commit is from the branch where it starts with Feature or Bug. I tried with the following and its not working.
Can you please help me.
($CI_COMMIT_REF_NAME ==/^Feature(.?)*/ || $CI_COMMIT_REF_NAME == /^Bug(.?)*/)

The following should do the trick:
workflow:
rules:
- if: '$CI_COMMIT_REF_SLUG =~ /^feature/'
- if: '$CI_COMMIT_REF_SLUG =~ /^bug/'

Related

How to set variable inline in gitlab-ci.yaml based on regex matching?

I am trying to create a variable in gitlab-ci.yaml based on the name of the branch.
Suppose I am pushing to a branch named 3.2.7
Here is the situation:
include:
- template: "Workflows/Branch-Pipelines.gitlab-ci.yml"
variables:
PRODUCTION_BRANCH: "master"
STAGING_BRANCH: (\d)\.(\d)\.(\d)
.deploy_rules:
rules:
- if: '$CI_COMMIT_BRANCH =~ /$STAGING_BRANCH/'
variables:
SERVER_PORT: 3007 # TODO: should be 300d ; d is the second digit
I want to generate 3002 inline using regex matching.
How can I do this?
I have done some research and seems I have to use sed but I am not sure if it is the best way to do it and how to do it.
TO MAKE THE PROBLEM SIMPLER
include:
- template: "Workflows/Branch-Pipelines.gitlab-ci.yml"
variables:
TEST_VAR: sed -E 's/(\d)\.(\d)\.(\d)/300\2/gm;t;d' <<< $CI_COMMIT_BRANCH
stages:
- temp
temp:
stage: temp
script:
- echo $TEST_VAR
Should be echoing 3002 but it is echoing sed -E 's/(\d)\.(\d)\.(\d)/300\2/gm;t;d' <<< 3.2.7
You can't use variables in the regex pattern. You just have to write the regex verbatim, it cannot be directly parameterized. You also cannot use sed or other Linux utilities in variables: or other parts of your yaml. You're bound to the limitations of YAML specification and features provided by GitLab.
However, there is an option available to you that will fit your stated use case.
Dynamic variables
TEST_VAR: sed -E 's/(\d).(\d).(\d)/300\2/gm;t;d' <<< $CI_COMMIT_BRANCH
While you can't use sed or other utilities directly in variables: declarations, you can use dotenv artifacts via artifacts:reports:dotenv to set variables dynamically.
For example, a job can use sed or whatever other utilities you like to create variables which will be used by the rest of the pipeline.
stages:
- temp
create_variables:
stage: .pre
script:
- TEST_VAR="$(sed -E 's/(\d)\.(\d)\.(\d)/300\2/gm;t;d' <<< ${CI_COMMIT_BRANCH})"
- echo "TEST_VAR=${TEST_VAR}" >> dotenv.txt
artifacts:
reports:
dotenv: dotenv.txt
temp:
stage: temp
script:
- echo $TEST_VAR
Here, the .pre stage is used, which is a special stage that is always ordered before every other stage. The dotenv artifact from the create_variables job will dynamically create variables for the jobs in subsequent stages that receive the artifact.

How to use if-else condition on gitlabci

How to use if else condition inside the gitlab-CI.
I have below code:
deploy-dev:
image: testimage
environment: dev
tags:
- kubectl
script:
- kubectl apply -f demo1 --record=true
- kubectl apply -f demo2 --record=true
Now I want to add a condition something like this
script:
- (if [ "$flag" == "true" ]; then kubectl apply -f demo1 --record=true; else kubectl apply -f demo2 --record=true);
Could someone provide the correct syntax for the same? Is there any documentation for the conditions (if-else, for loop) in gitlabci?
Hereunder three syntax options for that kind of statement. From gitlab-ci documentation :
Using shell variable
deploy-dev:
image: testimage
environment: dev
tags:
- kubectl
script:
- if [ "$flag" == "true" ]; then MODULE="demo1"; else MODULE="demo2"; fi
- kubectl apply -f ${MODULE} --record=true
Using shell variable with yaml multiline block
deploy-dev:
image: testimage
environment: dev
tags:
- kubectl
script:
- >
if [ "$flag" == "true" ]; then
kubectl apply -f demo1 --record=true
else
kubectl apply -f demo2 --record=true
fi
Using gitlab rules
workflow:
rules:
- if: '$CI_PIPELINE_SOURCE == "schedule"'
when: never
- if: '$CI_PIPELINE_SOURCE == "push"'
when: never
- when: always
Using gitlab templates and variables
demo1-deploy-dev:
extends: .deploy-dev
only:
variables: [ $flag == "true" ]
variables:
MODULE: demo1
demo2-deploy-dev:
extends: .deploy-dev
only:
variables: [ $flag == "false" ]
variables:
MODULE: demo2
.deploy-dev:
image: testimage
environment: dev
tags:
- kubectl
script:
- kubectl apply -f ${MODULE} --record=true
Note that with GitLab 13.3 (August 2020), there is an improvement to the if-else rule syntax:
CI/CD rules:if support logical expressions with parentheses
If you use the rules keyword with if clauses, it’s now even more powerful, with support for bracketed expressions evaluated by the pipeline processor.
You can use more complex and efficient AND (&&) / OR (||) expressions, making your pipelines rules more logical, powerful, and easier to manage.
See Documentation and Issue.
And, with GitLab 13.8 (January 2021)
Support variables for pipeline rules
Previously, the rules keyword was limited in scope and only determined if a job should be included or excluded from pipelines. In this release, you can now decide if certain conditions are met and subsequently override variables in jobs, providing you with more flexibility when configuring your pipelines.
See Documentation and Issue.
With GitLab 13.12 (May 2021):
Support variables in CI/CD pipeline 'workflow:rules'
Previously, the rules keyword was limited in scope and only determined if a job should be included or excluded from pipelines. In 13.8, we added the ability to use the variables keyword with rules to set variable values in a job based on which rule matched.
In this release we’ve extended this ability to workflow: rules, so you can set variable values for the whole pipeline if certain conditions match.
This helps you make your pipelines even more flexible.
See Documentation and Issue.
I think you need to just add a semicolon and closing "fi" at the end.
I couldn't find a link to documentation.
script:
- (if [ "$flag" == "true" ]; then kubectl apply -f demo1 --record=true; else kubectl apply -f demo2 --record=true; fi);
In addition, in the case of a multiline block if you want or need to preserve line breaks you can use the pipe character:
script: |
if [ "$flag" == "true" ]; then
kubectl apply -f demo1 --record=true
else
kubectl apply -f demo2 --record=true
fi
To go deeper, visit https://yaml-multiline.info/
You may consider checking rules
It allows for a list of individual rule objects to be evaluated in order, until one matches and dynamically provides attributes to the job.
Available rule clauses include:
if (similar to only:variables)
changes (same as only:changes)
exists
Example:
job:
script: "echo Hello, Rules!"
rules:
- if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master"'
when: always
- if: '$VAR =~ /pattern/'
when: manual
- when: on_success
This worked for me when using powershell based gitlab scripts:
script:
- 'if ($flag -eq "true") { kubectl apply -f demo1 --record=true; } else { kubectl apply -f demo2 --record=true; }'

if condition to folder branch in Jenkinsfile

I have branch folder "feature-set" under this folder there's multibranch
I need to run the below script in my Jenkinsfile with a condition if this build runs from any branches under the "feature-set" folder like "feature-set/" then run the script
the script is:
sh """
if [ ${env.BRANCH_NAME} = "feature-set*" ]
then
echo ${env.BRANCH_NAME}
branchName='${env.BRANCH_NAME}' | cut -d'\\/' -f 2
echo \$branchName
npm install
ng build --aot --output-hashing none --sourcemap=false
fi
"""
the current output doesn't get the condition:
[ feature-set/swat5 = feature-set* ]
any help?
I would re-write this to be primarily Jenkins/Groovy syntax and only go to shell when required.
Based on the info you provided I assume your env.BRANCH_NAME always looks like `feature-set/
// Echo first so we can see value if condition fails
echo(env.BRANCH_NAME)
// startsWith better than contains() based on current usecase
if ( (env.BRANCH_NAME).startsWith('feature-set') ) {
// Split branch string into list based on delimiter
List<String> parts = (env.BRANCH_NAME).tokenize('/')
/**
* Grab everything minus the first part
* This handles branches that include additional '/' characters
* e.g. 'feature-set/feat/my-feat'
*/
branchName = parts[1..-1].join('/')
echo(branchName)
sh('npm install && ng build --aot --output-hashing none --sourcemap=false')
}
This seems to be more on shell side. Since you are planning to use shell if condition the below worked for me.
Administrator1#XXXXXXXX:
$ if [[ ${BRANCH_NAME} = feature-set* ]]; then echo "Success"; fi
Success
Remove the quotes and add an additional "[]" at the start and end respectively.
The additional "[]" works as regex

Cloudbuild.yaml command with nested quotes

I am trying to run the following command found at http://blog.wrouesnel.com/articles/Totally%20static%20Go%20builds/:
CGO_ENABLED=0 GOOS=linux go build -a -ldflags '-extldflags "-static"' .
The two inner layers of quotes are tripping me up. How to deal with this in a cloudbuild.yaml file?
Escaping quotes don't seem to work:
steps:
- name: 'gcr.io/cloud-builders/go'
args: ['build', '-o', 'main', '-ldflags', "'-extldflags \"-static\"'", '.']
env:
- 'GOOS=linux'
Update:
There is no need for such quotes. See comment in Github here: https://github.com/GoogleCloudPlatform/cloud-builders/issues/146#issuecomment-337890587
===
Original Answer
Well, to quote ' within '-quoted strings, use '' as per YAML specification:
http://yaml.org/spec/current.html#id2534365
e.g. 'here''s to a toast!'
For the above args, it would be:
['build', '-o', 'main', '-ldflags', '''-extldflags "-static"''', '.']
Whether or not the command works within Cloud Builder is beyond the scope of this question.

How can I make multiple replacements on the same file using one saltstack state?

Here's my target file:
Sonatype Nexus
# ==============
# This is the most basic configuration of Nexus.
# Jetty section
application-port=8081
application-host=0.0.0.0
nexus-webapp=${bundleBasedir}/nexus
nexus-webapp-context-path=/nexus
# Nexus section
nexus-work=/opt/nexuswork
runtime=${bundleBasedir}/nexus/WEB-INF
I know there's an easy way to do this with regex or a simple sed script:
sed -i 's/${bundleBasedir}\/..\/my\/second\/path\/002\/\/nexus/\/myfirstdir001\/g'
However, I would, ideally, prefer the saltstack way.
I would like it to look something like this:
Sonatype Nexus
# ==============
# This is the most basic configuration of Nexus.
# Jetty section
application-port=8081
application-host=0.0.0.0
nexus-webapp=/my/second/path/002/nexus # changed
nexus-webapp-context-path=/nexus
# Nexus section
nexus-work=/opt/nexuswork
runtime=/myfirstdir001/nexus/WEB-INF # changed
I haven't yet made sense of the saltstack documentation on this.
Saltstack's documentation for salt.states.file.replace seems fairly straightforward:
http://docs.saltstack.com/en/latest/ref/states/all/salt.states.file.html#salt.states.file.replace
Here's what I tried:
/opt/nexus-2.8.0/conf/nexus.properties
file: # state
- replace
- pattern: '\$\{bundleBasedir\}' # without escapes: '${bundleBasedir}/nexus'
- repl: '/my/second/path/002/nexus'
# - name: /opt/nexus-2.8.0/conf/nexus.properties
# - count=0
# - append_if_not_found=False
# - prepend_if_not_found=False
# - not_found_content=None
# - backup='.bak'
# - show_changes=True
- pattern: '\$\{bundleBasedir\}\/WEB-INF' # without escapes: ${bundleBasedir}/WEB-INF
- repl: '/myfirstdir001/'
I could maybe try multiple state IDs, but that seems inelegant.
If there's anything else I'm fuffing up, please advise!
I'd shore love to find a solution to this.
Also, if there's any demand for people improving the salt documentation, I think my team could be convinced to pitch in some.
Here's the closest thing I've found to someone else asking this question:
http://comments.gmane.org/gmane.comp.sysutils.salt.user/15138
For such a small file I would probably go with a template as ahus1 suggested.
If the file was bigger and/or we didn't want to control other lines just ensure that those two are correct, I think multiple state IDs (as mentioned by OP) is a good way to go. Something like:
/opt/nexus-2.8.0/conf/nexus.properties-jetty:
file:
- replace
- name: /opt/nexus-2.8.0/conf/nexus.properties
- pattern: '\$\{bundleBasedir\}' # without escapes: '${bundleBasedir}/nexus'
- repl: '/my/second/path/002/nexus'
/opt/nexus-2.8.0/conf/nexus.properties-nexus:
file:
- replace:
- name: /opt/nexus-2.8.0/conf/nexus.properties
- pattern: '\$\{bundleBasedir\}\/WEB-INF' # without escapes: ${bundleBasedir}/WEB-INF
- repl: '/myfirstdir001/'
I have a similar setup in my configuration but I use salt.states.file.line to replace some lines with my values. In addition I used salt.states.file.managed with a template and replace: False to initialize the file if it's missing but once it exists, only the line states are doing changes.
The salt way to do this as I understand it: Place a template file for nexus.properties inside salt and use file.managed like shown in the docs http://docs.saltstack.com/en/latest/ref/states/all/salt.states.file.html
You will end up with something like:
/opt/nexus-2.8.0/conf/nexus.properties:
file.managed:
- source: salt://nexus/nexus.properties.jinja
- template: jinja
- defaults:
bundleBasedir: "..."
You'll then use Jinja templating in your file:
# Jetty section
application-port=8081
application-host=0.0.0.0
nexus-webapp={{ bundleBasedir }}/nexus
nexus-webapp-context-path=/nexus
See here for Jinja templating: http://docs.saltstack.com/en/latest/ref/renderers/all/salt.renderers.jinja.html
I hope it helps.