Shell
kind: shell
source | condition | target |
---|---|---|
✔ | ✔ | ✔ |
Description
source
The Shell "source" retrieves the source value from the standard output of a shell command.
condition
The Shell "condition" validates the condition by checking the exit code of a shell command with a source as argument.
target
The Shell "targets" delegates the update of your file(s) to a shell command with a source as argument.
Parameters
The following parameters can be specified through the spec
attributes map:
Name | Type | Description | Required |
---|---|---|---|
changedif | ChangedIf defines how to interpreted shell command success criteria. What a success means, what an error means, and what a warning would mean | ||
command | string | command specifies the shell command to execute by Updatecli | |
environments | array | environments allows to pass environment variable(s) to the shell script. By default no environment variable are shared. | |
name | string | Name defines the environment variable name | |
value | string | Value defines the environment variable value | |
shell | string | Shell specifies which shell interpreter to use. Default to powershell(Windows) and “/bin/sh” (Darwin/Linux) | |
workdir | string | workdir specifies the working directory path from where to execute the command. It defaults to the current context path (scm or current shell). Updatecli join the current path and the one specified in parameter if the parameter one contains a relative path. |
Environments
Name | Required | Default | Description |
---|---|---|---|
name | ✔ | Environment variable name | |
value | Environments variable value. If the value is empty, then we inherit the value from the updatecli process. |
By default the command doesn’t inherit any environment variables from the updatecli process. The motivation is to avoid environment variable leak into the command.
To specify an environment variable, you can use one of the following examples:
scenario1:
name: PATH value is inherited from Updatecli process
kind: shell
spec:
command: ./examples/scripts.d/env.sh
environments:
- name: PATH
scenario2:
name: MY_ENV value is set by the Updatecli manifest
kind: shell
spec:
command: ./examples/scripts.d/env.sh
environments:
- name: MY_ENV
value: setmyvalue
Please note the environment variable "DRY_RUN" is always defined by Updatecli to either true or false depending if we run updatecli diff
or updatecli apply
.
Shell Source
The command provided by your spec
section is executed by updatecli
to retrieve the source:
If the commands runs successfully (e.g. with an exit code of zero), the source takes the value of the inlined (e.g. removing the line returns) standard output.
An error is raised if the exit code of the command is different than zero. The error prints the content from both standard error (stderr) and output (stdout) of the command.
Source Examples
The following example should result in a source value of
1.2.3
:updateCli.yaml:sources: example: kind: shell spec: command: echo 1.2.3
$ updatecli apply # ... SOURCE: ======= ✔ The shell 🐚 command "echo 1.2.3" ran successfully and retrieved the following source value: "1.2.3" # ...
The following example should result in a failing source:
updateCli.yaml:sources: example: kind: shell spec: command: ls /foobar
$ updatecli apply # ... SOURCE: ======= ERROR: ✗ The shell 🐚 command "ls /foobar" failed with an exit code of 1 and the following messages: stderr= ls: /foobar: No such file or directory stdout=
Shell Condition
The command provided by your spec
section is executed by updatecli
to validate the condition:
If the commands runs successfully (e.g. with an exit code of zero), then the condition is validated.
Otherwise (an exit code different than zero) the condition is marked as not valid, and both the standard error and outputs are logged.
💡 The source associated to this condition (the default source or through the key sourceID
) is appended as the last argument to the command line unless the attribute disablesourceinput
is set to true
.
Condition Examples
The following examples show how to test if the value from the source named newVersion
equals to 1.2.3
:
conditions:
default:
kind: shell
sourceID: newVersion
spec:
# The value of the source "newVersion" is appended by updatecli
command: test 1.2.3 ==
If the value of the source is
1.2.3
, then you get:CONDITIONS: =========== ✔ The shell 🐚 command "test 1.2.3 == 1.2.3" successfully validated the condition.
If the value of the source is
2.0.0
, than you get:CONDITIONS: =========== The shell 🐚 command "test 1.2.3 == 2.0.0" failed with an exit code of 1 and the following messages: stderr= stdout= ✗ condition not met, skipping pipeline
In this example the command is executed without the source appended:
conditions:
checkIfMavenReleaseIsAvailable:
kind: shell
disablesourceinput: true
spec:
command: curl https://google.com
$ updatecli apply
# ...
CONDITIONS:
===========
✔ The shell 🐚 command "curl https://google.com" successfully validated the condition.
# ...
Run Summary
===========
1 job run
0 job succeed
0 job failed
1 job applied changes
Shell Target
The command provided by your spec
section is executed by updatecli
to change your files:
When the commands runs successfully (e.g. with an exit code of zero), the behavior depends on the content of the standard output:
If it is empty, then
updatecli
reports a success with no changes applied.Otherwise
updatecli
reports a success with the content of the standard output as the resulting value of the change.
Otherwise (an exit code different than zero) the condition is marked as not valid, and both the standard error and outputs are logged.
Please note that:
💡 The source associated to this target (the default source or through the key
sourceID
) is appended as the last argument to the command line.💡 The
DRY_RUN
environment variable is set to the valuetrue
when usingupdatecli diff
to report that any change should only be reported and not applied.
Target Examples
Consider the following shell script target.sh
:
#!/bin/bash
# Script "target.sh"
# The script check the content of the file "version.txt"
# - if different than $1 and DRY_RUN is set to:
# - "false" then it updates it with the value of $1
# - "true" then it only reports the value of $1
# - otherwise it exits without any value reported
version_file=version.txt
if test "$1" == "$(cat "${version_file}")"
then
## No change
# early return with no output
exit 0
else
if test "$DRY_RUN" == "false"
then
## Value changed to $1" - NO dry run
# do something such as writing a file here
echo "$1" > "${version_file}"
fi
# Report on stdout
echo "$1"
exit 0
fi
With the following manifest:
sources:
default:
kind: shell
spec:
command: echo 1.2.4
targets:
default:
name: setGrepVersion
sourceID: default
kind: shell
spec:
command: bash ./examples/updateCli.generic/shell/target.sh
You would have the following behaviors:
Running with dry run enabled:
$ cat version.txt 1.0.0 $ updatecli diff #... TARGETS: ======== **Dry Run enabled** ⚠ The shell 🐚 command "bash ./examples/updateCli.generic/shell/target.sh 1.2.4" ran successfully and reported the following change: "1.2.4". $ cat version.txt 1.0.0 # No change
Applying the changes:
$ updatecli apply #... TARGETS: ======== ⚠ The shell 🐚 command "bash ./examples/updateCli.generic/shell/target.sh 1.2.4" ran successfully and reported the following change: "1.2.4". $ cat version.txt 1.2.4 # Version changed
Reference
sources:
newVersion:
kind: shell
name: Get new version
spec:
command: bash ./get-new-version.sh"
failing:
kind: shell
name: Failing command
spec:
command: ls /foobar
conditions:
checkIfVersionEquals123:
kind: shell
sourceId: newVersion
spec:
command: test 1.2.3 ==
targets:
default:
name: setGrepVersion
sourceID: default
kind: shell
spec:
command: bash apply.sh
FAQ
Why can’t I execute an updatecli manifest with a local script using the shell provider?
Updatecli behaves differently if it uses a SCM configuration or not. If no SCM configuration is provided, then it sets the working directory to where updatecli is executed.
But if a SCM configuration is provided, then it clones the git repository in a temporary directory such as /tmp/updatecli
and then set the working directory to that temporary such as /tmp/updatecli/<git repository>
.
While it allows updatecli to work from a "clean" directory, it makes the testing of the local updatecli manifest a bit more complicated. We are investigating the best solution to address this but for now the best way to test is to comment out scmid
such as
targets:
jsonschema:
name: "Update updatecli jsonschema"
kind: "shell"
#scmid: "default"
spec:
command: "./updatecli/scripts/jsonschema.sh"
Issues: issues#660,issues#465