# Passos do Latchkey

> Os passos que o Latchkey publica para `uses: latchkey/<name>@<version>`: o que cada um faz, as entradas dele e como a versão é fixada.

Source: https://latchkey.dev/pt/documentation/steps

## Summary

- Um passo do Latchkey é escrito `uses: latchkey/<name>@<version>`, com as entradas em `with:`. O Latchkey nunca executa actions do GitHub.
- Toda versão é exata e nunca muda depois de publicada: uma mudança vira outra versão, como `latchkey/npm-publish@1.0.1` após `latchkey/npm-publish@1.0.0`. O plano registra o digest do passo, então uma reexecução roda os mesmos comandos.
- Os passos de cache hoje são `latchkey/cache-restore@1.0.0`, `latchkey/cache-restore@1.1.0`, `latchkey/cache-save@1.0.0` e `latchkey/cache-save@1.1.0`, e uma falha de cache ou um erro de cache nunca faz o job falhar.
- Os passos de artefato, Docker e AWS hoje são `latchkey/artifact-upload@1.0.0`, `latchkey/artifact-download@1.0.0`, `latchkey/docker-build-push@1.0.0` e `latchkey/aws-login@1.0.0`, e o passo falha se um envio ou download de artefato falhar.
- Os passos de setup e de npm hoje são `latchkey/setup-node@1.0.0`, `latchkey/setup-node@1.0.1`, `latchkey/setup-python@1.0.0`, `latchkey/setup-go@1.0.0`, `latchkey/setup-java@1.0.0` e as duas versões de `npm-publish` acima.

## Como um passo do Latchkey é executado

Quando o Latchkey compila o seu arquivo de workflow, ele copia os comandos do passo para o seu plano. O passo então roda como um passo do seu job, no runner do seu job e com o `env:` do seu job. O plano registra a versão e o digest do passo. Uma versão publicada nunca muda, então um commit sempre roda os mesmos comandos, inclusive numa reexecução.

`latchkey/setup-node` define NPM_CONFIG_PREFIX, `latchkey/setup-python` adiciona o `bin` do seu ambiente virtual ao fim do PATH e `latchkey/setup-java` define JAVA_HOME, cada um para todos os passos do job, inclusive os anteriores a ele. Uma variável que o seu arquivo de workflow define em um `env:`, seja o do workflow, o do job ou o de um passo, prevalece sobre uma que um passo do Latchkey define, e quando dois passos do Latchkey definem a mesma variável, vale o valor do passo posterior. Um passo pulado ainda definiria a sua variável, então esses três passos não aceitam `if:`. Para usar um deles só em algumas execuções, coloque-o em um job próprio e escreva o `if:` nesse job; para usar mais de uma versão, escolha a versão por uma matrix.

## Como escrever um

Um passo aceita `name:`, `uses:`, `with:`, `env:` e `if:`, e roda `run:` ou `uses:`, nunca os dois. Em `with:`, escreva cada entrada como um valor direto, a partir de um valor da matrix, como um `${{ needs.<job>.outputs.<name> }}` inteiro, ou como um mapa de branches que escolhe um valor direto pela branch da execução, como o `environment:` de um job pode fazer (veja [Arquivos de workflow](https://latchkey.dev/pt/documentation/workflow-files)). Um secret nunca vai em `with:`: o passo lê um secret do seu `env:`, como um passo `run:` faz.

Fixe uma versão exata. `@1`, `@latest` e a ausência de versão são recusados, e a recusa mostra as versões publicadas.

## latchkey/cache-restore

Restaura uma entrada do cache do Latchkey em um diretório. Uma falha de cache não restaura nada, e o job continua. Entradas: `key` (obrigatória; de 1 a 200 letras, dígitos, `.`, `_` ou `-`), `version` (obrigatória; de 1 a 64 dos mesmos caracteres; outra versão é outra entrada) e `into` (padrão `.`; um caminho dentro do workspace, ou `~` para o diretório home).

A versão 1.1.0 também aceita `hash-files`, descrito em `latchkey/cache-save`.

## latchkey/cache-save

Salva caminhos em uma entrada do cache do Latchkey. Uma entrada que já existe é mantida, e o job continua. Entradas: `key` e `version` (obrigatórias, como em `latchkey/cache-restore`), `from` (padrão `.`; o diretório a que os caminhos se referem, dentro do workspace ou do diretório home) e `path` (obrigatória; um ou mais caminhos dentro de `from`, separados por espaços).

Os dois passos usam o mesmo cache que `latchkey cache restore` e `latchkey cache save`: ele é restrito ao repositório e à branch, as outras branches leem o cache da branch padrão, e as entradas ficam guardadas por 14 dias. Um pull request de um fork não recebe nenhum cache, então seus passos não restauram nada e não salvam nada, e o job continua.

A versão 1.1.0 de cada um também aceita `hash-files`: padrões de arquivos rastreados no repositório, separados por espaços. O passo adiciona ao fim de `key` um hash do conteúdo deles como está no commit, então uma mudança no lockfile cria uma nova entrada, como o `hashFiles()` do GitHub faz em uma chave. Um padrão que não corresponde a nenhum arquivo rastreado ainda gera a mesma chave em toda execução.

## latchkey/setup-node

Troca o Node e o npm do runner por uma versão que a imagem do runner traz, para todos os passos seguintes. Entrada: `node-version` (obrigatória; como `22`, `22.23` ou `22.23.3`; uma versão major, ou major e minor, pega a versão mais nova desse tipo na imagem). Uma versão que a imagem não traz faz o passo falhar, e o passo mostra as versões que ela traz. A versão 1.0.1 também funciona em um job de um pull request de um fork, onde a versão 1.0.0 falha.

## latchkey/setup-python

Cria um ambiente virtual em `~/.latchkey/venv` a partir de uma versão do Python que a imagem do runner traz, e troca `python`, `python3`, `pip` e `pip3` por ele em todos os passos seguintes, então um `pip install` simples instala nele. Os comandos do ambiente, como um que um pacote instala, ficam no PATH depois dos da própria imagem, então, quando a imagem já tem um comando com esse nome, roda o da imagem. Entrada: `python-version` (obrigatória; uma versão menor, como `3.12` ou `3.13`; a imagem traz uma versão de cada). Uma versão que a imagem não traz faz o passo falhar, e o passo mostra as versões que ela traz. O Python da própria imagem não muda, e dentro do ambiente `pip install --user` é recusado.

## latchkey/setup-go

Troca o Go do runner por uma versão que a imagem do runner traz, para todos os passos seguintes. Entrada: `go-version` (obrigatória; como `1.25` ou `1.25.8`; uma versão minor pega o patch mais novo dela na imagem). Uma versão que a imagem não traz faz o passo falhar, e o passo mostra as versões que ela traz. Um job de um pull request de um fork não pode usar sudo, então o passo falha ali.

## latchkey/setup-java

Troca o Java do runner por um JDK Temurin que a imagem do runner traz, para todos os passos seguintes, e define JAVA_HOME para ele no job inteiro. Entrada: `java-version` (obrigatória; uma versão major como `17` ou `21`). Uma versão que a imagem não traz faz o passo falhar, e o passo mostra as versões que ela traz. Um job de um pull request de um fork não pode usar sudo, então o passo falha ali.

## latchkey/npm-publish

Publica o pacote em `directory` (padrão `.`) com o token em NODE_AUTH_TOKEN, que o passo lê do seu `env:`, definido a partir de um secret. Entradas: `tag` (padrão `latest`), `access` (`public` ou `restricted`), `dry-run` (padrão `false`) e `registry` (padrão `https://registry.npmjs.org/`). Sem token, o passo falha, a menos que `dry-run` seja true. Um job de um pull request de um fork não recebe nenhum secret, então ali o passo só pode rodar com `dry-run: true`, que não publica nada.

## latchkey/docker-build-push

Constrói a imagem em `context` (padrão `.`) a partir de `file` (padrão o seu `Dockerfile`) e a marca com cada referência em `tags` (obrigatória, separadas por espaços). Com `push: true` ele as envia, e com o padrão `false` carrega a imagem no Docker do runner para os passos seguintes. Com `username` definido, ele faz login em `registry` (padrão Docker Hub) com a senha de DOCKER_PASSWORD no `env:` do passo. Um job de um pull request de um fork não pode usar Docker, então o passo falha ali.

## latchkey/aws-login

Faz o login do job na AWS como uma role do IAM, com o token de identidade do Latchkey do job, para todos os passos seguintes. Entradas: `role-to-assume` (obrigatória; o ARN da role), `aws-region` (obrigatória), `role-session-name` (padrão `latchkey`) e `role-duration-seconds` (padrão `3600`; de 900 a 43200, e não mais que a sessão máxima da role). [A role precisa confiar no emissor do Latchkey para o seu repositório](https://latchkey.dev/pt/documentation/cloud-identity), com o público `sts.amazonaws.com`. Em uma execução de ensaio, e quando o pipeline do job está em ensaio, o token de identidade do job traz um `sub` que começa com `advisory:`, que uma confiança escrita para execuções reais não aceita. O AWS CLI e os SDKs dos passos seguintes leem a role da configuração AWS do job e buscam novas credenciais antes que as antigas expirem, então um job longo continua funcionando. Nenhuma chave entra no ambiente de nenhum passo, e o passo não define nenhuma variável de ambiente: a região está na configuração AWS, não em `AWS_REGION`. Uma ferramenta que lê credenciais da AWS só de variáveis de ambiente não recebe nenhuma deste passo. Um job de um pull request de um fork não tem token de identidade, então o passo falha ali.

## latchkey/artifact-upload

Envia caminhos como um único artefato desta execução, para os jobs que precisam deste job. Entradas: `name` (obrigatória; de 1 a 128 letras, dígitos, `.`, `_` ou `-`, e não `.` nem `..`), `from` (padrão `.`; o diretório a que os caminhos se referem, dentro do workspace ou do diretório home), `path` (obrigatória; um ou mais caminhos dentro de `from`, separados por espaços) e `include-hidden-files` (padrão `false`). O artefato guarda cada caminho como ele está sob `from`, então, para enviar o que um diretório contém, defina `from` como ele e `path` como `.`. Arquivos e diretórios cujo nome começa com um ponto ficam de fora, a menos que `include-hidden-files` seja true, e um envio que nomeia um deles, ou que não encontra nenhum arquivo regular, falha.

## latchkey/artifact-download

Baixa um artefato que um job nomeado em `needs:` deste job enviou e o extrai em um diretório. Entradas: `name` (obrigatória) e `into` (padrão `.`; um caminho dentro do workspace ou do diretório home, criado se ainda não existir). O artefato é conferido com o que foi enviado antes de qualquer extração, e um que contenha um caminho fora de `into` é recusado, e nada é extraído.

Os dois passos usam os mesmos artefatos que `latchkey artifact upload` e `latchkey artifact download`, com os mesmos nomes e limites, e um artefato fica guardado por 7 dias (veja [Arquivos de workflow](https://latchkey.dev/pt/documentation/workflow-files)). Ao contrário dos passos de cache, um envio ou download que falha faz o passo falhar. Um job de um pull request de um fork não pode usar artefatos, então os dois passos falham nele.

## O que o Latchkey recusa

O Latchkey recusa um arquivo em vez de rodá-lo com um passo que não consegue ler, e mostra a linha: um `uses:` fora de `latchkey/`, um nome de passo que ele não publica, uma versão que não é exata ou não foi publicada, uma entrada ausente, desconhecida ou fora da regra, `run:` e `uses:` no mesmo passo, e `with:` em um passo `run:`. Cada recusa diz o que escrever no lugar.

---

Latchkey runs CI/CD that repairs its own failures. Agent entry points: https://latchkey.dev/agent.txt, https://latchkey.dev/openapi.json, https://latchkey.dev/llms.txt
