335 lines
10 KiB
Markdown
335 lines
10 KiB
Markdown
---
|
|
title: Expressions
|
|
shortTitle: Expressions
|
|
intro: You can evaluate expressions in workflows and actions.
|
|
versions:
|
|
fpt: '*'
|
|
ghes: '*'
|
|
ghae: '*'
|
|
ghec: '*'
|
|
miniTocMaxHeadingLevel: 3
|
|
---
|
|
|
|
{% data reusables.actions.enterprise-beta %}
|
|
{% data reusables.actions.enterprise-github-hosted-runners %}
|
|
{% data reusables.actions.ae-beta %}
|
|
|
|
## About expressions
|
|
|
|
You can use expressions to programmatically set variables in workflow files and access contexts. An expression can be any combination of literal values, references to a context, or functions. You can combine literals, context references, and functions using operators. For more information about contexts, see "[Contexts](/actions/learn-github-actions/contexts)."
|
|
|
|
Expressions are commonly used with the conditional `if` keyword in a workflow file to determine whether a step should run. When an `if` conditional is `true`, the step will run.
|
|
|
|
You need to use specific syntax to tell {% data variables.product.prodname_dotcom %} to evaluate an expression rather than treat it as a string.
|
|
|
|
{% raw %}
|
|
`${{ <expression> }}`
|
|
{% endraw %}
|
|
|
|
{% data reusables.github-actions.expression-syntax-if %} For more information about `if` conditionals, see "[Workflow syntax for {% data variables.product.prodname_actions %}](/articles/workflow-syntax-for-github-actions/#jobsjob_idif)."
|
|
|
|
{% data reusables.github-actions.context-injection-warning %}
|
|
|
|
#### Example expression in an `if` conditional
|
|
|
|
```yaml
|
|
steps:
|
|
- uses: actions/hello-world-javascript-action@v1.1
|
|
if: {% raw %}${{ <expression> }}{% endraw %}
|
|
```
|
|
|
|
#### Example setting an environment variable
|
|
|
|
{% raw %}
|
|
```yaml
|
|
env:
|
|
MY_ENV_VAR: ${{ <expression> }}
|
|
```
|
|
{% endraw %}
|
|
|
|
## Literals
|
|
|
|
As part of an expression, you can use `boolean`, `null`, `number`, or `string` data types.
|
|
|
|
| Data type | Literal value |
|
|
|-----------|---------------|
|
|
| `boolean` | `true` or `false` |
|
|
| `null` | `null` |
|
|
| `number` | Any number format supported by JSON. |
|
|
| `string` | You must use single quotes. Escape literal single-quotes with a single quote. |
|
|
|
|
#### Example
|
|
|
|
{% raw %}
|
|
```yaml
|
|
env:
|
|
myNull: ${{ null }}
|
|
myBoolean: ${{ false }}
|
|
myIntegerNumber: ${{ 711 }}
|
|
myFloatNumber: ${{ -9.2 }}
|
|
myHexNumber: ${{ 0xff }}
|
|
myExponentialNumber: ${{ -2.99-e2 }}
|
|
myString: ${{ 'Mona the Octocat' }}
|
|
myEscapedString: ${{ 'It''s open source!' }}
|
|
```
|
|
{% endraw %}
|
|
|
|
## Operators
|
|
|
|
| Operator | Description |
|
|
| --- | --- |
|
|
| `( )` | Logical grouping |
|
|
| `[ ]` | Index
|
|
| `.` | Property dereference |
|
|
| `!` | Not |
|
|
| `<` | Less than |
|
|
| `<=` | Less than or equal |
|
|
| `>` | Greater than |
|
|
| `>=` | Greater than or equal |
|
|
| `==` | Equal |
|
|
| `!=` | Not equal |
|
|
| `&&` | And |
|
|
| <code>\|\|</code> | Or |
|
|
|
|
{% data variables.product.prodname_dotcom %} performs loose equality comparisons.
|
|
|
|
* If the types do not match, {% data variables.product.prodname_dotcom %} coerces the type to a number. {% data variables.product.prodname_dotcom %} casts data types to a number using these conversions:
|
|
|
|
| Type | Result |
|
|
| --- | --- |
|
|
| Null | `0` |
|
|
| Boolean | `true` returns `1` <br /> `false` returns `0` |
|
|
| String | Parsed from any legal JSON number format, otherwise `NaN`. <br /> Note: empty string returns `0`. |
|
|
| Array | `NaN` |
|
|
| Object | `NaN` |
|
|
* A comparison of one `NaN` to another `NaN` does not result in `true`. For more information, see the "[NaN Mozilla docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN)."
|
|
* {% data variables.product.prodname_dotcom %} ignores case when comparing strings.
|
|
* Objects and arrays are only considered equal when they are the same instance.
|
|
|
|
## Functions
|
|
|
|
{% data variables.product.prodname_dotcom %} offers a set of built-in functions that you can use in expressions. Some functions cast values to a string to perform comparisons. {% data variables.product.prodname_dotcom %} casts data types to a string using these conversions:
|
|
|
|
| Type | Result |
|
|
| --- | --- |
|
|
| Null | `''` |
|
|
| Boolean | `'true'` or `'false'` |
|
|
| Number | Decimal format, exponential for large numbers |
|
|
| Array | Arrays are not converted to a string |
|
|
| Object | Objects are not converted to a string |
|
|
|
|
### contains
|
|
|
|
`contains( search, item )`
|
|
|
|
Returns `true` if `search` contains `item`. If `search` is an array, this function returns `true` if the `item` is an element in the array. If `search` is a string, this function returns `true` if the `item` is a substring of `search`. This function is not case sensitive. Casts values to a string.
|
|
|
|
#### Example using an array
|
|
|
|
`contains(github.event.issue.labels.*.name, 'bug')`
|
|
|
|
#### Example using a string
|
|
|
|
`contains('Hello world', 'llo')` returns `true`
|
|
|
|
### startsWith
|
|
|
|
`startsWith( searchString, searchValue )`
|
|
|
|
Returns `true` when `searchString` starts with `searchValue`. This function is not case sensitive. Casts values to a string.
|
|
|
|
#### Example
|
|
|
|
`startsWith('Hello world', 'He')` returns `true`
|
|
|
|
### endsWith
|
|
|
|
`endsWith( searchString, searchValue )`
|
|
|
|
Returns `true` if `searchString` ends with `searchValue`. This function is not case sensitive. Casts values to a string.
|
|
|
|
#### Example
|
|
|
|
`endsWith('Hello world', 'ld')` returns `true`
|
|
|
|
### format
|
|
|
|
`format( string, replaceValue0, replaceValue1, ..., replaceValueN)`
|
|
|
|
Replaces values in the `string`, with the variable `replaceValueN`. Variables in the `string` are specified using the `{N}` syntax, where `N` is an integer. You must specify at least one `replaceValue` and `string`. There is no maximum for the number of variables (`replaceValueN`) you can use. Escape curly braces using double braces.
|
|
|
|
#### Example
|
|
|
|
Returns 'Hello Mona the Octocat'
|
|
|
|
`format('Hello {0} {1} {2}', 'Mona', 'the', 'Octocat')`
|
|
|
|
#### Example escaping braces
|
|
|
|
Returns '{Hello Mona the Octocat!}'
|
|
|
|
{% raw %}
|
|
```js
|
|
format('{{Hello {0} {1} {2}!}}', 'Mona', 'the', 'Octocat')
|
|
```
|
|
{% endraw %}
|
|
|
|
### join
|
|
|
|
`join( array, optionalSeparator )`
|
|
|
|
The value for `array` can be an array or a string. All values in `array` are concatenated into a string. If you provide `optionalSeparator`, it is inserted between the concatenated values. Otherwise, the default separator `,` is used. Casts values to a string.
|
|
|
|
#### Example
|
|
|
|
`join(github.event.issue.labels.*.name, ', ')` may return 'bug, help wanted'
|
|
|
|
### toJSON
|
|
|
|
`toJSON(value)`
|
|
|
|
Returns a pretty-print JSON representation of `value`. You can use this function to debug the information provided in contexts.
|
|
|
|
#### Example
|
|
|
|
`toJSON(job)` might return `{ "status": "Success" }`
|
|
|
|
### fromJSON
|
|
|
|
`fromJSON(value)`
|
|
|
|
Returns a JSON object or JSON data type for `value`. You can use this function to provide a JSON object as an evaluated expression or to convert environment variables from a string.
|
|
|
|
#### Example returning a JSON object
|
|
|
|
This workflow sets a JSON matrix in one job, and passes it to the next job using an output and `fromJSON`.
|
|
|
|
{% raw %}
|
|
```yaml
|
|
name: build
|
|
on: push
|
|
jobs:
|
|
job1:
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
matrix: ${{ steps.set-matrix.outputs.matrix }}
|
|
steps:
|
|
- id: set-matrix
|
|
run: echo "::set-output name=matrix::{\"include\":[{\"project\":\"foo\",\"config\":\"Debug\"},{\"project\":\"bar\",\"config\":\"Release\"}]}"
|
|
job2:
|
|
needs: job1
|
|
runs-on: ubuntu-latest
|
|
strategy:
|
|
matrix: ${{fromJSON(needs.job1.outputs.matrix)}}
|
|
steps:
|
|
- run: build
|
|
```
|
|
{% endraw %}
|
|
|
|
#### Example returning a JSON data type
|
|
|
|
This workflow uses `fromJSON` to convert environment variables from a string to a Boolean or integer.
|
|
|
|
{% raw %}
|
|
```yaml
|
|
name: print
|
|
on: push
|
|
env:
|
|
continue: true
|
|
time: 3
|
|
jobs:
|
|
job1:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- continue-on-error: ${{ fromJSON(env.continue) }}
|
|
timeout-minutes: ${{ fromJSON(env.time) }}
|
|
run: echo ...
|
|
```
|
|
{% endraw %}
|
|
|
|
### hashFiles
|
|
|
|
`hashFiles(path)`
|
|
|
|
Returns a single hash for the set of files that matches the `path` pattern. You can provide a single `path` pattern or multiple `path` patterns separated by commas. The `path` is relative to the `GITHUB_WORKSPACE` directory and can only include files inside of the `GITHUB_WORKSPACE`. This function calculates an individual SHA-256 hash for each matched file, and then uses those hashes to calculate a final SHA-256 hash for the set of files. For more information about SHA-256, see "[SHA-2](https://en.wikipedia.org/wiki/SHA-2)."
|
|
|
|
You can use pattern matching characters to match file names. Pattern matching is case-insensitive on Windows. For more information about supported pattern matching characters, see "[Workflow syntax for {% data variables.product.prodname_actions %}](/github/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions/#filter-pattern-cheat-sheet)."
|
|
|
|
#### Example with a single pattern
|
|
|
|
Matches any `package-lock.json` file in the repository.
|
|
|
|
`hashFiles('**/package-lock.json')`
|
|
|
|
#### Example with multiple patterns
|
|
|
|
Creates a hash for any `package-lock.json` and `Gemfile.lock` files in the repository.
|
|
|
|
`hashFiles('**/package-lock.json', '**/Gemfile.lock')`
|
|
|
|
## Job status check functions
|
|
|
|
You can use the following status check functions as expressions in `if` conditionals. A default status check of `success()` is applied unless you include one of these functions. For more information about `if` conditionals, see "[Workflow syntax for GitHub Actions](/articles/workflow-syntax-for-github-actions/#jobsjob_idif)."
|
|
|
|
### success
|
|
|
|
Returns `true` when none of the previous steps have failed or been canceled.
|
|
|
|
#### Example
|
|
|
|
```yaml
|
|
steps:
|
|
...
|
|
- name: The job has succeeded
|
|
if: {% raw %}${{ success() }}{% endraw %}
|
|
```
|
|
|
|
### always
|
|
|
|
Causes the step to always execute, and returns `true`, even when canceled. A job or step will not run when a critical failure prevents the task from running. For example, if getting sources failed.
|
|
|
|
#### Example
|
|
|
|
```yaml
|
|
if: {% raw %}${{ always() }}{% endraw %}
|
|
```
|
|
|
|
### cancelled
|
|
|
|
Returns `true` if the workflow was canceled.
|
|
|
|
#### Example
|
|
|
|
```yaml
|
|
if: {% raw %}${{ cancelled() }}{% endraw %}
|
|
```
|
|
|
|
### failure
|
|
|
|
Returns `true` when any previous step of a job fails.
|
|
|
|
#### Example
|
|
|
|
```yaml
|
|
steps:
|
|
...
|
|
- name: The job has failed
|
|
if: {% raw %}${{ failure() }}{% endraw %}
|
|
```
|
|
|
|
## Object filters
|
|
|
|
You can use the `*` syntax to apply a filter and select matching items in a collection.
|
|
|
|
For example, consider an array of objects named `fruits`.
|
|
|
|
```json
|
|
[
|
|
{ "name": "apple", "quantity": 1 },
|
|
{ "name": "orange", "quantity": 2 },
|
|
{ "name": "pear", "quantity": 1 }
|
|
]
|
|
```
|
|
|
|
The filter `fruits.*.name` returns the array `[ "apple", "orange", "pear" ]`
|