2 environment variables need to do a equally check before carry on the next sep in my workflow
- name: version check
env:
version_in_code : "v$(poetry version -s)"
version_in_tag : $(git describe --exact-match --tags $(git log -n1 --pretty='%h'))
version_is_equal: ${{ env.version_in_code != env.version_in_tag }}
run: |
if [ ${{ env.version_is_equal }} ]; #here comes the error
then
echo " ${{ env.version_in_tag }} will be released"
else
git push -d origin ${{ env.version_in_tag }}
echo "⛔️ Tag-version: ${{ env.version_in_tag }} and Code-version: ${{ env.version_in_code are NOT equivalent"
exit 1
fi
Using $env.version_is_equal is not allowed inside the if condition check, and the error message is very confusing: Unexpected symbol: 'are' how can I solve this issue?
There is the syntax issue pointed out by Gui, but there is also a Bash problem: this
[ ${{ env.version_is_equal }} ]
is either [ true ] or [ false ]. This will always evaluate to true, because the construct checks if it contains a non-empty string; it doesn't care if the string is true or false.
Then, you can replace ${{ env.version_is_equal }} with $version_is_equal; doesn't make much of a difference, but it's more convenient.
To fix the comparison, you either have to compare to a string:
if [ "$version_is_equal" = 'true' ]; then
or run it as a command (without the [ ... ]), which is shorter, but a bit more magic:
if "$version_is_equal"; then
This works because true and false are commands returning a success/failure exit status.
Notice that this
version_in_tag : $(git describe --exact-match --tags $(git log -n1 --pretty='%h'))
is evaluated only when it is used, and not when it is assigned. Until it is used, it's just a string. This may or may not be the intention, but it's in my opinion more clear to make the assignment part of the script itself:
version_in_tag=$(git describe --exact-match --tags $(git log -n1 --pretty='%h'))
It seems there is an error in the syntax.
You didn't close the env variable on the error message implementation:
echo "⛔️ Tag-version: ${{ env.version_in_tag }} and Code-version: ${{ env.version_in_code are NOT equivalent"
You used ${{ env.version_in_code instead of ${{ env.version_in_code }}
Related
I need to check if steps.get_acc.outputs.acc < 1 but right now the steps.get_acc.outputs.acc is a string how to make it an integer?
cml.yaml
name: MOPS
on: [push]
jobs:
run:
runs-on: [ubuntu-latest]
steps:
- uses: actions/checkout#v2
- uses: iterative/setup-cml#v1
- uses: actions/setup-python#v2
with:
python-version: '3.x'
- name: cml
id: get_acc
shell: pwsh
env:
repo_token: ${{ secrets.GITHUB_TOKEN }}
run: |
pip3 install -r requirements.txt
python train.py
$firstLine = Get-Content -Path 'metrics.txt' -TotalCount 1
$digits = $firstline.Split(':')[-1]
$acc = [int]$digits
Write-Output "::set-output name=acc::$acc"
- name: Check acc
if: ${{steps.get_acc.outputs.acc <1 }}
uses: actions/github-script#v3
with:
script: |
core.setFailed('Accuracy dropped')
The Github Documentation for output explained that:
The value that the output parameter will be mapped to can be set to a string or an expression with context. For example, you can use the steps context to set the value of an output to the output value of a step.
Taking a look at the Literals Github documentation, we can note that:
As part of an expression, we can use boolean, null, number, or string data types. Boolean literals are not case sensitive, so we can use true or True.
Therefore, it all depends on the way you set the output variable.
Example to set a number as output:
outputs:
random-number:
description: "Random number"
value: ${{ steps.random-number-generator.outputs.random-id }}
runs:
using: "composite"
steps:
- id: random-number-generator
run: echo "::set-output name=random-id::$(echo $RANDOM)"
shell: bash
EDIT:
Moreover the syntax you used for the if condition isn't correct, you need to remove the ${{ }} to make it work.
Example with if condition:
job:
runs-on: ubuntu-latest
steps:
- name: step-1
id: xyz
run: echo "::set-output name=acc::$(echo $RANDOM)"
- name: step-2
if: steps.xyz.outputs.acc < 1
run: |
echo "Number lower than 1"
echo "${{ steps.xyz.outputs.acc }}"
- name: step-3
if: steps.xyz.outputs.acc > 1
run: |
echo "Number higher than 1"
echo "${{ steps.xyz.outputs.acc }}"
It looks like you have been given an answer on how to handle it as an integer, but given that you are setting the output via code. Why not just evaluate the integer in your code and then set a true/false boolean value or a Y/N string? If all you need to do is use the value as an If condition why bother to set the integer value? You could just evaluate it and set the condition at the source.
I'm having an issue accessing a list within a dictionay in ansible.
It's actually more complex than this, I've made a simplified version of the issue for brevity.
ansible version is 2.9
The dictionary looks like:
data_dict:
data:
arch_paths:
- /opt/data1/20201007_test1
- /opt/data1/20201013_test2
- /opt/data1/20201029_test3
bucket: host-data
path: archives/host
src_path: /opt/data1
targz:
arch_paths:
- /opt/data2/20201005.tar.gz
- /opt/data2/20201013.tar.gz
- /opt/data2/20201029.tar.gz
bucket: app-data
path: archives/app
src_path: /opt/data2
My task examples:
- name: print files to archive
debug:
msg: "{{item.value.arch_paths}}"
loop: "{{ data_dict|dict2items }}"
- name: Archive the things
shell: echo "{{item.value.bucket}} -k {{item.value.path}} -p {{item.value.src_path}} {{item.value.arch_paths}}" >> /var/log/put.log
loop: "{{ data_dict|dict2items }}"
These run as expected. But, what ends up in the log file is:
host-data -k archives/host -p /opt/data1 [u'/opt/data1/20201007_test1', u'/opt/data1/20201013_test2', u'/opt/data1/20201029_test3']
app-data -k archives/app -p /opt/data2 [u'/opt/data2/20201005.tar.gz', u'/opt/data2/20201013.tar.gz', u'/opt/data2/20201029.tar.gz']
I want to remove the u'...' and commas so I just have the values with spaces e.g.
host-data -k archives/host -p /opt/data1 /opt/data1/20201007_test1 /opt/data1/20201013_test2 /opt/data1/20201029_test3
app-data -k archives/app -p /opt/data2 /opt/data2/20201005.tar.gz /opt/data2/20201013.tar.gz /opt/data2/20201029.tar.gz
I've seen similar problems on this site but have been unable to adapt any of the solutions.
This happens because arch_paths is a list, so, you just need to join the list items: item.value.arch_paths | join(' ').
With the task:
- shell: echo "{{ item.value.bucket }} -k {{ item.value.path }} -p {{ item.value.src_path }} {{ item.value.arch_paths | join(' ') }}" >> /var/log/put.log
loop: "{{ data_dict|dict2items }}"
It gives a file /var/log/put.log containing:
host-data -k archives/host -p /opt/data1 /opt/data1/20201007_test1 /opt/data1/20201013_test2 /opt/data1/20201029_test3
app-data -k archives/app -p /opt/data2 /opt/data2/20201005.tar.gz /opt/data2/20201013.tar.gz /opt/data2/20201029.tar.gz
You can currently set env vars via:
- name: Configure Environment Variables
uses: allenevans/set-env#v1.0.0
with:
CDN_PATH: app-foo/${{ github.run_id }}
CDN_URL: 'https://cdn.mycompany.com'
JIRA_TICKET_ID: ${{ match(github.ref, ...) }} # How can I extract a string from a branch name?
https://docs.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions#functions
https://docs.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions
How can I extract a string from the branch name?
JIRA_TICKET_ID: ${{ match(github.ref, ...) }}
I don't believe there is a build in function in github actions to do that. But you can run a step before your action that gets the jira ticket for you.
NOTE: You will need to modify the sed regex to the one to get your ticket. Right now it only gets the branch name from the ref
- id: getjiraticket
run: echo "::set-output name=jiraticketid::`echo "${{ github.ref }}" | sed 's/.*\///'`"
- name: Configure Environment Variables
uses: allenevans/set-env#v1.0.0
with:
CDN_PATH: app-foo/${{ github.run_id }}
CDN_URL: 'https://cdn.mycompany.com'
JIRA_TICKET_ID: ${{ steps.getjiraticket.outputs.jiraticketid }}
I have created a pipeline build variable "svctag" and assigned its value to blank (empty string). Now trying to execute below script inside a job in yaml file. Every time it prints "svctag is not blank". Not sure what I am doing wrong.
Please help.
- ${{ if eq('$(svctag)', '') }}:
- script: echo 'svctag is blank'
- ${{ if ne('$(svctag)', '') }}:
- script: echo 'svctag is not blank'
As I know, this format is only applied in YAML template. Now, the issue is the variable called method you are using is not correct.
You should use the format variables['svctag'] instead of $(svctag) to access the variable which declared previously while you using YAML.
So, you should change your script as
- ${{ if eq(variables['svctag'], '') }}:
- script: echo it is true
- ${{ if ne(variables['svctag'], '') }}:
- script: echo it is false
Here is the output on my side.
Another solution is define svctag under parameters:
parameters:
svctag: ''
Then use parameters with step:
steps:
- ${{ if eq(parameters.svctag, '') }}:
- script: echo it is true
- ${{ if ne(parameters.svctag, '') }}:
- script: echo it is false
Note: Please use parameters.svctag.
So, you should change your script as
- ${{ if eq(variables['svctag'], '') }}:
- script: echo it is true
- ${{ if ne(variables['svctag'], '') }}:
- script: echo it is false
My problem is with ansible and parsing stdout. I need to capture the stdout from an ansible play and parse this output for a specific substring within stdout and save into a var. My specific use case is below
- shell: "vault.sh --keystore EAP_HOME/vault/vault.keystore |
--keystore-password vault22 --alias vault --vault-block |
vb --attribute password --sec-attr 0penS3sam3 --enc-dir |
EAP_HOME/vault/ --iteration 120 --salt 1234abcd"
register: results
become: true
This generates an output with the following line, the goal is to capture the masked key that jboss vault generates and save that in an ansible var so I can use it to configure the standalone.xml template:
vault-option name="KEYSTORE_PASSWORD" value="MASK-5dOaAVafCSd"/>
I need a way parse this string with possibly regex and save the "MASK-5dOaAVafCSd" substring into an ansible var using set_facts module or any other ansible module.
Currently my code looks like this
#example stdout
results: vault-option name=\"KEYSTORE_PASSWORD\" value=\"MASK-5dOaAVafCSd\"/>
- name: JBOSS_VAULT:define keystore password masked value variable
set_fact:
masked_value: |
"{{ results.stdout |
regex_replace('^.+(MASK-.+?)\\.+','\\\1') }}"
This code is defining masked_value as the results.stdout, not the expected capture group.
You are very close. I advice you to use regex101.com to test regular expressions.
Here is my solution:
---
- hosts: localhost
gather_facts: no
tasks:
- shell: echo 'vault-option name="KEYSTORE_PASSWORD" value="MASK-5dOaAVafCSd"'
register: results
- set_fact:
myvalue: "{{ results.stdout | regex_search(regexp,'\\1') }}"
vars:
regexp: 'value=\"([^"]+)'
- debug:
var: myvalue
result:
ok: [localhost] => {
"myvalue": [
"MASK-5dOaAVafCSd"
]
}
Update:
regex_search returns a list of found matches, so to get only first one use:
{{ results.stdout | regex_search(regexp,'\\1') | first }}
The above solution worked for me, however I had to do some extra logic to filter shell command output to get to the line which contains following
<vault-option name="KEYSTORE_PASSWORD" value="MASK-6qcNdkIprlA"/>
because vault command output has many lines in it. Once this line is captured, the solution given by Konstantin works just fine. Below is the whole thing that needs to done in one place.
- name: Creating jboss vault
shell: |
{{ baseDir }}/bin/vault.sh -e {{ vaultDir }} -k {{ keystoreURL }} -p {{ keystorePassword }} \
-s {{ keystoreSalt }} -i {{ iterationCount }} -v {{ keystoreAlias }} -b {{ vaultBlock }} \
-a {{ attributeName }} -x {{ attributeValue }}
register: vaultResult
- set_fact:
jbossKeystorePassword: "{{ item | regex_search('value=\"([^\"]+)','\\1') | first }}"
when: item | trim | match('.*KEYSTORE_PASSWORD.*')
with_items:
- "{{ vaultResult.stdout_lines }}"
- debug:
var: jbossKeystorePassword
Be sure to replace all variables with your values in above vault.sh command.