Pular para o conteúdo

Um passo de workflow em DataForge

Saídas, variáveis, resumo, anotações, máscara e grupos — com Arcane.GitHub, e sem injeção.

Um passo de workflow conversa com o executor por arquivos (GITHUB_OUTPUT, GITHUB_ENV, GITHUB_STEP_SUMMARY) e por linhas mágicas na saída. Escrever isso à mão erra calado de dois jeitos: uma saída com quebra de linha vira duas (ou injeta uma variável), e uma mensagem com % é cortada. Arcane.GitHub escreve do jeito que o toolkit oficial escreve.

yaml
- name: relatorio
  id: relatorio
  run: dataforge run ci/relatorio.df
- name: usar
  run: echo "${{ steps.relatorio.outputs.cobertura }}"

Saída e resumo#

dataforge
adopt Arcane.GitHub as GH
adopt Arcane.OS as OS
adopt Arcane.IO as IO

// O executor aponta estas variaveis para arquivos. Aqui, para
// temporarios — e exatamente o que acontece dentro do job.
pasta := $"{OS.temp_dir()}/df-gh-{randint(100000, 999999)}"
IO.mkdir(pasta)
OS.set_env("GITHUB_OUTPUT", $"{pasta}/output")
OS.set_env("GITHUB_STEP_SUMMARY", $"{pasta}/resumo.md")

resultados := [
    {"suite": "pedidos", "passou": 42, "falhou": 0},
    {"suite": "estoque", "passou": 17, "falhou": 1}
]

// Uma saida multilinha: sem o delimitador aleatorio, a segunda linha
// viraria outra saida — ou outra variavel.
GH.saida("resumo", "pedidos: 42\nestoque: 17")
GH.saida("falhas", str(sum(resultados >> morph r: r["falhou"])))
GH.resumo("## Testes\n\n" + GH.tabela_markdown(resultados))

saidas := IO.read($"{pasta}/output")
assert "falhas<<ghadelimiter_" in saidas
assert "| estoque | 17 | 1 |" in IO.read($"{pasta}/resumo.md")

OS.unset_env("GITHUB_OUTPUT")
OS.unset_env("GITHUB_STEP_SUMMARY")
IO.remove_tree(pasta)
out "saidas escritas como o executor espera"

Anotações, máscara e grupos#

dataforge
adopt Arcane.GitHub as GH

// A anotacao aparece na linha do arquivo, no PR.
a := GH.anotacao("aviso", "cobertura caiu para 71%\nminimo: 80%", "src/regras.df", 12,
    titulo := "cobertura")
out a
assert a is "::warning file=src/regras.df,line=12,title=cobertura::cobertura caiu para 71%25%0Aminimo: 80%25"

// Nivel desconhecido e recusado: o executor ignoraria a linha calado.
monitor:
    GH.anotacao("fatal", "x")
    assert no
handle Error as e:
    out e.message

// Fora do Actions, o contexto vem vazio — e nao levanta.
c := GH.contexto()
out $"em actions: {c['em_actions']}"
FunçãoO que ela resolve
saida(nome, valor)multilinha com delimitador aleatório — o valor não injeta outra saída
exportar(nome, valor)variável para os passos seguintes; nome com = é recusado
resumo(md) + tabela_markdowna página do job; a | dentro de um valor é escapada
anotar / anotacao%, \n, : e , escapados
mascarar_no_log(segredo)linha a linha — o executor casa por linha
grupo(nome, acao)o ::endgroup:: sai mesmo se a ação falhar
contexto() / evento()repositório, commit, quem disparou, a carga do evento

Continue em Webhooks e Arcane.GitHub.