Skip to main content

Enterprise Server 3.15 está disponível no momento como versão release candidate.

Avaliar expressões em fluxos de trabalho e ações

Você pode avaliar expressões em fluxos de trabalho e ações.

Observação: no momento, não há suporte para os executores hospedados no GitHub no GitHub Enterprise Server. Você pode ver mais informações sobre o suporte futuro planejado no GitHub public roadmap.

Sobre as expressões

Você pode usar expressões para definir variáveis de ambiente programaticamente em arquivos de fluxo de trabalho e contextos de acesso. Uma expressão pode ser qualquer combinação de valores literais, referências a um contexto ou funções. É possível combinar literais, referências de contexto e funções usando operadores. Para obter mais informações sobre contextos, confira "Acessar informações contextuais sobre execuções de fluxo de trabalho".

As expressões são normalmente usadas com a palavra-chave if condicional em um arquivo de fluxo de trabalho para determinar se uma etapa deve ser executada. Quando um condicional if for true, a etapa será executada.

É necessário usar uma sintaxe específica para avisar o GitHub para avaliar a expressão e não tratá-la como uma string.

${{ <expression> }}

Observação: a exceção a essa regra é quando você está usando expressões em uma cláusula if, em que, opcionalmente, você pode omitir ${{ and }}, em geral. Para obter mais informações sobre condicionais if, confira "Sintaxe de fluxo de trabalho para o GitHub Actions".

Warning

Ao criar fluxos de trabalho e ações, sempre considere se o código poderá executar entradas não confiáveis de possíveis invasores. Certos contextos devem ser tratados como entradas não confiáveis, uma vez que um invasor pode inserir seu próprio conteúdo malicioso. Para obter mais informações, confira "Fortalecimento de segurança para o GitHub Actions".

Exemplo de configuração de variável de ambiente

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

Literais

Como parte de uma expressão, você pode usar os tipos de dados boolean, null, number ou string.

Tipo de dadosValor literal
booleantrue ou false
nullnull
numberQualquer formato de número aceito por JSON.
stringVocê não precisa colocar cadeias de caracteres em ${{ e }}. No entanto, se você fizer isso, deverá usar aspas simples (') ao redor da cadeia de caracteres. Para usar uma aspa simples literal, não use as aspas simples literais e use as aspas simples adicionais (''). Encapsular com aspas duplas (") gerará um erro.

Note que em condicionais, valores falsos (false, 0, -0, "", '', null) são coagidos para false e valores verdadeiros (true e outros valores não falsos) são coagidos para true.

Exemplo de literais

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!' }}

Operadores

OperadorDescrição
( )Agrupamento lógico
[ ]Índice
.Property de-reference
!Not
<Menor que
<=Inferior ou igual
>Maior que
>=Maior ou igual
==Igual
!=Diferente
&&And
||Ou

Observações:

  • O GitHub ignora as maiúsculas e minúsculas ao comparar strings.
  • steps.<step_id>.outputs.<output_name> é avaliada como uma cadeia de caracteres. É necessário usar uma sintaxe específica para avisar o GitHub para avaliar a expressão e não tratá-la como uma string. Para obter mais informações, confira "Acessar informações contextuais sobre execuções de fluxo de trabalho".
  • Para comparação numérica, a função fromJSON() pode ser usada para converter uma cadeia de caracteres em um número. Para obter mais informações sobre a função fromJSON(), confira "fromJSON".

O GitHub faz comparações livres de igualdade.

  • Se os tipos não correspondem, o GitHub força o tipo para um número. O GitHub converte tipos de dados em um número usando estes esquemas:

    TipoResult
    Nulo0
    Boolianotrue retorna 1
    false retorna 0
    StringAnalisado de qualquer formato de número JSON legal, caso contrário, NaN.
    Observação: a cadeia de caracteres vazia retorna 0.
    ArrayNaN
    ObjetoNaN
  • Quando NaN é um dos operandos de qualquer comparação relacional (>, <, >=, <=), o resultado é sempre false. Para obter mais informações, confira os "documentos do NaN Mozilla".

  • O GitHub ignora as maiúsculas e minúsculas ao comparar strings.

  • Objetos e arrays só são considerados iguais quando forem a mesma instância.

O GitHub oferece um operador ternário como um comportamento que pode ser usado em expressões. Usando um operador ternário dessa forma, é possível definir dinamicamente o valor de uma variável de ambiente com base em uma condição, sem precisar gravar blocos if-else separados para cada opção possível.

Exemplo

env:
  MY_ENV_VAR: ${{ github.ref == 'refs/heads/main' && 'value_for_main_branch' || 'value_for_other_branches' }}

Neste exemplo, um operador ternário é usado para definir o valor da variável de ambiente MY_ENV_VAR com base na definição ou não da referência de GitHub como refs/heads/main. Se essa referência estiver definida, a variável será definida como value_for_main_branch. Caso contrário, ele será definido como value_for_other_branches. É importante notar que o primeiro valor após o && deve ser verdadeiro. Caso contrário, o valor após o || será sempre retornado.

Funções

O GitHub oferece um conjunto de funções integradas que podem ser usadas em expressões. Algumas funções convertem valores em uma string para realizar comparações. O GitHub converte tipos de dados em uma string usando estes esquemas:

TipoResult
Nulo''
Booliano'true' ou 'false'
NúmeroFormato decimal, exponencial para números altos
ArrayArrays não são convertidos em uma string
ObjetoObjetos não são convertidos em uma string

contém

contains( search, item )

Retorna true se search contém item. Se search for uma matriz, essa função retornará true se o item for um elemento na matriz. Se search for uma cadeia de caracteres, essa função retornará true se item uma substring de search. Essa função não diferencia maiúsculas de minúsculas. Lança valores em uma string.

Exemplo de uso de string

contains('Hello world', 'llo') retorna true.

Exemplo de como usar um filtro de objeto

contains(github.event.issue.labels.*.name, 'bug') retornará true se o problema relacionado ao evento tiver um rótulo "bug".

Para obter mais informações, confira "Filtros de objeto".

Exemplo que corresponde a uma matriz de cadeias de caracteres

Em vez de escrever github.event_name == "push" || github.event_name == "pull_request", você pode usar contains() com fromJSON() para verificar se uma matriz de cadeias de caracteres contém um item.

Por exemplo, contains(fromJSON('["push", "pull_request"]'), github.event_name) retornará true se github.event_name for "push" ou "pull_request".

startsWith

startsWith( searchString, searchValue )

Retorna true quandosearchString começa com searchValue. Essa função não diferencia maiúsculas de minúsculas. Lança valores em uma string.

Exemplo de startsWith

startsWith('Hello world', 'He') retorna true.

endsWith

endsWith( searchString, searchValue )

Retorna true se searchString termina com searchValue. Essa função não diferencia maiúsculas de minúsculas. Lança valores em uma string.

Exemplo de endsWith

endsWith('Hello world', 'ld') retorna true.

format

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

Substitui os valores na string, com a variável replaceValueN. As variáveis na string são especificadas usando a sintaxe {N}, em que N é um inteiro. É necessário especificar pelo menos um replaceValue e uma string. Não há um máximo para o número de variáveis (replaceValueN) que você pode usar. Escape de chaves usando chaves duplas.

Exemplo de format

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

Retorna "Hello Mona the Octocat".

Exemplo de escape de chaves

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

Retorna '{Hello Mona the Octocat!}'.

join

join( array, optionalSeparator )

O valor para array pode ser uma matriz ou uma cadeia de caracteres. Todos os valores em array são concatenados em uma cadeia de caracteres. Se você fornecer optionalSeparator, ele será inserido entre os valores concatenados. Caso contrário, o separador padrão , será usado. Lança valores em uma string.

Exemplo de join

join(github.event.issue.labels.*.name, ', ') pode retornar "bug, preciso de ajuda"

toJSON

toJSON(value)

Retorna uma representação JSON recém-impressa de value. Você pode usar essa função para depurar as informações fornecidas em contextos.

Exemplo de toJSON

toJSON(job) pode retornar { "status": "success" }

fromJSON

fromJSON(value)

Retorna um objeto JSON ou um tipo de dados JSON para value. Você pode usar essa função para fornecer um objeto JSON como uma expressão avaliada ou para converter qualquer tipo de dados que possa ser representado em JSON ou JavaScript, como cadeias de caracteres, boolianos, valores nulos, matrizes e objetos.

Exemplo que retorna um objeto do JSON

Esse fluxo de trabalho define uma matriz JSON em um trabalho e a passa para o próximo trabalho usando uma saída e fromJSON.

YAML
name: build
on: push
jobs:
  job1:
    runs-on: ubuntu-latest
    outputs:
      matrix: ${{ steps.set-matrix.outputs.matrix }}
    steps:
      - id: set-matrix
        run: echo "matrix={\"include\":[{\"project\":\"foo\",\"config\":\"Debug\"},{\"project\":\"bar\",\"config\":\"Release\"}]}" >> $GITHUB_OUTPUT
  job2:
    needs: job1
    runs-on: ubuntu-latest
    strategy:
      matrix: ${{ fromJSON(needs.job1.outputs.matrix) }}
    steps:
      - run: echo "Matrix - Project ${{ matrix.project }}, Config ${{ matrix.config }}"

Exemplo que retorna um tipo de dado do JSON

Esse fluxo de trabalho usa fromJSON para converter variáveis de ambiente de uma cadeia de caracteres em um booliano ou inteiro.

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

O fluxo de trabalho usa a função fromJSON() para converter a variável de ambiente continue de uma cadeia de caracteres em um booliano, permitindo que ele determine se deve continuar no erro ou não. Da mesma forma, ele converte a variável de ambiente time de uma cadeia de caracteres em um inteiro, definindo o tempo limite para o trabalho em minutos.

hashFiles

hashFiles(path)

Retorna um único hash para o conjunto de arquivos que corresponde ao padrão path. Você pode fornecer um único padrão path ou vários padrões path separados por vírgulas. O path é relativo ao diretório GITHUB_WORKSPACE e só pode incluir arquivos dentro do GITHUB_WORKSPACE. Essa função calcula uma hash SHA-256 individual para cada arquivo correspondente e, em seguida, usa esses hashes para calcular um hash SHA-256 final para o conjunto de arquivos. Se o padrão path não corresponder a nenhum arquivo, isso retornará uma cadeia de caracteres vazia. Para obter mais informações sobre SHA-256, confira "SHA-2".

Você pode usar a correspondência de padrão de caracteres para corresponder os nomes dos arquivos. A correspondência de padrões para hashFiles segue a correspondência de padrão glob e não diferencia maiúsculas de minúsculas no Windows. Para obter mais informações sobre caracteres de correspondência de padrão com suporte, confira a seção Padrões na documentação @actions/glob.

Exemplo com um padrão único

Corresponde a qualquer arquivo package-lock.json no repositório.

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

Exemplo com vários padrões

Cria um hash para qualquer package-lock.json e arquivos Gemfile.lock no repositório.

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

Funções de verificação de status

Você pode usar as funções de verificação de status a seguir como expressões em condicionais if. Uma verificação de status success() padrão é aplicada, a menos que você inclua uma dessas funções. Para obter mais informações sobre condicionais if, confira "Sintaxe de fluxo de trabalho para o GitHub Actions" e "Sintaxe de metadados para o GitHub Actions".

sucesso

Retorna true quando todas as etapas anteriores forem bem-sucedidas.

Exemplo de success

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

always

Faz com que a etapa sempre seja executada e retorna true, mesmo quando cancelada. A expressão always é melhor usada no nível da etapa ou em tarefas que você espera executar mesmo quando um trabalho é cancelado. Por exemplo, você pode usar always para enviar logs mesmo quando um trabalho é cancelado.

Aviso: evite usar always para qualquer tarefa que possa sofrer uma falha crítica, por exemplo, obtenção de fontes, caso contrário, o fluxo de trabalho pode travar até atingir o tempo limite. Se você quiser executar um trabalho ou uma etapa independentemente de seu êxito ou falha, use a alternativa recomendada: if: ${{ !cancelled() }}

Exemplo de always

if: ${{ always() }}

cancelled

Retorna true se o fluxo de trabalho foi cancelado.

Exemplo de cancelled

if: ${{ cancelled() }}

falha

Retorna true quando qualquer etapa anterior de um trabalho falha. Se você tiver uma cadeia de trabalhos dependentes, failure() retornará true se algum trabalho ancestral falhar.

Exemplo de failure

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

falha com condições

Você pode incluir condições extras para uma etapa a ser executada após uma falha, mas ainda precisa incluir failure() para substituir a verificação de status padrão de success() que é aplicada automaticamente a condições if que não contêm uma função de verificação de status.

Exemplo de failure com condições
steps:
  ...
  - name: Failing step
    id: demo
    run: exit 1
  - name: The demo step has failed
    if: ${{ failure() && steps.demo.conclusion == 'failure' }}

Filtros de objeto

Você pode usar a sintaxe * para aplicar um filtro e selecionar itens de uma coleção correspondente.

Por exemplo, considere uma matriz de objetos chamados fruits.

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

O filtro fruits.*.name retorna a matriz [ "apple", "orange", "pear" ].

Você também pode usar a sintaxe * em um objeto. Por exemplo, suponha que você tenha um objeto chamado 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"],
  },
}

O filtro vegetables.*.ediblePortions pode ser avaliado como:


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

Como os objetos não preservam a ordem, a ordem da saída não pode ser garantida.