Skip to main content
Мы публикуем частые обновления нашей документации, и перевод этой страницы может все еще выполняться. Актуальные сведения см. в документации на английском языке.

Выражения

Выражения можно оценивать в рабочих процессах и действиях.

Примечание. В GitHub Enterprise Server в настоящее время не поддерживаются средства выполнения тестов, размещенные в GitHub. Дополнительные сведения о планируемой поддержке в будущем см. в GitHub public roadmap.

Сведения о выражениях

С помощью выражений можно программно задавать переменные среды в файлах рабочих процессов и контекстах доступа. Выражение представляет собой сочетание литералов, ссылок на контекст и функций, которые соединяются с помощью операторов. Дополнительные сведения о контекстах см. в разделе Контексты.

Выражения обычно используются с условным оператором if в файле рабочего процесса для определения того, следует ли выполнять шаг или нет. Если выражение в условии if равно true, шаг выполняется.

Чтобы в GitHub выражение вычислялось, а не считалось строкой, необходимо использовать особый синтаксис.

${{ <expression> }}

При использовании выражений в условной директиве if можно пропустить синтаксис выражения (${{ }}), так как GitHub автоматически обрабатывает условную директиву if как выражение. Дополнительные сведения об if условных выражениях см. в разделе Синтаксис рабочего процесса для GitHub Actions.

Предупреждение. Во время создания рабочих процессов и действий необходимо учитывать, будет ли код использовать непроверенные входные данные от возможных злоумышленников. Некоторые контексты следует считать непроверенными, так как злоумышленники могут вставить собственное вредоносное содержимое. Дополнительные сведения см. в разделе Защита системы безопасности для GitHub Actions.

Пример выражения в условном операторе if

steps:
  - uses: actions/hello-world-javascript-action@e76147da8e5c81eaf017dede5645551d4b94427b
    if: ${{ <expression> }}

Пример настройки переменной среды

env:
  MY_ENV_VAR: ${{ <expression> }}

Литералы

В выражении можно использовать типы данных boolean, null, number и string.

Тип данныхЛитерал
booleantrue или false
nullnull
numberЛюбой числовой формат, поддерживаемый JSON.
stringЗаключать строки в скобки ${{ и }} необязательно. Однако если вы решите это сделать, используйте одинарные кавычки (') вокруг строки. Чтобы использовать литерал в виде одинарной кавычки, экранируйте его с помощью дополнительной одинарной кавычки (''). Если заключить такой литерал в двойные кавычки ("), возникнет ошибка.

Пример литерала

env:
  myNull: ${{ null }}
  myBoolean: ${{ false }}
  myIntegerNumber: ${{ 711 }}
  myFloatNumber: ${{ -9.2 }}
  myHexNumber: ${{ 0xff }}
  myExponentialNumber: ${{ -2.99e-2 }}
  myString: Mona the Octocat
  myStringInBraces: ${{ 'It''s open source!' }}

Операторы

ОператорОписание
( )Логическое группирование
[ ]Индекс
.Разыменование свойства
!Not
<Меньше чем
<=Меньше или равно
>Больше чем
>=Больше или равно
==Равно
!=Не равно
&&And
||либо

GitHub выполняет нестрогое сравнение.

  • Если типы не совпадают, GitHub приводит их к числовому типу. Для этого в GitHub используются следующие преобразования:

    ТипРезультат
    NULL0
    Логическое значениеtrue возвращает 1
    false возвращает 0
    СтрокаПреобразуется в любой допустимый числовой формат JSON, в противном случае дает значение NaN.
    Примечание. Для пустой строки возвращается 0.
    ArrayNaN
    ОбъектNaN
  • Сравнение одного значения NaN с другим NaN не дает true. Дополнительные сведения см. в разделе о свойствах NaN в Mozilla.

  • При сравнении строк в GitHub регистр не учитывается.

  • Объект и массив считаются равными, только если это один экземпляр.

Функции

В GitHub предлагается набор встроенных функций, которые можно использовать в выражениях. Чтобы выполнить сравнение, некоторые функции приводят значения к строковому типу. Для этого в GitHub используются следующие преобразования:

ТипРезультат
NULL''
Логическое значение'true' или 'false'
NumberДесятичный формат, экспоненциальная запись для больших чисел
ArrayМассивы не преобразуются в строку
ОбъектОбъекты не преобразуются в строку

contains

contains( search, item )

Возвращает true, если search содержит item. Если search является массивом, эта функция возвращает значение true, когда item является элементом в массиве. Если search является строкой, эта функция возвращает значение true, когда item является подстрокой search. В этой функции регистр не учитывается. Приводит значения к строковому типу.

Пример использования строки

contains('Hello world', 'llo') возвращает true.

Пример использования фильтра объектов

contains(github.event.issue.labels.*.name, 'bug') возвращает true, если проблема, связанная с событием, имеет метку "bug" (ошибка).

Дополнительные сведения см. в разделе Фильтры объектов.

Пример сопоставления массива строк

Вместо записи github.event_name == "push" || github.event_name == "pull_request" можно использовать contains() с fromJSON(), чтобы проверить, содержит ли массив строк item.

Например, contains(fromJSON('["push", "pull_request"]'), github.event_name) возвращает true, если github.event_name имеет значение "push" или "pull_request".

startsWith

startsWith( searchString, searchValue )

Возвращает значение true, когда searchString начинается с searchValue. В этой функции регистр не учитывается. Приводит значения к строковому типу.

Пример startsWith

startsWith('Hello world', 'He') возвращает true.

endsWith

endsWith( searchString, searchValue )

Возвращает значение true, если searchString заканчивается на searchValue. В этой функции регистр не учитывается. Приводит значения к строковому типу.

Пример endsWith

endsWith('Hello world', 'ld') возвращает true.

format

format( string, replaceValue0, replaceValue1, ..., replaceValueN)

Заменяет значения в строке string на значение переменной replaceValueN. Переменные в string указываются с помощью синтаксиса {N}, где N является целым числом. Необходимо указать хотя бы одно значение replaceValue и string. Максимальное количество переменных (replaceValueN) не ограничивается. Чтобы указать фигурную скобку, экранируйте ее еще одной фигурной скобкой.

Пример format

format('Hello {0} {1} {2}', 'Mona', 'the', 'Octocat')

Возвращает «Hello Mona the Octocat».

Пример экранирования фигурных скобок

format('{{Hello {0} {1} {2}!}}', 'Mona', 'the', 'Octocat')

Возвращает «{Hello Mona the Octocat!}».

join

join( array, optionalSeparator )

Значением array может быть массив или строка. Все значения в array сцепляются в строку. Между сцепленными значениями вставляется разделитель optionalSeparator. Если он не указан, используется разделитель по умолчанию — ,. Приводит значения к строковому типу.

Пример join

join(github.event.issue.labels.*.name, ', ') может вернуть «bug, help wanted» (ошибка, требуется помощь)

toJSON

toJSON(value)

Возвращает значение value в правильном формате JSON. С помощью этой функции можно отлаживать данные, предоставленные в контекстах.

Пример toJSON

toJSON(job) может вернуть { "status": "success" }

fromJSON

fromJSON(value)

Возвращает объект JSON или тип данных JSON для value. С помощью этой функции можно представить объект JSON в виде вычисляемого выражения или преобразовать переменные среды из строки.

Пример возврата объекта JSON

Этот рабочий процесс задает матрицу JSON в одном задании и передает ее следующему заданию с помощью выходных данных и функции fromJSON.

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

Пример возврата типа данных JSON

Этот рабочий процесс с помощью функции fromJSON преобразует переменные среды из строки в логическое значение или целое число.

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 ...

hashFiles

hashFiles(path)

Возвращает один хэш для набора файлов по шаблону пути path. Вы можете указать один шаблон path или несколько шаблонов path, разделенных запятыми. Путь path указывается относительно каталога GITHUB_WORKSPACE и может включать только файлы внутри GITHUB_WORKSPACE. Эта функция вычисляет отдельный хэш SHA-256 для каждого подходящего файла, а затем с помощью этих хэшей вычисляет окончательный хэш SHA-256 для набора файлов. Если по шаблону path файлы отсутствуют, функция возвращает пустую строку. Дополнительные сведения о SHA-256 см. в разделе «SHA-2».

Для сопоставления с именами файлов можно использовать подстановочные знаки. В Windows при сопоставлении по шаблону регистр не учитывается. Дополнительные сведения о поддерживаемых символах сопоставления шаблонов см. в разделе Синтаксис рабочего процесса для GitHub Actions.

Пример с одним шаблоном

Соответствует любому файлу package-lock.json в репозитории.

hashFiles('**/package-lock.json')

Пример с несколькими шаблонами

Создает хэш для всех файлов package-lock.json и Gemfile.lock в репозитории.

hashFiles('**/package-lock.json', '**/Gemfile.lock')

Функции проверки состояния

Следующие функции проверки состояния можно использовать в качестве выражений в условных операторах if. Если не включить ни одну из этих функций, применяется проверка состояния по умолчанию success(). Дополнительные сведения об if условных выражениях см. в разделах Синтаксис рабочего процесса для GitHub Actions и Синтаксис метаданных для GitHub Actions.

Успешное завершение

Возвращает значение true, если ни один из предыдущих шагов не завершился сбоем или не был отменен.

Пример success

steps:
  ...
  - name: The job has succeeded
    if: ${{ success() }}

always

Задает принудительное выполнение шага при любых обстоятельствах и возвращает значение true даже при отмене. Выражение always лучше всего использовать на уровне шага или для задач, которые должны выполняться даже при отмене задания. Например, можно использовать для always отправки журналов даже при отмене задания.

Примечание: Избегайте использования always для любой задачи, которая может пострадать от критического сбоя, например получение источников, в противном случае рабочий процесс может зависать до истечения времени ожидания. Если вы хотите выполнить задание или шаг независимо от их успешного или неудачного выполнения, используйте рекомендуемую альтернативу:if: success() || failure()

Пример always

if: ${{ always() }}

cancelled

Возвращает значение true, если рабочий процесс был отменен.

Пример cancelled

if: ${{ cancelled() }}

ошибка

Возвращает значение true, если любой предыдущий шаг задания завершается сбоем. При наличии цепочки зависимых заданий, функция failure() возвращает значение true, если сбоем завершается любое предыдущее задание.

Пример failure

steps:
  ...
  - name: The job has failed
    if: ${{ failure() }}

сбой с условиями

Вы можете включить дополнительные условия для шага, выполняемого после сбоя, но необходимо по-прежнему включить failure() для переопределения проверки состояния по умолчанию для success(), которая автоматически применяется к условиям if, не содержащим функцию проверки состояния.

Пример с failure условиями
steps:
  ...
  - name: Failing step
    id: demo
    run: exit 1
  - name: The demo step has failed
    if: ${{ failure() && steps.demo.conclusion == 'failure' }}

Фильтры объектов

С помощью записи * можно применить фильтр и подобрать соответствующие элементы из коллекции.

Например, рассмотрим массив объектов с именем fruits.

[
  { "name": "apple", "quantity": 1 },
  { "name": "orange", "quantity": 2 },
  { "name": "pear", "quantity": 1 }
]

Фильтр fruits.*.name возвращает массив [ "apple", "orange", "pear" ].

Синтаксис * также можно использовать для объекта. Например, допустим, у вас есть объект с именем vegetables.


{
  "scallions":
  {
    "colors": ["green", "white", "red"],
    "ediblePortions": ["roots", "stalks"],
  },
  "beets":
  {
    "colors": ["purple", "red", "gold", "white", "pink"],
    "ediblePortions": ["roots", "stems", "leaves"],
  },
  "artichokes":
  {
    "colors": ["green", "purple", "red", "black"],
    "ediblePortions": ["hearts", "stems", "leaves"],
  },
}

Применение фильтра vegetables.*.ediblePortions может дать следующий результат:


[
  ["roots", "stalks"],
  ["hearts", "stems", "leaves"],
  ["roots", "stems", "leaves"],
]

Так как объекты не сохраняют порядок, порядок выходных данных не может быть гарантирован.