{"__v":98,"_id":"573f942a784fa20e00973faf","category":{"__v":14,"_id":"55c6bec2b9aa4e0d0016c2c7","pages":["55c6bec3b9aa4e0d0016c2c9","55c8f451b79cb30d005b3e49","55ccea804906d12f001226e4","56c14ca9f203270d00d6c546","56c3bbeb2d97560d00e23ccf","56cce248ca43550b002814db","56cceaacd98d851d00c0c376","56cceefc723ad71d00cae46d","56ccef4e8fa8b01b00b8200e","56cd03e8723ad71d00cae4af","56cd03f2723ad71d00cae4b1","56cd061eca43550b0028151c","56cd07e4d98d851d00c0c3ba","56df35fbef8c1b320047c2d5"],"project":"55c6bec1b9aa4e0d0016c2c3","version":"55c6bec1b9aa4e0d0016c2c6","sync":{"url":"","isSync":false},"reference":false,"createdAt":"2015-08-09T02:45:22.223Z","from_sync":false,"order":0,"slug":"documentation","title":"Guides"},"parentDoc":null,"project":"55c6bec1b9aa4e0d0016c2c3","user":"55c8f42fb79cb30d005b3e48","version":{"__v":8,"_id":"55c6bec1b9aa4e0d0016c2c6","project":"55c6bec1b9aa4e0d0016c2c3","createdAt":"2015-08-09T02:45:21.683Z","releaseDate":"2015-08-09T02:45:21.683Z","categories":["55c6bec2b9aa4e0d0016c2c7","56c14bc5826df10d00e82230","56cceed8723ad71d00cae46c","56ccf29a431ada1f00e85aae","56ccf3c28fa8b01b00b82018","56ce1e6ee538330b0021ac5d","56f97e9a4c612020008f2eaf","5734fafd146eb82000597261"],"is_deprecated":false,"is_hidden":false,"is_beta":false,"is_stable":true,"codename":"","version_clean":"1.0.0","version":"1.0"},"updates":["5743710b6b0c5c0e00099b4e","57c4c2396a36a80e002b6698","582e3b781a6d730f0056fd8e"],"next":{"pages":[],"description":""},"createdAt":"2016-05-20T22:48:10.267Z","link_external":false,"link_url":"","githubsync":"","sync_unique":"","hidden":false,"api":{"results":{"codes":[]},"settings":"","auth":"required","params":[],"url":""},"isReference":false,"order":5,"body":"[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"What are Pipeline Expressions?\"\n}\n[/block]\nA pipeline expression in Spinnaker looks like this:\n\n`${ execution.stages[0].name }`\n\nPipeline expressions allow you to put a placeholder value that gets filled in when you run your pipeline. \n\nFor example, let's say I have a field called `command` that I want to be able to change every time I manually execute a pipeline. When I configure the pipeline, instead of a normal string, I can enter the expression `${ parameters.command }`,\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/1QoArUm7TKafB3p1zq8O_Screen%20Shot%202016-05-20%20at%203.54.32%20PM.png\",\n        \"Screen Shot 2016-05-20 at 3.54.32 PM.png\",\n        \"500\",\n        \"44\",\n        \"#434343\",\n        \"\"\n      ]\n    }\n  ]\n}\n[/block]\nI can now set up my pipeline to take a `command` parameter, when I manually execute my pipeline, it will ask me to enter the value for `command`. \n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/wzntuo4zQgmB8YNvKUgN_Screen%20Shot%202016-05-20%20at%204.00.00%20PM.png\",\n        \"Screen Shot 2016-05-20 at 4.00.00 PM.png\",\n        \"600\",\n        \"266\",\n        \"#3b6972\",\n        \"\"\n      ],\n      \"sizing\": \"original\",\n      \"border\": true\n    }\n  ]\n}\n[/block]\nWhen the pipeline runs, it will substitute the value I have entered for `command` with the value `sleep 40000` that I have entered. \n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Where can I use Pipeline Expressions in Spinnaker?\"\n}\n[/block]\n\nYou can usually type in a value in the text fields of the Pipeline stages in Spinnaker. \n\nIn the following example, we're using pipeline expressions as parameters being passed into a Jenkins stage:\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/7214674-selectedStageContextList.png\",\n        \"selectedStageContextList.png\",\n        757,\n        456,\n        \"#496c92\"\n      ],\n      \"border\": true\n    }\n  ]\n}\n[/block]\n\n[block:callout]\n{\n  \"type\": \"warning\",\n  \"title\": \"Expressions and Pipeline Configuration\",\n  \"body\": \"Since expressions are only evaluated before stages start, Spinnaker does not support using pipeline expressions in the configuration screen of a pipeline. For example, putting an expression in the job name of a trigger won't actually work.\"\n}\n[/block]\n\nThere are often cases where the value you want to replace doesn't allow typing, such as specifying a list of security groups or wanting to dynamically control the behavior of a checkbox. For these cases, you should edit the pipeline JSON directly.\n\nYou can edit the pipeline JSON by selecting Pipeline Actions -> Edit as Json\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/HUt7vhvBRXWMX6H5fOwm_clouddriver_·_pipeline_config.png\",\n        \"clouddriver_·_pipeline_config.png\",\n        \"220\",\n        \"156\",\n        \"#f93370\",\n        \"\"\n      ],\n      \"sizing\": \"50\",\n      \"border\": false\n    }\n  ]\n}\n[/block]\nIn the popup screen, you can now edit the fields that match the fields you want to substitute. \n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/QF1iBxppSSuJ3684Sqqm_edit.png\",\n        \"edit.png\",\n        \"1212\",\n        \"1204\",\n        \"#45595e\",\n        \"\"\n      ],\n      \"sizing\": \"smart\",\n      \"border\": true\n    }\n  ]\n}\n[/block]\n\n[block:callout]\n{\n  \"type\": \"danger\",\n  \"title\": \"Warning\",\n  \"body\": \"Sometimes adding an expression will stop your ability to use the UI. For example, if you use a parameter for the account field in a cluster deployment Stage, you will see a spinning loader from the UI when you try to edit this cluster.\"\n}\n[/block]\n##Turning a stage on or off##\n\nYou can use expressions to turn an individual stage on or off. \n\nTo do so, select the 'Conditional on Expression' checkbox. \n\nEnter an expression:\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/XjIlLZCQjyZreblIMkpO_Screen%20Shot%202016-05-26%20at%202.53.51%20PM.png\",\n        \"Screen Shot 2016-05-26 at 2.53.51 PM.png\",\n        \"602\",\n        \"43\",\n        \"#456f8d\",\n        \"\"\n      ]\n    }\n  ]\n}\n[/block]\nWhen this pipeline runs, it will evaluate the expression to decide if the stage can be skipped. This is useful for adding optional stages to your pipeline. \n\n##Preconditions Stage##\n\nTo use expressions to gate multiple stages, you can use the the 'check Preconditions' stage. When this stage is configured, it will gate the execution of subsequent stages. In other words, the stages that follow this stage will only run if the precondition evaluates to true.\n\nAdd a new stage and set it to be of type *Check Preconditions*.\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/Tv63pvfT3GnWZ19yVcQj_precondition_check.png\",\n        \"precondition_check.png\",\n        \"650\",\n        \"227\",\n        \"#95abca\",\n        \"\"\n      ]\n    }\n  ]\n}\n[/block]\nYou can add one or more preconditions by clicking on *Add Precondition*. \n\nYou can add expressions to be checked here by selecting *Expression* from the Check dropdown and entering an expression. \n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/E30ovIyzRl6z9LGNtaZx_precondition.png\",\n        \"precondition.png\",\n        \"600\",\n        \"250\",\n        \"#3993a7\",\n        \"\"\n      ]\n    }\n  ]\n}\n[/block]\nWhen the pipeline runs, if this expression evaluates to true, the pipeline will continue as is. If not, the stages following this stage will not run. \n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/T2mTN7zcRL6MbEjCwuLP_precond%20pipe.png\",\n        \"precond pipe.png\",\n        \"600\",\n        \"207\",\n        \"#61676c\",\n        \"\"\n      ]\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"What kind of data can I put in Pipeline Expressions?\"\n}\n[/block]\nSo where do we actually get the values that get evaluated in by pipeline expressions? In this section, we will describe the numerous sources of data for a pipeline in Spinnaker and how to access them. \n\n##Pipeline Execution##\n\nThe current running pipeline is available within Pipeline Expressions as `execution`. The easiest way to view this JSON is as follows,\n\n* Go to an execution of your pipeline.\n* Click on `Details` to expand the pipeline.\n* Click on the `source` link under the pipeline execution:\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/DoOxa42vRbere15q52i8_source.png\",\n        \"source.png\",\n        \"700\",\n        \"269\",\n        \"#71924b\",\n        \"\"\n      ]\n    }\n  ]\n}\n[/block]\nThis will take you to a JSON file that contains the details of your pipeline execution. \n\nFrom there, you can navigate to different parts of the pipeline. For example, to reference the name of the first stage you can use `${ execution.stages[0]['name'] }`.\n\n##The current stage##\n\nValues for the current stage context are available by their variable name. In the execution JSON, they will be defined under the context object.\n\nFor example, if I look at the JSON for a bake stage execution, I will see something like this:\n\n```\n{\n\t\"id\": \"e980c921-b1f3-4b04-adda-b5c50ea1797a\",\n\t\"type\": \"bake\",\n\t\"name\": \"Bake\",\n\t\"startTime\": 1464024188808,\n\t\"endTime\": null,\n\t\"status\": \"RUNNING\",\n\t\"context\": {\n\t\t\"cloudProviderType\": \"aws\",\n\t\t\"regions\": [\"us-west-1\"],\n\t\t\"user\": \"clin:::at:::netflix.com\",\n\t\t\"vmType\": \"hvm\",\n\t\t\"storeType\": \"docker\",\n\t\t\"baseOs\": \"trusty\",\n\t\t\"baseLabel\": \"release\",\n\t\t\"package\": \"mypackage\",\n\t\t\"amiSuffix\": \"20160523172307\" ... \n```\n\nThis means that if I reference a field in my expression like `${ package }`, it will resolve to the package for that stage.\n\n##Other stages##\n\nYou can also access the value of other stages by doing a lookup by name using the [#stage( stage name )](#stagestring) helper method. To access stage attributes, you can call `${ #stage('stage name')['id']}`. To access the values passed into the stage, use `${ #stage('stage name')['context']['baseAmiName']}`.\n\n##Pipeline Parameters##\n\nThe configuration screen of your pipeline lets you specify parameters. Parameters to the pipeline can also come from upstream pipelines that have configured a Pipeline stage.\n\nYou can access values of parameters within expressions by referencing the `parameters` array. This is a shortcut for `execution.parameters`. For example, `${ parameters['run canary'] }` will evaluate to the value of the parameter called *run canary*. \n\n##Trigger Values##\n\nYou can reference values in the pipeline trigger via the `trigger` property. This value is available in the execution JSON under the trigger object. \n\nThe `trigger.buildInfo` field in jenkins triggers will contain details about the jenkins execution. To access the version hash of the git commit in Jenkins, for example, we can ask for `${ trigger.buildInfo.scm[0]['sha1'] }`.\n\n##Property files##\n\nA feature of the Jenkins trigger is the ability to specify a properties file. Spinnaker will read the contents of this artifact ( it can be a Java .properties file, yml or json ) and add it into the pipeline context. \n\nTo specify a property file, make sure you're archiving it in your jenkins job, then provide the name of the file, i.e `mypropertyfile.properties` ( not the absolute path i.e, `workspace/build/mypropertyfile.properties` ).\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/714c76c-helperParamContextList.png\",\n        \"helperParamContextList.png\",\n        867,\n        460,\n        \"#416b96\"\n      ]\n    }\n  ]\n}\n[/block]\nThe contents of this file will now be available as a map under the trigger and accessible via `trigger.properties`. \n\nFor example, if my property file looked like this:\n\n```\nBUILD_STACK=bojack\nBUILD_ANIMAL=horseman\n```\n\nI can then access the value from the property file as `${ trigger.properties['BUILD_ANIMAL']}` to get `horseman`.\n\nIf you're adding property files from a Jenkins or Script *STAGE* ( not Trigger ), then you can omit the `trigger.properties` field as the stage. Any stage that runs after will be able to access these parameters as normal context fields. If we created a new stage and ran the same Jenkins job as above, then `${ BUILD_ANIMAL }` will resolve to `horseman`.\n[block:callout]\n{\n  \"type\": \"warning\",\n  \"title\": \"Using the same field names\",\n  \"body\": \"If you have multiple Jenkins jobs, they can clobber the same properties. A way around this is to reference the particular stage. `${ #stage( 'first jenkins job' )['context']['BUILD_ANIMAL'] }`\"\n}\n[/block]\n##Manual Judgement Choices##\n\nThe manual judgment stage allows you to specify options when you approve a stage. Under Judgement Inputs, you can enter a choice.\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/yH9aAHjKSaagOkZ0FlIg_options.png\",\n        \"options.png\",\n        \"600\",\n        \"187\",\n        \"#5bb6c6\",\n        \"\"\n      ]\n    }\n  ]\n}\n[/block]\nWhen your stage executes, you will see a dropdown with the provided choice. \n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/8q9kbsbNRWOu59vfbNV3_input%20choice.png\",\n        \"input choice.png\",\n        \"350\",\n        \"286\",\n        \"#416eba\",\n        \"\"\n      ]\n    }\n  ]\n}\n[/block]\nIn subsequent stages, you can reference the choice provided via the [#judgment( stage Name ) ](#judgmentstring) helper method `${ #judgment( 'manual judgment stage name' )}`. \n\n##External sources##\n\nYou can also read from external sources via the [#fromUrl( url )](#fromurlstring) and [#jsonFromUrl( url )](#jsonfromurlstring) helper methods. \n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Pipeline Expression Language Reference\"\n}\n[/block]\nThe Pipeline Expression syntax is implemented with the Spring Expression Language ( SpEL ). You can learn more about SPeL by following this [link](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/expressions.html).\n\n##Writing Expressions##\n\nA pipeline expression is started by `${` and terminated by `}` : \n\n`${ expression here }`\n\nYou can interpolate expressions and strings, so\n\n`${expressionA}-randomString-${expressionB}` \n\nwill evaluate to `Kimmy-randomString-Schmidt` when expressionA is `Kimmy` and expressionB is `Schmidt`.\n\nIn Spinnaker, if an expression cannot be evaluated, it will return the expression entered. \n\n##Strings##\n\nYou can enter String in expressions: `${ 'this is a String' }` will evaluate to `this is a String`.\n\n##Lists##\n\nYou can reference entries in lists: `${ stages[0] }` will return the value of the first stage.\n\n##Maps##\n\nAnd you can reference values in maps based on their keys: `${ trigger['properties']['value1']}`\n[block:callout]\n{\n  \"type\": \"info\",\n  \"title\": \"Using a dot (.) vs square brackets [ 'value' ]\",\n  \"body\": \"Spinnaker supports both a dot notation for accessing values and a square bracket notation. However, there are a few places where the dot notation doesn't work as expected --- for example after a filter operation or getting nested JSON values from an URL. Generally, it's recommended to use the square bracket notation for referencing map values as this is most predictable. I.e, prefer `trigger['properties']['value']` instead of `trigger.properties.value`.\"\n}\n[/block]\n##Math##\n\nArithmetic operations such as `${ trigger.buildInfo.number * 2 }` are supported.\n\n##Comparisons##\n\nThe expression language also allows you to specify rational operators, such as `${ instance.size > 400 }` or `${ params.runCanary == true }`.\n\n##Functions##\n\nThere are a few [helper functions](#helper-functions-in-spinnaker) available within Spinnaker. These can be accessed via `#functionName( params )`. For example, `#fromUrl( 'http://www.netflix.com' )`.\n\n##Code##\n\nYou can execute java code within the expression language. This can be useful for string manipulation or to create more exotic data fields.\n\nYou can use methods available to existing types like String - `${ 'this is a long string'.substring(0,5)}`\n\nYou can also declare new classes. Note that package names need to be fully qualified. In the following expression, we're getting the current date as mm-dd-yyyy format: `${ new java.text.SimpleDateFormat('mm-dd-yyyy').format(new java.util.Date()) }` \n\n##Some Useful Things to Know##\n\n###Default Values###\n\nYou can set a default value within expressions by using `?:`. For example, `${ parameters.region ?: 'us-east-1'}`.\n\n###Filtering Maps###\n\nThe expression language allows you to filter maps by using the `.?` expression. For example, to filter a list of stages by type, you can use the expression `${ execution.stages.?[ type == 'bake' ] }`\n\n###Lists as Parameters###\n\nSometimes you want to enter a list of values as a parameter. For example, a list of regions or security groups. A useful tip here is to ask the user to enter them as a list of comma separated values `us-east-1,us-west-1,eu-west-1` and then use the `split()` method to make these into a map. Your expression would look like this `parameters.regions.split(',')`.\n\n### #root ###\n\nSometimes you want to reference another variable in an expression. You can do this by prepending `#root` in front of the expression name. In the following expression, I can set a value depending on the baseLabel field: `${ #root.baseLabel ?: 'noBaseLabelValue' }`\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Helper properties in Spinnaker\"\n}\n[/block]\nThere are a few attribute shortcuts that you can use in Spinnaker:\n\n* `execution` : refers to the current pipeline execution.\n* `parameters` : pipeline parameters\n* `trigger` : pipeline trigger\n* `scmInfo` : this is a shortcut to the git details of either the trigger or the last executed jenkins stage. `scmInfo.sha1` will give you the hash of the last build. `scmInfo.branch` will give you the branch name.\n* `deployedServerGroups` : this is a reference to the server group that was created by the last deploy stage. Here is an example of the contents of a deployedServerGroups : ```[{account=prod,capacity={desired=1, max=1, min=1}, parentStage=23452655-c6de-4aac-b529-55e1357dfee7, region=us-west-1, ami=ami-575eb013, amiSuffix=201505190020, baseLabel=release, baseOs=trusty, package=rush, storeType=ebs, vmType=pv, serverGroup=rush-prestaging-v049}]```\n\n\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Helper functions in Spinnaker\"\n}\n[/block]\nThe following section outlines the currently available helper functions in Spinnaker. \n[block:api-header]\n{\n  \"type\": \"fn\",\n  \"title\": \"#alphanumerical( String )\"\n}\n[/block]\nReturns the String value of a string passed in with non A-Z or digits stripped out. This is useful if you want to have a valid stack or details field in Spinnaker, as some provides don't allow special characters in them.\n[block:api-header]\n{\n  \"type\": \"fn\",\n  \"title\": \"#readJson(String)\"\n}\n[/block]\nConverts a JSON String into a Map that can then be processed further. This is useful if a jenkins property file has a complex value that you want to pass into Spinnaker. This is also used by the #jsonFromUrl( ) function under the hood. \n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"\\\"instanceType\\\": \\\"${#readJson('{\\\\\\\"prod\\\\\\\": \\\\\\\"r3.8xlarge\\\\\\\"}')[#root.parameters['environment']]}\\\",\",\n      \"language\": \"text\"\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"fn\",\n  \"title\": \"#fromUrl(String)\"\n}\n[/block]\nReturns the contents of the specified URL as a String.\n[block:api-header]\n{\n  \"type\": \"fn\",\n  \"title\": \"#jsonFromUrl(String)\"\n}\n[/block]\nRetrieves the contents of the given URL and converts it into either a map or a list. This is useful to fetch information from the Spinnaker API or other sources.\n[block:api-header]\n{\n  \"type\": \"fn\",\n  \"title\": \"#judgment(String)\"\n}\n[/block]\nGets the selected judgment value from the stage with the name asked for. I.,e `${#judgment('my manual judgment stage')}` will return the selected judgmentInput from the stage called `my manual judgment`.\n[block:api-header]\n{\n  \"title\": \"#propertiesFromUrl(String)\"\n}\n[/block]\nRetrieves the contents of the properties file at the given URL and converts it into a map. This is useful to fetch information from jenkins properties files or other similar endpoints.\n[block:api-header]\n{\n  \"type\": \"fn\",\n  \"title\": \"#stage(String)\"\n}\n[/block]\nA shortcut to get the stage by name. I.e, `${#stage( 'bake' )}`. Be careful that the values for the stage are still under the context, so accessing a property would be via `${#stage('bake')['context']['valuePassedIn']}`.\n[block:api-header]\n{\n  \"type\": \"fn\",\n  \"title\": \"#toBoolean(String)\"\n}\n[/block]\nConverts a value to a boolean.\n\n[block:api-header]\n{\n  \"type\": \"fn\",\n  \"title\": \"#toFloat(String)\"\n}\n[/block]\nConverts a value to a floating point number.\n[block:api-header]\n{\n  \"type\": \"fn\",\n  \"title\": \"#toInt( String )\"\n}\n[/block]\nConverts a value to an integer.\n\n[block:api-header]\n{\n  \"type\": \"fn\",\n  \"title\": \"#toJson(Object)\"\n}\n[/block]\nConverts a Map into a JSON String. This is useful when you want to pass values from Spinnaker to another system. For example, I can use `${#toJson( deployedServerGroups )}` to pass the details of the recently deployed server groups to a jenkins job.\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Sample Use Cases\"\n}\n[/block]\n## Create a stack based on the committed git branch ##\n\nIn this use case, we're going to create a different cluster for each branch that gets triggered in Jenkins.\n\n1. Set up a jenkins trigger for the pipeline.\n\n2. Add a deploy stage and use an expression for my cluster name that uses the scmInfo value in the branch. `${ #alphanumerical( scmInfo.branch ) }`:\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/bLvuE8RlOWvPk9cvsQwl_Screen%20Shot%202016-05-23%20at%2011.28.24%20AM.png\",\n        \"Screen Shot 2016-05-23 at 11.28.24 AM.png\",\n        \"1104\",\n        \"426\",\n        \"#3d546b\",\n        \"\"\n      ]\n    }\n  ]\n}\n[/block]\nThe deploy stage should look like this:\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/ZaQSqDORDCfHU1hSZGSn_Screen%20Shot%202016-05-23%20at%2011.28.11%20AM.png\",\n        \"Screen Shot 2016-05-23 at 11.28.11 AM.png\",\n        \"2034\",\n        \"236\",\n        \"#404a4c\",\n        \"\"\n      ]\n    }\n  ]\n}\n[/block]\nWhen the pipeline runs, it will replace the expression with the name of the branch, creating a new cluster:\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/ND6LhA0LRmGHt4B4MjDI_Screen%20Shot%202016-05-23%20at%2011.27.58%20AM.png\",\n        \"Screen Shot 2016-05-23 at 11.27.58 AM.png\",\n        \"558\",\n        \"262\",\n        \"#386f7d\",\n        \"\"\n      ]\n    }\n  ]\n}\n[/block]\n## Conditionally execute pipeline behavior based on manual input ##\n\nFor this use case, we're going to set up a pipeline with 3 conditions, and gate these conditions with a manual judgment stage.\n\n1. First, add a manual judgment stage and add three options.\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/YoMC5Jr7TTK9x0bfSag3_inputs.png\",\n        \"inputs.png\",\n        \"600\",\n        \"185\",\n        \"#51666a\",\n        \"\"\n      ]\n    }\n  ]\n}\n[/block]\n2. Now that I have these inputs set up, I create a new precondition stage. I add an expression to check that the input was 'clean up'\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/SH2bUiVWQfuv7VPUlkLS_edit%20precondition.png\",\n        \"edit precondition.png\",\n        \"600\",\n        \"244\",\n        \"#3898ad\",\n        \"\"\n      ]\n    }\n  ]\n}\n[/block]\nMy precondition stage should look like this.\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/17PhCH1RTW1MkW9BWQzx_stage.png\",\n        \"stage.png\",\n        \"800\",\n        \"342\",\n        \"#51b0c3\",\n        \"\"\n      ]\n    }\n  ]\n}\n[/block]\n\n[block:callout]\n{\n  \"type\": \"info\",\n  \"title\": \"Fail pipeline\",\n  \"body\": \"For these type of workflows, you want to set *Fail Pipeline* as false when you're setting up your expression.\"\n}\n[/block]\n3. Add stages that you want to execute based on this precondition. \n\n4.  I do the same for the 'deploy another' input.\n\n5. My pipeline now looks like this:\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/14051de-selectedStageContextList.png\",\n        \"selectedStageContextList.png\",\n        757,\n        456,\n        \"#496c92\"\n      ]\n    }\n  ]\n}\n[/block]\n6. Go to the executions screen and run my pipeline. I should see the options show up in the Manual Judgment stage:\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/ZrkkNylpSDCIAKsMgVJ9_selection.png\",\n        \"selection.png\",\n        \"800\",\n        \"391\",\n        \"#466a9d\",\n        \"\"\n      ]\n    }\n  ]\n}\n[/block]\nIf I select 'do nothing', which matches no preconditions, my pipeline should just stop:\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/dWiqWfsaQsatXQhXf5vl_donothing.png\",\n        \"donothing.png\",\n        \"800\",\n        \"163\",\n        \"#c24040\",\n        \"\"\n      ]\n    }\n  ]\n}\n[/block]\nIf I choose 'deploy another', I can see that the stages gated by deploy another are executed. \n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/sLjlgETKSzWMyEDCTpPB_deploy%20another.png\",\n        \"deploy another.png\",\n        \"800\",\n        \"140\",\n        \"#52b4c4\",\n        \"\"\n      ]\n    }\n  ]\n}\n[/block]\nSimilarly, you can see that when I chose 'cleaning up', that pipeline branch is the one that runs. \n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/VfDBgfUeSBqb1ugIBL6O_runclean.png\",\n        \"runclean.png\",\n        \"800\",\n        \"132\",\n        \"#59755b\",\n        \"\"\n      ]\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Expression Autocomplete\"\n}\n[/block]\nSpinnaker has autocompleted functionality within the context of a pipeline configuration.\n\n**TLDR;**\nHere are the character triggers that will invoke the autocomplete\n**$** = Adds the **${ }** to the text field and starts the expression building\n**#** = Displays a list of all the **helper functions**\n**?** = Displays a list of **helper parameters** and **stages** for the pipeline\n\nIn any text field, you can start autocompleting by typing a **dollar sign($)**. \nDoing so will display this:\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/5b1be30-start.png\",\n        \"start.png\",\n        560,\n        114,\n        \"#3e84b7\"\n      ]\n    }\n  ]\n}\n[/block]\nHit enter and the opening and closing braces of the expression will be added to the text field.\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/8681fbb-textfieldwithexpression.png\",\n        \"textfieldwithexpression.png\",\n        560,\n        115,\n        \"#eaf4fa\"\n      ]\n    }\n  ]\n}\n[/block]\n### Helper Functions and Stages\n\nWithin the **curly braces ${ }**,  adding a **question mark (?)** will display a list of all the helper properties that are relevant to the stage config that you are in as well as a list of all the stages in the pipeline.\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/36cab01-helperParamsAndStages.png\",\n        \"helperParamsAndStages.png\",\n        560,\n        330,\n        \"#3f6a92\"\n      ]\n    }\n  ]\n}\n[/block]\nOnce the list is displayed you can start typing to narrow down the list and hitting enter will add the helper property or stage name to the expression.\n\nIf a helper property is added to the expression you can then hit any of the meta-keys (Shift, Comand, Alt, Control) to pop up a list of all the pipeline config context relevant to that selected helper property.\n\nHere is an example of what context of the 'deployedServerGroups' helper property will show.\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/5d586b8-helperParamContextList.png\",\n        \"helperParamContextList.png\",\n        867,\n        460,\n        \"#416b96\"\n      ]\n    }\n  ]\n}\n[/block]\nThe list will show the available context attributes on the left and the previous values highlighted on the right. The list can also be narrowed by typing a few characters, and selecting on by hitting **ENTER**.\n\n\n### Helper Functions\n\nAlso within the **curly braces (${ })**,  adding a **pound sign (#)** will display a list of all the helper functions that are available.\n\nHere is an example of selecting the '#stage' helper function. \n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/e0344b1-helperFunctions.png\",\n        \"helperFunctions.png\",\n        560,\n        302,\n        \"#396993\"\n      ]\n    }\n  ]\n}\n[/block]\nSelecting the function will add it to the expression and place the cursor between the single quotes\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/04fb5c7-stageFunctionSelected.png\",\n        \"stageFunctionSelected.png\",\n        560,\n        115,\n        \"#5c95b7\"\n      ]\n    }\n  ]\n}\n[/block]\nFrom here we can enter a **question mark (?)** to pull up the list of stages.\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/5689a73-stageSelectionInHelperFn.png\",\n        \"stageSelectionInHelperFn.png\",\n        560,\n        335,\n        \"#416e97\"\n      ]\n    }\n  ]\n}\n[/block]\nOnce the stage name is selected it will be added to the expression.  \n\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/e4fee2f-stageSelectedInHelperFn.png\",\n        \"stageSelectedInHelperFn.png\",\n        560,\n        115,\n        \"#5e8bac\"\n      ]\n    }\n  ]\n}\n[/block]\nFrom here you can move the cursor to the end of the closing paren of the function, and a list of context values for that stage will be presented for your choosing.\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/0c5674a-selectedStageContextList.png\",\n        \"selectedStageContextList.png\",\n        757,\n        456,\n        \"#496c92\"\n      ]\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Source Code\"\n}\n[/block]\nThe expression language support can be found in the orca codebase and pretty much encapsulated in the [ContextParameterProcessor](https://github.com/spinnaker/orca/blob/master/orca-core/src/main/groovy/com/netflix/spinnaker/orca/pipeline/util/ContextParameterProcessor.groovy) class.","excerpt":"","slug":"pipeline-expressions-guide","type":"basic","title":"Pipeline Expressions Guide"}

Pipeline Expressions Guide


[block:api-header] { "type": "basic", "title": "What are Pipeline Expressions?" } [/block] A pipeline expression in Spinnaker looks like this: `${ execution.stages[0].name }` Pipeline expressions allow you to put a placeholder value that gets filled in when you run your pipeline. For example, let's say I have a field called `command` that I want to be able to change every time I manually execute a pipeline. When I configure the pipeline, instead of a normal string, I can enter the expression `${ parameters.command }`, [block:image] { "images": [ { "image": [ "https://files.readme.io/1QoArUm7TKafB3p1zq8O_Screen%20Shot%202016-05-20%20at%203.54.32%20PM.png", "Screen Shot 2016-05-20 at 3.54.32 PM.png", "500", "44", "#434343", "" ] } ] } [/block] I can now set up my pipeline to take a `command` parameter, when I manually execute my pipeline, it will ask me to enter the value for `command`. [block:image] { "images": [ { "image": [ "https://files.readme.io/wzntuo4zQgmB8YNvKUgN_Screen%20Shot%202016-05-20%20at%204.00.00%20PM.png", "Screen Shot 2016-05-20 at 4.00.00 PM.png", "600", "266", "#3b6972", "" ], "sizing": "original", "border": true } ] } [/block] When the pipeline runs, it will substitute the value I have entered for `command` with the value `sleep 40000` that I have entered. [block:api-header] { "type": "basic", "title": "Where can I use Pipeline Expressions in Spinnaker?" } [/block] You can usually type in a value in the text fields of the Pipeline stages in Spinnaker. In the following example, we're using pipeline expressions as parameters being passed into a Jenkins stage: [block:image] { "images": [ { "image": [ "https://files.readme.io/7214674-selectedStageContextList.png", "selectedStageContextList.png", 757, 456, "#496c92" ], "border": true } ] } [/block] [block:callout] { "type": "warning", "title": "Expressions and Pipeline Configuration", "body": "Since expressions are only evaluated before stages start, Spinnaker does not support using pipeline expressions in the configuration screen of a pipeline. For example, putting an expression in the job name of a trigger won't actually work." } [/block] There are often cases where the value you want to replace doesn't allow typing, such as specifying a list of security groups or wanting to dynamically control the behavior of a checkbox. For these cases, you should edit the pipeline JSON directly. You can edit the pipeline JSON by selecting Pipeline Actions -> Edit as Json [block:image] { "images": [ { "image": [ "https://files.readme.io/HUt7vhvBRXWMX6H5fOwm_clouddriver_·_pipeline_config.png", "clouddriver_·_pipeline_config.png", "220", "156", "#f93370", "" ], "sizing": "50", "border": false } ] } [/block] In the popup screen, you can now edit the fields that match the fields you want to substitute. [block:image] { "images": [ { "image": [ "https://files.readme.io/QF1iBxppSSuJ3684Sqqm_edit.png", "edit.png", "1212", "1204", "#45595e", "" ], "sizing": "smart", "border": true } ] } [/block] [block:callout] { "type": "danger", "title": "Warning", "body": "Sometimes adding an expression will stop your ability to use the UI. For example, if you use a parameter for the account field in a cluster deployment Stage, you will see a spinning loader from the UI when you try to edit this cluster." } [/block] ##Turning a stage on or off## You can use expressions to turn an individual stage on or off. To do so, select the 'Conditional on Expression' checkbox. Enter an expression: [block:image] { "images": [ { "image": [ "https://files.readme.io/XjIlLZCQjyZreblIMkpO_Screen%20Shot%202016-05-26%20at%202.53.51%20PM.png", "Screen Shot 2016-05-26 at 2.53.51 PM.png", "602", "43", "#456f8d", "" ] } ] } [/block] When this pipeline runs, it will evaluate the expression to decide if the stage can be skipped. This is useful for adding optional stages to your pipeline. ##Preconditions Stage## To use expressions to gate multiple stages, you can use the the 'check Preconditions' stage. When this stage is configured, it will gate the execution of subsequent stages. In other words, the stages that follow this stage will only run if the precondition evaluates to true. Add a new stage and set it to be of type *Check Preconditions*. [block:image] { "images": [ { "image": [ "https://files.readme.io/Tv63pvfT3GnWZ19yVcQj_precondition_check.png", "precondition_check.png", "650", "227", "#95abca", "" ] } ] } [/block] You can add one or more preconditions by clicking on *Add Precondition*. You can add expressions to be checked here by selecting *Expression* from the Check dropdown and entering an expression. [block:image] { "images": [ { "image": [ "https://files.readme.io/E30ovIyzRl6z9LGNtaZx_precondition.png", "precondition.png", "600", "250", "#3993a7", "" ] } ] } [/block] When the pipeline runs, if this expression evaluates to true, the pipeline will continue as is. If not, the stages following this stage will not run. [block:image] { "images": [ { "image": [ "https://files.readme.io/T2mTN7zcRL6MbEjCwuLP_precond%20pipe.png", "precond pipe.png", "600", "207", "#61676c", "" ] } ] } [/block] [block:api-header] { "type": "basic", "title": "What kind of data can I put in Pipeline Expressions?" } [/block] So where do we actually get the values that get evaluated in by pipeline expressions? In this section, we will describe the numerous sources of data for a pipeline in Spinnaker and how to access them. ##Pipeline Execution## The current running pipeline is available within Pipeline Expressions as `execution`. The easiest way to view this JSON is as follows, * Go to an execution of your pipeline. * Click on `Details` to expand the pipeline. * Click on the `source` link under the pipeline execution: [block:image] { "images": [ { "image": [ "https://files.readme.io/DoOxa42vRbere15q52i8_source.png", "source.png", "700", "269", "#71924b", "" ] } ] } [/block] This will take you to a JSON file that contains the details of your pipeline execution. From there, you can navigate to different parts of the pipeline. For example, to reference the name of the first stage you can use `${ execution.stages[0]['name'] }`. ##The current stage## Values for the current stage context are available by their variable name. In the execution JSON, they will be defined under the context object. For example, if I look at the JSON for a bake stage execution, I will see something like this: ``` { "id": "e980c921-b1f3-4b04-adda-b5c50ea1797a", "type": "bake", "name": "Bake", "startTime": 1464024188808, "endTime": null, "status": "RUNNING", "context": { "cloudProviderType": "aws", "regions": ["us-west-1"], "user": "clin@netflix.com", "vmType": "hvm", "storeType": "docker", "baseOs": "trusty", "baseLabel": "release", "package": "mypackage", "amiSuffix": "20160523172307" ... ``` This means that if I reference a field in my expression like `${ package }`, it will resolve to the package for that stage. ##Other stages## You can also access the value of other stages by doing a lookup by name using the [#stage( stage name )](#stagestring) helper method. To access stage attributes, you can call `${ #stage('stage name')['id']}`. To access the values passed into the stage, use `${ #stage('stage name')['context']['baseAmiName']}`. ##Pipeline Parameters## The configuration screen of your pipeline lets you specify parameters. Parameters to the pipeline can also come from upstream pipelines that have configured a Pipeline stage. You can access values of parameters within expressions by referencing the `parameters` array. This is a shortcut for `execution.parameters`. For example, `${ parameters['run canary'] }` will evaluate to the value of the parameter called *run canary*. ##Trigger Values## You can reference values in the pipeline trigger via the `trigger` property. This value is available in the execution JSON under the trigger object. The `trigger.buildInfo` field in jenkins triggers will contain details about the jenkins execution. To access the version hash of the git commit in Jenkins, for example, we can ask for `${ trigger.buildInfo.scm[0]['sha1'] }`. ##Property files## A feature of the Jenkins trigger is the ability to specify a properties file. Spinnaker will read the contents of this artifact ( it can be a Java .properties file, yml or json ) and add it into the pipeline context. To specify a property file, make sure you're archiving it in your jenkins job, then provide the name of the file, i.e `mypropertyfile.properties` ( not the absolute path i.e, `workspace/build/mypropertyfile.properties` ). [block:image] { "images": [ { "image": [ "https://files.readme.io/714c76c-helperParamContextList.png", "helperParamContextList.png", 867, 460, "#416b96" ] } ] } [/block] The contents of this file will now be available as a map under the trigger and accessible via `trigger.properties`. For example, if my property file looked like this: ``` BUILD_STACK=bojack BUILD_ANIMAL=horseman ``` I can then access the value from the property file as `${ trigger.properties['BUILD_ANIMAL']}` to get `horseman`. If you're adding property files from a Jenkins or Script *STAGE* ( not Trigger ), then you can omit the `trigger.properties` field as the stage. Any stage that runs after will be able to access these parameters as normal context fields. If we created a new stage and ran the same Jenkins job as above, then `${ BUILD_ANIMAL }` will resolve to `horseman`. [block:callout] { "type": "warning", "title": "Using the same field names", "body": "If you have multiple Jenkins jobs, they can clobber the same properties. A way around this is to reference the particular stage. `${ #stage( 'first jenkins job' )['context']['BUILD_ANIMAL'] }`" } [/block] ##Manual Judgement Choices## The manual judgment stage allows you to specify options when you approve a stage. Under Judgement Inputs, you can enter a choice. [block:image] { "images": [ { "image": [ "https://files.readme.io/yH9aAHjKSaagOkZ0FlIg_options.png", "options.png", "600", "187", "#5bb6c6", "" ] } ] } [/block] When your stage executes, you will see a dropdown with the provided choice. [block:image] { "images": [ { "image": [ "https://files.readme.io/8q9kbsbNRWOu59vfbNV3_input%20choice.png", "input choice.png", "350", "286", "#416eba", "" ] } ] } [/block] In subsequent stages, you can reference the choice provided via the [#judgment( stage Name ) ](#judgmentstring) helper method `${ #judgment( 'manual judgment stage name' )}`. ##External sources## You can also read from external sources via the [#fromUrl( url )](#fromurlstring) and [#jsonFromUrl( url )](#jsonfromurlstring) helper methods. [block:api-header] { "type": "basic", "title": "Pipeline Expression Language Reference" } [/block] The Pipeline Expression syntax is implemented with the Spring Expression Language ( SpEL ). You can learn more about SPeL by following this [link](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/expressions.html). ##Writing Expressions## A pipeline expression is started by `${` and terminated by `}` : `${ expression here }` You can interpolate expressions and strings, so `${expressionA}-randomString-${expressionB}` will evaluate to `Kimmy-randomString-Schmidt` when expressionA is `Kimmy` and expressionB is `Schmidt`. In Spinnaker, if an expression cannot be evaluated, it will return the expression entered. ##Strings## You can enter String in expressions: `${ 'this is a String' }` will evaluate to `this is a String`. ##Lists## You can reference entries in lists: `${ stages[0] }` will return the value of the first stage. ##Maps## And you can reference values in maps based on their keys: `${ trigger['properties']['value1']}` [block:callout] { "type": "info", "title": "Using a dot (.) vs square brackets [ 'value' ]", "body": "Spinnaker supports both a dot notation for accessing values and a square bracket notation. However, there are a few places where the dot notation doesn't work as expected --- for example after a filter operation or getting nested JSON values from an URL. Generally, it's recommended to use the square bracket notation for referencing map values as this is most predictable. I.e, prefer `trigger['properties']['value']` instead of `trigger.properties.value`." } [/block] ##Math## Arithmetic operations such as `${ trigger.buildInfo.number * 2 }` are supported. ##Comparisons## The expression language also allows you to specify rational operators, such as `${ instance.size > 400 }` or `${ params.runCanary == true }`. ##Functions## There are a few [helper functions](#helper-functions-in-spinnaker) available within Spinnaker. These can be accessed via `#functionName( params )`. For example, `#fromUrl( 'http://www.netflix.com' )`. ##Code## You can execute java code within the expression language. This can be useful for string manipulation or to create more exotic data fields. You can use methods available to existing types like String - `${ 'this is a long string'.substring(0,5)}` You can also declare new classes. Note that package names need to be fully qualified. In the following expression, we're getting the current date as mm-dd-yyyy format: `${ new java.text.SimpleDateFormat('mm-dd-yyyy').format(new java.util.Date()) }` ##Some Useful Things to Know## ###Default Values### You can set a default value within expressions by using `?:`. For example, `${ parameters.region ?: 'us-east-1'}`. ###Filtering Maps### The expression language allows you to filter maps by using the `.?` expression. For example, to filter a list of stages by type, you can use the expression `${ execution.stages.?[ type == 'bake' ] }` ###Lists as Parameters### Sometimes you want to enter a list of values as a parameter. For example, a list of regions or security groups. A useful tip here is to ask the user to enter them as a list of comma separated values `us-east-1,us-west-1,eu-west-1` and then use the `split()` method to make these into a map. Your expression would look like this `parameters.regions.split(',')`. ### #root ### Sometimes you want to reference another variable in an expression. You can do this by prepending `#root` in front of the expression name. In the following expression, I can set a value depending on the baseLabel field: `${ #root.baseLabel ?: 'noBaseLabelValue' }` [block:api-header] { "type": "basic", "title": "Helper properties in Spinnaker" } [/block] There are a few attribute shortcuts that you can use in Spinnaker: * `execution` : refers to the current pipeline execution. * `parameters` : pipeline parameters * `trigger` : pipeline trigger * `scmInfo` : this is a shortcut to the git details of either the trigger or the last executed jenkins stage. `scmInfo.sha1` will give you the hash of the last build. `scmInfo.branch` will give you the branch name. * `deployedServerGroups` : this is a reference to the server group that was created by the last deploy stage. Here is an example of the contents of a deployedServerGroups : ```[{account=prod,capacity={desired=1, max=1, min=1}, parentStage=23452655-c6de-4aac-b529-55e1357dfee7, region=us-west-1, ami=ami-575eb013, amiSuffix=201505190020, baseLabel=release, baseOs=trusty, package=rush, storeType=ebs, vmType=pv, serverGroup=rush-prestaging-v049}]``` [block:api-header] { "type": "basic", "title": "Helper functions in Spinnaker" } [/block] The following section outlines the currently available helper functions in Spinnaker. [block:api-header] { "type": "fn", "title": "#alphanumerical( String )" } [/block] Returns the String value of a string passed in with non A-Z or digits stripped out. This is useful if you want to have a valid stack or details field in Spinnaker, as some provides don't allow special characters in them. [block:api-header] { "type": "fn", "title": "#readJson(String)" } [/block] Converts a JSON String into a Map that can then be processed further. This is useful if a jenkins property file has a complex value that you want to pass into Spinnaker. This is also used by the #jsonFromUrl( ) function under the hood. [block:code] { "codes": [ { "code": "\"instanceType\": \"${#readJson('{\\\"prod\\\": \\\"r3.8xlarge\\\"}')[#root.parameters['environment']]}\",", "language": "text" } ] } [/block] [block:api-header] { "type": "fn", "title": "#fromUrl(String)" } [/block] Returns the contents of the specified URL as a String. [block:api-header] { "type": "fn", "title": "#jsonFromUrl(String)" } [/block] Retrieves the contents of the given URL and converts it into either a map or a list. This is useful to fetch information from the Spinnaker API or other sources. [block:api-header] { "type": "fn", "title": "#judgment(String)" } [/block] Gets the selected judgment value from the stage with the name asked for. I.,e `${#judgment('my manual judgment stage')}` will return the selected judgmentInput from the stage called `my manual judgment`. [block:api-header] { "title": "#propertiesFromUrl(String)" } [/block] Retrieves the contents of the properties file at the given URL and converts it into a map. This is useful to fetch information from jenkins properties files or other similar endpoints. [block:api-header] { "type": "fn", "title": "#stage(String)" } [/block] A shortcut to get the stage by name. I.e, `${#stage( 'bake' )}`. Be careful that the values for the stage are still under the context, so accessing a property would be via `${#stage('bake')['context']['valuePassedIn']}`. [block:api-header] { "type": "fn", "title": "#toBoolean(String)" } [/block] Converts a value to a boolean. [block:api-header] { "type": "fn", "title": "#toFloat(String)" } [/block] Converts a value to a floating point number. [block:api-header] { "type": "fn", "title": "#toInt( String )" } [/block] Converts a value to an integer. [block:api-header] { "type": "fn", "title": "#toJson(Object)" } [/block] Converts a Map into a JSON String. This is useful when you want to pass values from Spinnaker to another system. For example, I can use `${#toJson( deployedServerGroups )}` to pass the details of the recently deployed server groups to a jenkins job. [block:api-header] { "type": "basic", "title": "Sample Use Cases" } [/block] ## Create a stack based on the committed git branch ## In this use case, we're going to create a different cluster for each branch that gets triggered in Jenkins. 1. Set up a jenkins trigger for the pipeline. 2. Add a deploy stage and use an expression for my cluster name that uses the scmInfo value in the branch. `${ #alphanumerical( scmInfo.branch ) }`: [block:image] { "images": [ { "image": [ "https://files.readme.io/bLvuE8RlOWvPk9cvsQwl_Screen%20Shot%202016-05-23%20at%2011.28.24%20AM.png", "Screen Shot 2016-05-23 at 11.28.24 AM.png", "1104", "426", "#3d546b", "" ] } ] } [/block] The deploy stage should look like this: [block:image] { "images": [ { "image": [ "https://files.readme.io/ZaQSqDORDCfHU1hSZGSn_Screen%20Shot%202016-05-23%20at%2011.28.11%20AM.png", "Screen Shot 2016-05-23 at 11.28.11 AM.png", "2034", "236", "#404a4c", "" ] } ] } [/block] When the pipeline runs, it will replace the expression with the name of the branch, creating a new cluster: [block:image] { "images": [ { "image": [ "https://files.readme.io/ND6LhA0LRmGHt4B4MjDI_Screen%20Shot%202016-05-23%20at%2011.27.58%20AM.png", "Screen Shot 2016-05-23 at 11.27.58 AM.png", "558", "262", "#386f7d", "" ] } ] } [/block] ## Conditionally execute pipeline behavior based on manual input ## For this use case, we're going to set up a pipeline with 3 conditions, and gate these conditions with a manual judgment stage. 1. First, add a manual judgment stage and add three options. [block:image] { "images": [ { "image": [ "https://files.readme.io/YoMC5Jr7TTK9x0bfSag3_inputs.png", "inputs.png", "600", "185", "#51666a", "" ] } ] } [/block] 2. Now that I have these inputs set up, I create a new precondition stage. I add an expression to check that the input was 'clean up' [block:image] { "images": [ { "image": [ "https://files.readme.io/SH2bUiVWQfuv7VPUlkLS_edit%20precondition.png", "edit precondition.png", "600", "244", "#3898ad", "" ] } ] } [/block] My precondition stage should look like this. [block:image] { "images": [ { "image": [ "https://files.readme.io/17PhCH1RTW1MkW9BWQzx_stage.png", "stage.png", "800", "342", "#51b0c3", "" ] } ] } [/block] [block:callout] { "type": "info", "title": "Fail pipeline", "body": "For these type of workflows, you want to set *Fail Pipeline* as false when you're setting up your expression." } [/block] 3. Add stages that you want to execute based on this precondition. 4. I do the same for the 'deploy another' input. 5. My pipeline now looks like this: [block:image] { "images": [ { "image": [ "https://files.readme.io/14051de-selectedStageContextList.png", "selectedStageContextList.png", 757, 456, "#496c92" ] } ] } [/block] 6. Go to the executions screen and run my pipeline. I should see the options show up in the Manual Judgment stage: [block:image] { "images": [ { "image": [ "https://files.readme.io/ZrkkNylpSDCIAKsMgVJ9_selection.png", "selection.png", "800", "391", "#466a9d", "" ] } ] } [/block] If I select 'do nothing', which matches no preconditions, my pipeline should just stop: [block:image] { "images": [ { "image": [ "https://files.readme.io/dWiqWfsaQsatXQhXf5vl_donothing.png", "donothing.png", "800", "163", "#c24040", "" ] } ] } [/block] If I choose 'deploy another', I can see that the stages gated by deploy another are executed. [block:image] { "images": [ { "image": [ "https://files.readme.io/sLjlgETKSzWMyEDCTpPB_deploy%20another.png", "deploy another.png", "800", "140", "#52b4c4", "" ] } ] } [/block] Similarly, you can see that when I chose 'cleaning up', that pipeline branch is the one that runs. [block:image] { "images": [ { "image": [ "https://files.readme.io/VfDBgfUeSBqb1ugIBL6O_runclean.png", "runclean.png", "800", "132", "#59755b", "" ] } ] } [/block] [block:api-header] { "type": "basic", "title": "Expression Autocomplete" } [/block] Spinnaker has autocompleted functionality within the context of a pipeline configuration. **TLDR;** Here are the character triggers that will invoke the autocomplete **$** = Adds the **${ }** to the text field and starts the expression building **#** = Displays a list of all the **helper functions** **?** = Displays a list of **helper parameters** and **stages** for the pipeline In any text field, you can start autocompleting by typing a **dollar sign($)**. Doing so will display this: [block:image] { "images": [ { "image": [ "https://files.readme.io/5b1be30-start.png", "start.png", 560, 114, "#3e84b7" ] } ] } [/block] Hit enter and the opening and closing braces of the expression will be added to the text field. [block:image] { "images": [ { "image": [ "https://files.readme.io/8681fbb-textfieldwithexpression.png", "textfieldwithexpression.png", 560, 115, "#eaf4fa" ] } ] } [/block] ### Helper Functions and Stages Within the **curly braces ${ }**, adding a **question mark (?)** will display a list of all the helper properties that are relevant to the stage config that you are in as well as a list of all the stages in the pipeline. [block:image] { "images": [ { "image": [ "https://files.readme.io/36cab01-helperParamsAndStages.png", "helperParamsAndStages.png", 560, 330, "#3f6a92" ] } ] } [/block] Once the list is displayed you can start typing to narrow down the list and hitting enter will add the helper property or stage name to the expression. If a helper property is added to the expression you can then hit any of the meta-keys (Shift, Comand, Alt, Control) to pop up a list of all the pipeline config context relevant to that selected helper property. Here is an example of what context of the 'deployedServerGroups' helper property will show. [block:image] { "images": [ { "image": [ "https://files.readme.io/5d586b8-helperParamContextList.png", "helperParamContextList.png", 867, 460, "#416b96" ] } ] } [/block] The list will show the available context attributes on the left and the previous values highlighted on the right. The list can also be narrowed by typing a few characters, and selecting on by hitting **ENTER**. ### Helper Functions Also within the **curly braces (${ })**, adding a **pound sign (#)** will display a list of all the helper functions that are available. Here is an example of selecting the '#stage' helper function. [block:image] { "images": [ { "image": [ "https://files.readme.io/e0344b1-helperFunctions.png", "helperFunctions.png", 560, 302, "#396993" ] } ] } [/block] Selecting the function will add it to the expression and place the cursor between the single quotes [block:image] { "images": [ { "image": [ "https://files.readme.io/04fb5c7-stageFunctionSelected.png", "stageFunctionSelected.png", 560, 115, "#5c95b7" ] } ] } [/block] From here we can enter a **question mark (?)** to pull up the list of stages. [block:image] { "images": [ { "image": [ "https://files.readme.io/5689a73-stageSelectionInHelperFn.png", "stageSelectionInHelperFn.png", 560, 335, "#416e97" ] } ] } [/block] Once the stage name is selected it will be added to the expression. [block:image] { "images": [ { "image": [ "https://files.readme.io/e4fee2f-stageSelectedInHelperFn.png", "stageSelectedInHelperFn.png", 560, 115, "#5e8bac" ] } ] } [/block] From here you can move the cursor to the end of the closing paren of the function, and a list of context values for that stage will be presented for your choosing. [block:image] { "images": [ { "image": [ "https://files.readme.io/0c5674a-selectedStageContextList.png", "selectedStageContextList.png", 757, 456, "#496c92" ] } ] } [/block] [block:api-header] { "type": "basic", "title": "Source Code" } [/block] The expression language support can be found in the orca codebase and pretty much encapsulated in the [ContextParameterProcessor](https://github.com/spinnaker/orca/blob/master/orca-core/src/main/groovy/com/netflix/spinnaker/orca/pipeline/util/ContextParameterProcessor.groovy) class.