Voltar ao catálogo
Season 24 14 Episódios 54 min 2026

GitHub Actions

Edição de 2026. Uma análise técnica e aprofundada ao GitHub Actions, abrangendo o seu modelo de execução, workflows avançados, controlo de acesso a ambientes, runners e segurança. Edição de 2026.

CI/CD DevOps
GitHub Actions
A Reproduzir
Click play to start
0:00
0:00
1
O Caso Empresarial para o GitHub Actions
Uma comparação executiva entre o GitHub Actions e ferramentas tradicionais de CI/CD, como o Azure DevOps e o GCP Cloud Build. Exploramos as vantagens arquitetónicas da automação orientada a eventos a viver lado a lado com o seu código-fonte.
5m 02s
2
O Modelo Mental de Execução
Uma análise técnica da hierarquia do GitHub Actions. Compreenda a relação crítica entre Workflows, Jobs, Steps e Actions.
3m 39s
3
Triggers Orientados a Eventos e Filtros
Uma análise aprofundada aos event triggers do GitHub Actions. Aprenda a configurar filtros precisos de path e branch para controlar exatamente quando os seus workflows são executados.
4m 07s
4
Avaliação de Estado com Variáveis e Contexts
Compreenda as diferenças críticas entre variáveis de ambiente e GitHub Contexts. Aprenda quando cada um é avaliado durante o ciclo de vida do workflow.
3m 35s
5
A Fronteira de Segurança: Secrets e GITHUB_TOKEN
Um olhar técnico sobre a gestão de secrets no GitHub Actions. Exploramos o GITHUB_TOKEN efémero e a hierarquia de secrets de repositório e de organização.
3m 52s
6
Otimização de Dados: Caching vs Artifacts
Aprenda a diferença exata entre Dependency Caching e Workflow Artifacts. Pare de atrasar as suas builds com o mecanismo de armazenamento errado.
4m 05s
7
Controlo de Fluxo com Concurrency
Domine o controlo de execução de workflows. Aprenda a usar a palavra-chave concurrency para cancelar execuções redundantes e evitar sobreposição de deployments.
3m 38s
8
Controlo de Deployments com Environments
Descubra como mapear os seus workflows do GitHub Actions para alvos de deployment externos usando Environments para impor aprovações manuais e isolar secrets.
4m 14s
9
Acesso Cloud Sem Palavra-passe via OIDC
Elimine credenciais cloud de longa duração dos seus repositórios. Aprenda a usar o OpenID Connect (OIDC) para autenticar o GitHub Actions de forma segura com a AWS, Azure e GCP.
4m 19s
10
Escalar Pipelines DRY
Compare Reusable Workflows e Composite Actions. Aprenda qual o mecanismo a escolher ao padronizar as suas pipelines de CI/CD em toda a empresa.
3m 51s
11
Criar Custom Actions: Docker vs JavaScript
Assuma o controlo da sua pipeline construindo Custom Actions. Exploramos os compromissos de desempenho e compatibilidade entre actions em JavaScript e em contentores Docker.
3m 16s
12
Gestão de Frota: Hosted vs Self-Hosted Runners
Navegue pelas fronteiras dos runners do GitHub. Aprenda quando deve depender de máquinas alojadas pelo GitHub (GitHub-hosted) e quando a sua arquitetura exige Self-Hosted runners.
3m 30s
13
Escala Kubernetes: Actions Runner Controller
Descubra como o Actions Runner Controller (ARC) orquestra frotas de runners efémeros e com auto-scaling nativamente nos seus clusters Kubernetes.
3m 28s
14
Integridade da Cadeia de Fornecimento com Attestations
Proteja a sua cadeia de fornecimento de software. Aprenda a gerar artifact attestations e proveniência infalsificáveis diretamente a partir dos seus workflows.
3m 40s

Episódios

1

O Caso Empresarial para o GitHub Actions

5m 02s

Uma comparação executiva entre o GitHub Actions e ferramentas tradicionais de CI/CD, como o Azure DevOps e o GCP Cloud Build. Exploramos as vantagens arquitetónicas da automação orientada a eventos a viver lado a lado com o seu código-fonte.

Download
Olá, daqui é o Alex do DEV STORIES DOT EU. GitHub Actions, episódio 1 de 14. A maioria das builds empresariais são tratadas como um detalhe de última hora numa ferramenta completamente separada. Fazes push do código, acontece um context switch, e esperas que um webhook dispare corretamente num servidor remoto noutro lugar qualquer. O caso empresarial do GitHub Actions resolve esta lacuna ao mover a execução da tua pipeline diretamente para junto do teu source code. O erro comum é tratar o GitHub Actions estritamente como uma ferramenta de CI/CD, como se fosse apenas um substituto moderno do Jenkins. Chama-lhe o que ele realmente é. É um motor de automação flexível, event-driven, profundamente integrado no teu repositório. Responde a praticamente qualquer mudança de estado dentro da plataforma de controlo de versões. Olha para um setup empresarial padrão a usar ferramentas como o GCP Cloud Build ou o Azure DevOps. O source code vive no GitHub, mas a execução acontece noutro lugar. Isto exige a gestão de service accounts multiplataforma, a manutenção de webhooks frágeis e a sincronização de controlos de acesso entre vários fornecedores. Quando uma pipeline falha, os developers saem do seu repositório, fazem login numa consola de cloud separada e vasculham logs desconectados do seu pull request. A proximidade ao código elimina esta fricção. Quando o teu motor de automação é construído diretamente na plataforma de controlo de versões, eliminas a taxa de integração. A identidade do utilizador, as regras de branch protection, e o contexto da alteração de código são compreendidos nativamente pela instância de compute que corre a tua pipeline. Pensa numa pipeline tradicional numa ferramenta de cloud build separada. Normalmente, fica à escuta de um commit de código, faz pull do source, faz a build de um artifact, e reporta um status simples de pass ou fail de volta ao repositório. A sua visão do mundo limita-se à compilação de código e ao deploy. Uma GitHub Action opera numa escala muito maior. Como entende nativamente os eventos do repositório, podes criar um workflow que faz trigger no momento exato em que um pull request é aberto. Numa única run contínua, pode ler o payload do evento, atribuir os senior engineers certos como reviewers com base nos ficheiros específicos que mudaram, executar um linter, e publicar quaisquer falhas de sintaxe diretamente como comentários inline nas linhas de código exatas. O developer resolve os problemas sem nunca sair da vista do pull request. Automatizas o workflow em si, não apenas o artifact da build. Do ponto de vista arquitetónico, isto transforma o teu repositório de um volume de storage passivo num controller ativo. Deixas de automatizar apenas os teus deploys e passas a automatizar a tua governance operacional. Se uma issue for marcada com uma label crítica, uma action pode provisionar automaticamente uma base de dados de testing temporária. Se uma vulnerabilidade de segurança for sinalizada por um scan de dependências automatizado, uma action pode abrir instantaneamente um ticket de tracking, atribuir à equipa de segurança, e fazer ping ao teu sistema de chat interno. Tudo utiliza exatamente a mesma infraestrutura de compute subjacente. Numa grande organização, podes definir estes workflows centralmente e partilhá-los por centenas de repositórios. Se a tua equipa de segurança atualizar a política de scanning de containers obrigatória, eles atualizam uma action central. Cada repositório que chama essa action herda imediatamente o novo requisito de segurança, sem que as equipas de produto individuais precisem de reescrever os seus scripts de pipeline. Esta centralização proporciona uma enorme vantagem para as equipas de platform engineering. Aqui está o insight principal. A arquitetura empresarial debate-se constantemente com o tool sprawl. Cada nova ferramenta de pipeline adiciona carga cognitiva, exige manutenção dedicada e cria mais uma surface area para políticas de segurança. Ao consolidares a tua execution layer diretamente no GitHub, padronizas o comportamento de cada repositório. Exatamente a mesma infraestrutura que faz o deploy dos teus microsserviços de produção também gere a manutenção do teu repositório. A grande vantagem arquitetónica do GitHub Actions não é ter build agents mais rápidos ou melhor caching. É que remove a fronteira entre o workflow do developer e o sistema de continuous integration. Se achas estes episódios úteis e queres apoiar o programa, podes procurar por DevStoriesEU no Patreon. Obrigado por ouvirem, happy coding a todos!
2

O Modelo Mental de Execução

3m 39s

Uma análise técnica da hierarquia do GitHub Actions. Compreenda a relação crítica entre Workflows, Jobs, Steps e Actions.

Download
Olá, daqui é o Alex da DEV STORIES DOT EU. GitHub Actions, episódio 2 de 14. Um workflow não é apenas um script simples que corre de cima para baixo. É uma máquina de estados paralelizada que distribui o teu código por várias máquinas virtuais exatamente ao mesmo tempo. Se escreveres a tua configuração à espera de um processo contínuo, os teus dados vão desaparecer a meio. Compreender o modelo mental de execução evita isto. No nível mais alto está o workflow. Este é um processo automatizado configurável, definido num ficheiro YAML dentro do teu repositório. Contém o plano do que deve acontecer quando é acionado. Um workflow em si não executa código diretamente. Orquestra o nível imediatamente abaixo. Um workflow contém um ou mais jobs. É aqui que os limites físicos de execução são definidos. Por defeito, cada job num workflow corre em paralelo. Se definires um job de build e um job de test, o GitHub cria uma máquina virtual separada, chamada runner, para cada job. Eles começam exatamente ao mesmo tempo. Não sabem nada um sobre o outro. O job de build corre no runner A, e o job de test corre no runner B. Como são executados em máquinas virtuais completamente diferentes, não partilham o filesystem, variáveis de ambiente ou memória. Dentro de um job, o modelo de execução muda completamente. Um job é composto por uma sequência de steps. Enquanto os jobs correm em paralelo em máquinas diferentes, os steps correm sequencialmente exatamente na mesma máquina. O step um termina antes de o step dois começar. Como correm no mesmo runner, os steps partilham dados. No nosso job de build, o step um pode fazer o download do código da tua aplicação. O step dois compila-o. O step três empacota-o. Como estes steps acontecem na mesma máquina virtual, o step dois lê nativamente os ficheiros descarregados pelo step um. Isto levanta um ponto comum de confusão. As pessoas frequentemente confundem steps e actions. Um step não é uma action. Um step é simplesmente uma unidade de execução dentro de um job. É um slot na tua sequência. Podes preencher esse slot de duas maneiras. Podes escrever um comando shell puro, ou podes chamar uma action. Uma action é um bloco de código empacotado e reutilizável, desenhado para executar uma tarefa complexa específica, como configurar um ambiente de linguagem. A action é o payload reutilizável. O step é o contentor que a guarda dentro da sequência do job. Vamos olhar novamente para o nosso cenário de build e test. O workflow começa. Dois runners arrancam simultaneamente. No runner de build, os steps são executados um a um. O primeiro step chama uma action de checkout para ir buscar o repositório. O segundo step corre um comando shell para compilar o código. Estes steps partilham o espaço em disco local sem problemas. Entretanto, no runner de test, uma sequência de steps completamente diferente está a correr de forma isolada. Se o teu job de test precisar do output compilado do job de build, não pode simplesmente procurar no disco rígido. O job de test está num servidor diferente. Aqui está o ponto chave. O limite de um job é o limite físico da máquina virtual, o que significa que escrever um workflow de GitHub Actions é, na verdade, um exercício de mapeamento de infraestrutura. Obrigado por estares aí. Espero que tenhas aprendido algo novo.
3

Triggers Orientados a Eventos e Filtros

4m 07s

Uma análise aprofundada aos event triggers do GitHub Actions. Aprenda a configurar filtros precisos de path e branch para controlar exatamente quando os seus workflows são executados.

Download
Olá, daqui é o Alex da DEV STORIES DOT EU. GitHub Actions, episódio 3 de 14. É feito o push de um único commit automatizado para o teu repositório. Esse commit faz trigger a um workflow. Esse workflow faz outro commit, que faz trigger ao workflow novamente. Em poucos minutos, queimaste centenas de run minutes num infinite loop acidental. A forma de evitares isto, e de controlares exatamente quando os teus workflows executam, é através de Event-Driven Triggers e Filters. Qualquer workflow de GitHub Actions começa com a keyword on. Isto diz ao GitHub quais os events que devem acordar o teu workflow. Podes especificar um único event, como um push, ou múltiplos events num array. Mas os events nem sempre são triggers simples. Alguns events, como issues ou pull requests, têm múltiplos activity types. Quando uma issue é aberta, editada ou fechada, dispara o mesmo base event. Se escreveres apenas que um workflow corre em issues, ele vai correr para todas essas atividades. Para seres preciso, especificas os activity types exatos. Podes dizer ao GitHub para correr o workflow apenas quando uma issue é aberta, ignorando edições ou fechos. Isto poupa run minutes e evita processamento desnecessário. Os activity types tratam do que aconteceu, mas os branch e path filters tratam de onde aconteceu. Quando fazes trigger a um workflow num push ou pull request, normalmente não queres que ele corra em todas as branches. Usas branch filters para focar em destinos específicos, como a branch main ou release branches. Também podes filtrar por paths. Se um developer corrigir uma gralha num ficheiro readme, não precisas de correr a tua test suite inteira. Os path filters permitem-te incluir ou excluir ficheiros e diretórios específicos. Aqui está o ponto chave. Quando misturas path filters positivos e negativos, a ordem em que os escreves importa. Um filtro positivo diz ao workflow para correr se um path específico mudar. Um filtro negativo, denotado por um ponto de exclamação, diz ao workflow para ignorar alterações num path. O GitHub avalia-os de cima para baixo. Se colocares um filtro negativo depois de um filtro positivo, o filtro negativo sobrepõe-se ao positivo para quaisquer ficheiros correspondentes. Vamos pôr isto em prática. Queres fazer trigger a uma build sempre que é feito push de código para a branch main, mas queres poupar dinheiro ignorando alterações que afetam apenas a documentação. Abaixo da keyword on, especificas o event de push. Abaixo disso, defines um branch filter para a main. A seguir, adicionas um paths filter. Podes começar com um filtro positivo para tudo, usando um wildcard. Logo abaixo, adicionas um filtro negativo para a pasta docs, focando especificamente em ficheiros markdown. Se um commit modificar apenas um ficheiro markdown na pasta docs, o workflow continua adormecido. Se um commit modificar um ficheiro python e um ficheiro markdown, o workflow corre porque o ficheiro python faz trigger ao filtro positivo. Agora, voltando àquele infinite loop. Quando o teu workflow corre, o GitHub fornece uma credencial temporária chamada GitHub Token para autenticar contra o repositório. By design, quaisquer events que sofram trigger usando este token específico não vão criar novas workflow runs. Isto é um mecanismo de segurança built-in para evitar recursive loops. No entanto, se o teu workflow usar um Personal Access Token para fazer commit de código ou push de tags, essa rede de segurança desaparece. O novo commit vai fazer trigger a outra workflow run, que faz outro commit, criando um infinite loop. Se tiveres mesmo de usar um Personal Access Token, tens de ser extremamente disciplinado com os teus branch e path filters para garantir que o commit automatizado não cumpre as condições de trigger para o workflow. A forma mais eficaz de otimizar os teus custos de computação não é escrever código mais rápido, mas simplesmente garantir que os teus workflows só correm quando têm absolutamente de o fazer. Obrigado por ouvirem, happy coding a todos!
4

Avaliação de Estado com Variáveis e Contexts

3m 35s

Compreenda as diferenças críticas entre variáveis de ambiente e GitHub Contexts. Aprenda quando cada um é avaliado durante o ciclo de vida do workflow.

Download
Olá, daqui fala o Alex do DEV STORIES DOT EU. GitHub Actions, episódio 4 de 14. Tentas usar uma variável de ambiente do runner para ditar se um job deve arrancar, e o teu pipeline falha antes sequer de iniciar uma máquina. Tens a certeza de que a variável existe, mas o GitHub age como se estivesse vazia. O problema não é a tua variável, é o teu timing. Para corrigir isto, precisamos de falar sobre State Evaluation com Variáveis e Contextos. No GitHub Actions, o estado do teu workflow é avaliado em duas fases completamente separadas, que acontecem em dois locais totalmente diferentes. Esta é a principal diferença entre um Contexto e uma Variável de Ambiente. Vamos olhar para os Contextos primeiro. Os Contextos são conjuntos de informação avaliados diretamente pelo GitHub, antes sequer de o teu workflow ser enviado para um runner. Eles contêm dados sobre a run do workflow, o repositório, o evento de webhook que disparou a run, e o utilizador que a iniciou. Como o GitHub avalia os Contextos imediatamente, podes usá-los para controlar a estrutura do teu pipeline. Acedes a um Contexto usando uma sintaxe de expressão específica, normalmente um cifrão seguido de chaves duplas contendo o nome do contexto. Por outro lado, as variáveis de ambiente default são avaliadas mais tarde, na própria máquina do runner que executa o teu job. Quando o runner arranca, define automaticamente várias variáveis de ambiente default, como o nome do repositório ou a branch atual. Acedes a estas variáveis exatamente como farias num script normal de bash ou PowerShell. Também podes definir as tuas próprias variáveis de ambiente usando a key env no teu ficheiro de workflow. Podes associar a key env a um workflow inteiro, a um único job, ou a um step específico. Aqui está o ponto chave. O ciclo de vida dita o que podes usar e onde. Um erro comum é tentar usar uma variável de ambiente do runner dentro de uma condicional if ao nível do job. Se disseres a um job para correr apenas se uma variável de ambiente de bash específica for igual a um certo valor, o workflow vai falhar. O runner ainda não arrancou. A máquina não existe, logo a variável de ambiente não existe. Para tomar decisões antes de o runner arrancar, tens de usar um Contexto. Vamos ver um cenário prático. Queres que um job de deploy corra apenas se o código for merged para a branch main. Ao nível do job, escreves uma condicional if. Usas a expressão de contexto para verificar se o contexto github ponto ref é igual à string refs barra heads barra main. O GitHub avalia isto instantaneamente. Se for true, o GitHub provisiona um runner e envia-lhe o job. Assim que o job estiver no runner e os teus steps começarem a executar, passas para as variáveis de ambiente. Dentro de um step de script bash nesse mesmo job, podes precisar de saber o nome da branch para fazer tag a um artifact de build. Aqui, simplesmente digitas um cifrão seguido de GITHUB underscore REF. O runner lê isto do ambiente local do seu sistema operativo. Estás a referenciar exatamente o mesmo dado, o nome da branch, mas estás a aceder-lhe através de mecanismos completamente diferentes, dependendo de onde a execução vive neste momento. Os Contextos encaminham o workflow nos servidores do GitHub. As variáveis de ambiente conduzem os scripts de execução no runner. Se alguma vez deres por ti a lutar contra variáveis vazias na lógica do teu workflow, pergunta-te se a máquina que está a avaliar essa lógica já arrancou. Como sempre, obrigado por ouvires. Vemo-nos no próximo episódio.
5

A Fronteira de Segurança: Secrets e GITHUB_TOKEN

3m 52s

Um olhar técnico sobre a gestão de secrets no GitHub Actions. Exploramos o GITHUB_TOKEN efémero e a hierarquia de secrets de repositório e de organização.

Download
Olá, daqui fala o Alex da DEV STORIES DOT EU. GitHub Actions, episódio 5 de 14. Os developers frequentemente criam Personal Access Tokens de longa duração para tarefas básicas do repositório, deixando credenciais permanentes na sua codebase. Mas, para a maioria das interações com o GitHub, não precisas de criar um token de todo — existe um token seguro e efémero à tua espera em cada job. Este é o foco do episódio de hoje: A Security Boundary: Secrets e GITHUB_TOKEN. Quando fazes trigger a um workflow, o GitHub provisiona automaticamente um secret único chamado GITHUB_TOKEN. Este não é um Personal Access Token normal. Funciona como um installation access token de uma GitHub App de curta duração. Existe exclusivamente durante a duração do job do workflow. No momento em que o job termina, ou após um máximo de 24 horas, o token expira e torna-se completamente inútil. Um erro comum é gerar um Personal Access Token permanente apenas para que um workflow adicione uma label a uma issue ou publique um comentário num pull request. Isto expande a tua superfície de ataque desnecessariamente. O GITHUB_TOKEN built-in já possui as permissões necessárias para interagir com o repositório que fez trigger ao workflow. Se o teu job precisar de adicionar uma label a uma issue, passas este token built-in para o step que executa a API call. Nenhuma credencial permanente é criada, armazenada ou exposta. Isto cobre a interação com o próprio GitHub. Mas o teu workflow inevitavelmente precisará de comunicar com o mundo exterior. É aqui que entram os secrets encriptados personalizados. Quando crias um secret personalizado, ele não fica armazenado em plain text num servidor do GitHub. O valor é encriptado localmente usando uma sealed box do Libsodium antes mesmo de ser transmitido. A encriptação baseia-se em public-key cryptography. Quando adicionas um secret pela interface web ou API, o GitHub fornece uma public key. O teu client usa essa chave para selar a caixa. Apenas a máquina virtual isolada do runner possui a private key correspondente necessária para abrir essa caixa, e apenas desencripta o payload no momento exato em que o job é executado. Podes definir estes secrets encriptados a diferentes níveis, dependendo da tua arquitetura. Secrets ao nível do repositório aplicam-se a uma única codebase. Secrets ao nível da organização permitem-te partilhar uma única credencial, como uma password de uma base de dados de produção, por vários repositórios. Isto centraliza a gestão de credenciais, mas exige um controlo rigoroso. Os secrets de organização usam access policies, nas quais defines explicitamente quais os repositórios que têm permissão para ler o secret. Vamos aplicar isto a um cenário concreto. Digamos que tens uma password de base de dados ao nível da organização necessária para um step de migração de base de dados. Não queres que esta password esteja acessível a todo o workflow. O GitHub Actions impõe uma security boundary rigorosa aqui. Os secrets não são injetados automaticamente no environment de cada step. Tens de mapear explicitamente o secret para uma environment variable no step específico que o requer. Ao escrever o ficheiro de workflow, acedes ao valor encriptado usando uma context reference específica, chamando-o a partir do objeto secrets, e atribui-lo a uma environment variable local. Como o mapeaste explicitamente, o step anterior à migração não consegue ver a password, e o step seguinte também não. Aqui está o insight principal. A segurança na automação tem a ver com minimizar o lifespan e limitar o scope. Utiliza o GITHUB_TOKEN efémero para ações internas do repositório, para evitar a gestão de credenciais permanentes, e mapeia secrets encriptados estritamente apenas para os steps individuais que exigem acesso externo. Ficamos por aqui neste episódio. Até à próxima!
6

Otimização de Dados: Caching vs Artifacts

4m 05s

Aprenda a diferença exata entre Dependency Caching e Workflow Artifacts. Pare de atrasar as suas builds com o mecanismo de armazenamento errado.

Download
Olá, daqui é o Alex da DEV STORIES DOT EU. GitHub Actions, episódio 6 de 14. Configuraste um workflow multi-job e, para garantir que o segundo job tem tudo o que precisa, agrupaste toda a tua pasta de dependências e passaste-a para a frente. Mas, de repente, a tua build demora mais cinco minutos e o teu uso de storage dispara. O problema é uma confusão fundamental entre dois mecanismos de dados distintos, e é exatamente isso que este episódio aborda: Otimização de Dados: Caching vs Artifacts. Vamos esclarecer a confusão já. Tanto o caching como os artifacts movem ficheiros entre os teus runners de GitHub Actions, mas resolvem problemas completamente diferentes. Pensa nos artifacts como aquilo que o teu workflow produz. Pensa no caching como aquilo que o teu workflow consome. Se inverteres estes papéis, vais criar silenciosamente um bottleneck em todo o teu pipeline. Os artifacts são ficheiros gerados que queres guardar depois de um job terminar. Pode ser um binário compilado, um relatório de test coverage, ou um zip da tua diretoria de build final. Eles existem por dois motivos principais. Primeiro, para te permitir fazer o download do output final do teu workflow assim que ele terminar. Segundo, para passar dados gerados entre diferentes jobs dentro da exata mesma run do workflow. Como cada job corre numa máquina virtual nova, quaisquer ficheiros criados no job um perdem-se instantaneamente quando esse job termina, a não ser que faças o upload deles explicitamente. Ao usares a action de upload artifact, guardas esses ficheiros no storage do GitHub. Depois, o job dois usa a action de download artifact para os puxar para o seu próprio workspace limpo. Agora, compara isso com o dependency caching. O caching é puramente uma otimização de performance desenhada para acelerar o teu workflow entre diferentes runs ao longo do tempo. Quando fazes a build de software, normalmente fazes o download de milhares de dependências de terceiros, como packages do NPM ou pip. Ir buscar isto pela rede em cada run é lento. Em vez de fazeres o download de dependências novas de cada vez, a action de cache guarda a tua pasta de dependências nos servidores de cache. Ela atribui a esta cache uma key única, quase sempre baseada no hash do teu lock file. Na run do workflow de amanhã, o GitHub verifica se o lock file corresponde a uma key existente. Se corresponder, restaura a pasta diretamente no teu runner em segundos, ignorando completamente o package registry. Aqui está o ponto chave. O maior erro que podes cometer é usar a action de upload artifact para mover uma pasta de dependências enorme, como o node modules, entre jobs. Os artifacts processam dados fazendo zip, upload, download e unzip. Fazer isto com dezenas de milhares de pequenos ficheiros de texto adiciona uma latência de rede enorme ao teu run time e consome as quotas de storage da tua conta. Os artifacts não foram feitos para velocidade bruta; foram feitos para transferência segura de dados e para manter um registo permanente. As caches, por outro lado, são altamente otimizadas para puxar dependency trees pesadas rapidamente, e expiram e apagam-se automaticamente para poupar espaço. Imagina um pipeline adequado que usa ambos corretamente. Tens um workflow com um job de build e um job de deploy. No job de build, o teu primeiro step usa a action de cache para restaurar instantaneamente as tuas dependências do NPM da run de ontem. O teu código compila rapidamente, produzindo um binário final da aplicação. A seguir, usas a action de upload artifact para guardar apenas esse único ficheiro binário. O job de build termina, e o runner é destruído. O job de deploy arranca num novo runner. Não precisa da cache, nem precisa das dependências do NPM. Usa simplesmente a action de download artifact para agarrar no binário compilado que acabaste de gerar, e depois faz push para o teu servidor de produção. O caching é um atalho descartável para coisas de que fazes download, enquanto os artifacts são o hand-off essencial para coisas que crias. Obrigado por estares aí. Espero que tenhas aprendido algo novo.
7

Controlo de Fluxo com Concurrency

3m 38s

Domine o controlo de execução de workflows. Aprenda a usar a palavra-chave concurrency para cancelar execuções redundantes e evitar sobreposição de deployments.

Download
Olá, daqui é o Alex da DEV STORIES DOT EU. GitHub Actions, episódio 7 de 14. Um developer faz push de três commits seguidos para um pull request aberto em cinco minutos. Se o teu servidor de CI estiver a correr três test suites redundantes, estás a queimar dinheiro. Precisas de uma forma de dizer ao sistema que só o código mais recente interessa, e é exatamente isso que o controlo de fluxo com concurrency resolve. Por defeito, o GitHub Actions corre os workflows acionados em paralelo. Se fizeres push cinco vezes, ele arranca com cinco runners independentes. Para checks básicos, isto desperdiça minutos de runner. Para deployments, é ativamente perigoso. Se duas runs do workflow tentarem fazer deploy para o mesmo ambiente de staging em simultâneo, crias uma race condition. O commit mais antigo pode até acabar o deploy depois do mais recente, substituindo os teus updates e deixando o teu ambiente num estado desatualizado. Resolves isto usando a keyword concurrency. Podes aplicá-la ao nível de topo de todo o workflow ou restringi-la a um job específico. O mecanismo depende inteiramente de concurrency groups. Um concurrency group é simplesmente um nome em string que tu defines. Se duas runs partilharem exatamente o mesmo nome de grupo, o GitHub impõe limites de concurrency entre elas. Muitas pessoas cometem o erro de fazer hardcode desta string. Se definires o nome do grupo apenas como a palavra deploy, então fazer push para a tua branch de testing vai cancelar um deploy ativo na tua branch principal de produção. O nome do grupo tem de ser dinâmico. Constróis isso usando variáveis de contexto, como a referência da branch atual. Se nomeares o grupo usando o número do pull request, então os limites de concurrency aplicam-se apenas aos pushes dentro desse pull request específico. A tua branch principal permanece completamente inalterada. Quando um novo workflow é acionado, o GitHub verifica se já existe uma run ativa para esse concurrency group. Se existir, o comportamento por defeito é colocar a nova run num estado pendente. Fica à espera numa queue. Aqui está o detalhe crucial. A queue só guarda um job pendente. Se uma terceira run for acionada enquanto a primeira está a correr e a segunda está pendente, a segunda run é ejetada da queue. Só a run mais recente é que fica à espera. Esperar é mais seguro para deployments, mas para testes de pull requests, esperar continua a consumir tempo desnecessário. É aqui que entra a configuração cancel-in-progress. É uma flag booleana que adicionas debaixo da definição do teu concurrency group. Quando defines o cancel-in-progress para true, mudas o comportamento de colocar em queue para terminar. Voltemos ao developer a fazer push de três commits seguidos. O primeiro push aciona uma test suite. Dois minutos depois, faz push novamente. Como definiste o concurrency group para o nome da branch e ativaste o cancel-in-progress, o GitHub vê a nova run, termina instantaneamente a test suite ativa para o primeiro commit, e começa a testar o segundo commit. Quando o terceiro push acontece um minuto depois, termina a segunda run e inicia a terceira. O developer continua a receber o pass ou fail final, mas tu só pagaste para correr os testes uma vez. Os controlos de concurrency transformam os teus CI pipelines de um sistema reativo que executa cegamente cada trigger, num sistema state-aware que só gasta recursos no código que realmente interessa. Obrigado por ouvirem, happy coding a todos!
8

Controlo de Deployments com Environments

4m 14s

Descubra como mapear os seus workflows do GitHub Actions para alvos de deployment externos usando Environments para impor aprovações manuais e isolar secrets.

Download
Olá, daqui é o Alex da DEV STORIES DOT EU. GitHub Actions, episódio 8 de 14. As credenciais da tua base de dados de production nunca devem estar acessíveis a um pull request aleatório de uma feature branch. No entanto, se todos os teus secrets estiverem armazenados ao nível do repository, qualquer workflow pode potencialmente ir buscá-los. Resolver esta falha de segurança é exatamente o motivo pelo qual precisas de Gating Deployments com Environments. Primeiro, precisamos de esclarecer um equívoco comum. Um environment no GitHub Actions não é um servidor físico. O GitHub não cria uma máquina virtual ou uma cloud instance chamada production para ti. Um environment é puramente uma fronteira lógica configurada nas settings do teu repositório de GitHub. Atua como um gatekeeper, controlando quando um job tem permissão para correr e que dados esse job pode ver. A principal razão para esta feature existir é garantir a release governance e proteger dados sensíveis. Quando crias um environment, podes associar secrets e variables específicas diretamente a ele. Podes criar um environment chamado staging e outro chamado production. Cada um recebe o seu próprio conjunto único de API keys, guardadas exatamente com o mesmo nome de variable. No teu ficheiro de workflow, ligas um job específico a um environment simplesmente indicando o seu nome. Quando o workflow corre, o job que referencia o environment de staging recebe as keys de staging. O job que referencia o environment de production recebe as live keys. Isto isola completamente os teus dados sensíveis. Um job a correr numa feature branch não consegue ler as keys de production porque não corre no contexto do environment de production. Mas isolar secrets é apenas metade do poder dos environments. A outra metade são as protection rules. Estas rules atuam como gates rigorosas no teu deployment pipeline. A protection rule mais comum é um required reviewer. Vejamos como isto flui num cenário real. Tens um workflow que faz o build da tua aplicação e faz o deploy automático para staging. Esse job tem sucesso. O job imediatamente a seguir no workflow está configurado para fazer deploy para production, e referencia o teu environment de production. Se tiveres uma rule de required reviewer configurada para esse environment, o workflow para logo ali. O job entra em pausa. Não é despachado para um runner, e as API keys de production permanecem trancadas em segurança. O GitHub envia uma notificação ao gestor ou equipa designada, a indicar que um deployment está à espera. O workflow vai ficar neste estado pendente até que seja tomada uma ação. Só quando o gestor clica em approve na interface do GitHub é que a gate se abre. Nesse exato momento, o job é despachado para um runner disponível, os secrets de production são desencriptados e injetados, e o script de deployment é executado. Podes sobrepor outras protection rules às aprovações manuais. Uma opção é um wait timer, que força um job a atrasar-se por um número específico de minutos antes de começar. Isto dá-te uma margem para cancelar um rollout se notares um pico nas taxas de erro nos teus monitoring dashboards logo após um deployment em staging. Também podes configurar deployment branches. Isto restringe o environment para que apenas aceite jobs a correr a partir de branches específicas, como a tua main branch ou release tags específicas. Se um developer tentar forçar um deployment job para production a partir de uma bugfix branch aleatória, a gate do environment simplesmente rejeita a run. Aqui está o ponto chave. Os environments desacoplam as tuas mecânicas de deployment do teu access control. O teu ficheiro de workflow descreve os passos exatos necessários para fazer o deploy do teu código, mas as settings de environment dentro do GitHub ditam quem tem a autoridade para permitir que isso aconteça e que secrets são desbloqueados quando isso ocorre. Se gostas destes deep dives técnicos, podes apoiar o programa procurando por DevStoriesEU no Patreon. Obrigado por ouvirem, e happy coding a todos!
9

Acesso Cloud Sem Palavra-passe via OIDC

4m 19s

Elimine credenciais cloud de longa duração dos seus repositórios. Aprenda a usar o OpenID Connect (OIDC) para autenticar o GitHub Actions de forma segura com a AWS, Azure e GCP.

Download
Olá, daqui é o Alex do DEV STORIES DOT EU. GitHub Actions, episódio 9 de 14. A credencial de cloud mais segura é aquela que expira cinco minutos depois do teu deploy terminar. No entanto, muitas equipas ainda copiam chaves de administrador de longa duração para as settings do repositório, na esperança de que nunca vazem. Hoje, vamos resolver isso ao analisar o acesso à cloud sem password via OIDC. Historicamente, ligar um workflow do GitHub a um cloud provider significava gerar uma access key na AWS, Google Cloud ou Azure, e guardá-la como um GitHub Secret de longa duração. Se esse secret vazasse, qualquer pessoa poderia usá-lo a partir de qualquer lado até que um administrador o revogasse manualmente. As pessoas muitas vezes pensam que o OpenID Connect, ou OIDC, é apenas um novo tipo de secret que colas no teu repositório. Não é. O OIDC substitui completamente os secrets armazenados. É um protocolo que gera um token criptográfico dinâmico on the fly para provar a identidade do workflow ao teu cloud provider. O GitHub atua como um Identity Provider OIDC. Quando um workflow corre, pode pedir ao GitHub para emitir um JSON Web Token, ou JWT. Para que isto aconteça, tens de adicionar uma permissão específica ao teu ficheiro de workflow. Configuras o bloco de permissions para permitir write access para o ID token. Isto diz ao GitHub que o workflow está autorizado a gerar uma credencial de identidade. Aqui está o ponto crucial. Este token não concede acesso por si só. É simplesmente um documento assinado digitalmente que contém claims. Claims são pedaços de metadata que declaram factos verificáveis sobre o workflow que está a correr. O token inclui o nome do repositório, a organização, a branch, o environment, e o evento que fez trigger à run. Como o GitHub assina o token criptograficamente, o teu cloud provider pode confiar nestas claims. Isto forma a base de um zero-trust deploy. Vamos olhar para um job de deploy a fazer push de uma imagem para um AWS Elastic Container Registry. O workflow arranca e pede um token OIDC ao GitHub. O token é gerado, contendo claims que verificam que vem da main branch do teu repositório de backend. O workflow envia então este token para a AWS. A AWS primeiro verifica a assinatura digital para garantir que o token veio realmente do GitHub. A seguir, lê as claims. Compara estas claims com uma trust policy rigorosa que definiste anteriormente. A policy pode dizer que apenas aceita tokens do teu repositório específico e apenas se o workflow estiver a correr na main branch. Como as claims correspondem, a AWS aceita o token. A AWS não devolve uma key permanente. Em vez disso, emite um access token temporário. Este token pode ser válido por apenas quinze minutos. O teu workflow usa esta credencial temporária para fazer push da imagem do container para o registry. Quando o job termina, a credencial expira. Não há nada para fazer rotate, e nada guardado no GitHub que um atacante possa extrair. Ao configurar isto, presta muita atenção à subject claim, muitas vezes chamada de sub claim. Este é o campo principal que os cloud providers usam para filtrar o acesso. Por default, o GitHub formata a subject claim para incluir o nome do repositório e a referência do git, como a branch ou tag. Tens de garantir que a tua cloud trust policy valida rigorosamente esta subject claim. Se verificares apenas o nome da organização, qualquer repositório na tua organização poderá pedir cloud resources. Ao ligar o acesso temporário à cloud a metadata específica do workflow, garantes que um repositório comprometido não pode tocar na tua infraestrutura, a não ser que o pedido venha exatamente da branch e do environment em que confias explicitamente. É tudo por este episódio. Obrigado por ouvires, e continua a desenvolver!
10

Escalar Pipelines DRY

3m 51s

Compare Reusable Workflows e Composite Actions. Aprenda qual o mecanismo a escolher ao padronizar as suas pipelines de CI/CD em toda a empresa.

Download
Olá, daqui é o Alex da DEV STORIES DOT EU. GitHub Actions, episódio 10 de 14. Ao gerir continuous integration em cinquenta repositórios, copiar e colar exatamente o mesmo YAML é um pesadelo de manutenção à espera de acontecer. Mudas uma ferramenta de security scanning e, de repente, tens de atualizar manualmente cinquenta ficheiros diferentes. Este episódio é sobre escalar pipelines DRY para resolver exatamente isso. Para deixares de te repetir no GitHub Actions, tens duas ferramentas principais. Reusable Workflows e Composite Actions. Os engenheiros escolhem frequentemente a errada porque ambas evitam a duplicação. Uma Composite Action não é um workflow. É simplesmente um conjunto de steps. Um Reusable Workflow é um pipeline completo que agrupa jobs inteiros. Se a tua lógica partilhada precisa de abranger várias máquinas, orquestrar dependências complexas entre jobs ou gerir secrets com segurança, tens de usar um Reusable Workflow. Uma Composite Action pega numa sequência de steps, como fazer checkout do código, configurar um ambiente de linguagem e instalar dependências, e empacota-os numa única custom action. Quando um workflow usa esta action, todos esses steps agrupados são executados sequencialmente dentro do job atual existente. A Composite Action não decide em que máquina runner é executada. Ela corre onde o job pai a colocar. Ela existe puramente para limpar a lógica repetitiva de steps dentro de um único ambiente de execução. Os Reusable Workflows operam num nível arquitetónico muito mais alto. São ficheiros YAML completos que outro workflow pode acionar. O workflow que faz o pedido é o caller workflow, e o workflow acionado é o called workflow. Como um called workflow define jobs inteiros, ele controla a infraestrutura. Um job dentro do reusable workflow pode correr num runner Ubuntu para fazer a build de uma aplicação, enquanto um job dependente corre num runner macOS para a testar. Considera uma equipa de Platform Engineering a padronizar um pipeline de deployment em Node. Eles querem garantir que todas as equipas correm security checks idênticos antes de lançar o código. Em vez de confiar em cinquenta equipas de produto para manter ficheiros YAML idênticos, os platform engineers criam um Reusable Workflow central num repositório partilhado. Este ficheiro central define a sequência exata de jobs necessários para fazer scan, build e deploy da aplicação. Os cinquenta repositórios de produto criam, então, um caller workflow minimalista. Este caller workflow contém apenas um job que aponta diretamente para o ficheiro partilhado da equipa de plataforma, usando o seu path. Passas os dados de configuração para o called workflow usando inputs, especificando parâmetros como o nome do ambiente de destino ou a versão de Node. O caller workflow também pode passar secrets. Podes mapear secrets específicos explicitamente, ou instruir o called workflow a simplesmente herdar todos os secrets disponíveis para o caller. Quando a equipa de plataforma precisa de fazer rotate a um deployment secret ou adicionar uma nova ferramenta de análise estática, eles atualizam o called workflow central. Instantaneamente, todos os cinquenta repositórios correm o novo security check no seu próximo commit. As equipas de produto não tocam em nenhuma configuração. Aqui está o ponto-chave. Usa Composite Actions para ocultar a lógica complexa de steps dentro de um único ambiente, mas usa Reusable Workflows para impor arquiteturas de pipeline padronizadas em toda a tua organização. É tudo por este episódio. Obrigado por ouvires, e continua a desenvolver!
11

Criar Custom Actions: Docker vs JavaScript

3m 16s

Assuma o controlo da sua pipeline construindo Custom Actions. Exploramos os compromissos de desempenho e compatibilidade entre actions em JavaScript e em contentores Docker.

Download
Olá, daqui é o Alex da DEV STORIES DOT EU. GitHub Actions, episódio 11 de 14. Um container garante versões exatas das ferramentas, mas traz um custo oculto de latência em cada run do workflow. A consistência do teu ambiente pode estar a atrasar a tua equipa e a prendê-la a um único sistema operativo sem que te apercebas. Criar Custom Actions: Docker vs JavaScript resolve esta tensão. Uma custom action é lógica reutilizável que tu escreves uma vez e partilhas por vários repositórios. Quando constróis uma, tens de escolher uma arquitetura de execução. Os dois modelos principais são JavaScript e Docker. Muitos engenheiros optam por Docker actions por defeito, porque querem segurança absoluta e dependências previsíveis. Assumem que um container é a escolha mais robusta. A realidade é que criar uma Docker action impede permanentemente que qualquer runner macOS ou Windows use a tua ferramenta. As Docker actions só correm em ambientes Linux. As JavaScript actions adotam uma abordagem diferente. Elas correm diretamente na máquina host. Escreves a tua lógica, compilas tudo num único ficheiro com todas as dependências, e apontas os metadados da action para esse ficheiro de entrada. Quando um workflow é acionado, o runner usa o seu runtime Node integrado para executar o teu script. Isto desacopla a tua lógica do sistema operativo subjacente. Exatamente a mesma action vai correr nativamente em runners Linux, macOS e Windows, sem modificações. As Docker container actions, por outro lado, empacotam o sistema operativo, as dependências do sistema e o teu código numa unidade imutável. Tu ditas o ambiente exato. O runner lê um Dockerfile fornecido pela tua action, faz o build ou o pull da imagem do container, e corre o teu código dentro desse espaço isolado. Aqui está o ponto chave. O isolamento estrito de uma Docker action introduz uma penalização de cold-start. Imagina uma equipa a criar uma ferramenta custom de linting de código para partilhar por toda a organização. Se a construírem como uma Docker action, o runner tem de fazer pull dessa imagem de container antes de poder avaliar uma única linha de código. Isso pode adicionar um atraso de quinze segundos ao início de cada job de linting. Ao longo de centenas de pull requests por dia, esse tempo ocioso acumula-se em horas de compute desperdiçado. Se a equipa construir essa mesma lógica de linting em JavaScript, o runner simplesmente descarrega o ficheiro de script e executa-o instantaneamente. A tua escolha de arquitetura dita como a tua action se comporta na prática. Se a tua ferramenta depende de binários de sistema complexos, requer uma versão muito específica de um compilador de uma linguagem, ou encapsula scripts Bash legacy que são frágeis fora de uma distribuição Linux específica, o Docker é a escolha certa. Pagas a taxa de latência em troca de estabilidade garantida. Se o teu objetivo é criar uma ferramenta rápida e amplamente adotada que funcione em qualquer tipo de projeto, o JavaScript é o melhor caminho. A escolha arquitetónica entre Docker e JavaScript para uma custom action nunca é sobre a linguagem de programação em que preferes escrever, é um trade-off difícil entre controlo rigoroso do ambiente e velocidade de execução cross-platform. É tudo por agora. Até à próxima!
12

Gestão de Frota: Hosted vs Self-Hosted Runners

3m 30s

Navegue pelas fronteiras dos runners do GitHub. Aprenda quando deve depender de máquinas alojadas pelo GitHub (GitHub-hosted) e quando a sua arquitetura exige Self-Hosted runners.

Download
Olá, daqui fala o Alex da DEV STORIES DOT EU. GitHub Actions, episódio 12 de 14. Os cloud runners do GitHub são extremamente convenientes, até que os teus testes de integração precisem de aceder a uma base de dados legacy, protegida por uma firewall corporativa. De repente, um runner público não consegue aceder aos teus dados privados. É exatamente aí que entra o Fleet Management: Hosted vs Self-Hosted Runners. Por default, o GitHub Actions usa GitHub-hosted runners. Quando um workflow é acionado, o GitHub faz o spin up de uma nova máquina virtual. Podes pedir Ubuntu, Windows ou macOS. O runner executa o teu job, reporta o resultado e, a seguir, a máquina virtual é imediatamente destruída. É começar do zero todas as vezes. Não geres o sistema operativo, não instalas patches de segurança e não te preocupas com ficheiros que sobram de uma build anterior. No entanto, esse isolamento é uma faca de dois gumes. Como estes runners existem na infraestrutura cloud do GitHub, operam com endereços IP dinâmicos e não têm acesso direto às tuas redes privadas. Se tens uma aplicação interna ou uma base de dados que não pode ser exposta à internet pública, precisas de um runner que viva dentro do teu próprio perímetro de segurança. Isto é um self-hosted runner. És tu que forneces o hardware. Pode ser um servidor físico num data center, uma máquina virtual no teu cloud provider ou um container. Instalas a aplicação do GitHub Actions runner nessa máquina. O runner liga-se ao GitHub, vai buscar os jobs pendentes, executa-os localmente e envia os logs de volta. Como vive na tua rede, pode comunicar com segurança com a tua infraestrutura interna sem precisares de abrir buracos na tua firewall. Aqui está a questão central. És dono do hardware, o que significa que a manutenção é tua. És responsável pelas atualizações do sistema operativo, pela segurança da rede e pela instalação das dependências necessárias, como language runtimes ou build tools. Um equívoco comum é achar que os self-hosted runners se comportam exatamente como os hosted. Mas não. Os GitHub-hosted runners são efémeros por design. Os self-hosted runners standard são stateful. Quando um job termina num self-hosted runner default, a máquina continua a correr. Se o teu job gravar um ficheiro temporário, iniciar um processo em background ou fizer pull de uma imagem de container grande, tudo isso permanece no disco quando o próximo job arrancar. Isto cria sérios riscos de contaminação cruzada. Um script de build com defeito num pull request pode deixar ficheiros corrompidos para trás, fazendo com que o job de deploy que corre logo a seguir falhe. Tens de configurar ativamente a tua infraestrutura self-hosted para ser efémera, se for isso que queres, muitas vezes usando webhooks para fazer o spin up de novos containers por job. Se simplesmente precisas de mais poder de processamento ou de um endereço IP estático, mas ainda queres que o GitHub trate da manutenção da máquina, existe um meio-termo chamado larger runners. Estas são máquinas GitHub-hosted onde defines as especificações de hardware e as features de rede, mas permanecem efémeras e geridas pelo GitHub. Em última análise, a decisão entre hosted e self-hosted raramente se resume apenas a custos de compute. Trata-se de um trade-off fundamental entre a conveniência de um ambiente descartável e de zero manutenção, e a necessidade de controlares as fronteiras da tua própria rede. Obrigado por passares uns minutos comigo. Até à próxima, e fica bem.
13

Escala Kubernetes: Actions Runner Controller

3m 28s

Descubra como o Actions Runner Controller (ARC) orquestra frotas de runners efémeros e com auto-scaling nativamente nos seus clusters Kubernetes.

Download
Olá, daqui fala o Alex da DEV STORIES DOT EU. GitHub Actions, episódio 13 de 14. Tens uma equipa enorme e, às nove da manhã, cem developers fazem push de código em simultâneo. Os teus servidores estáticos de build ou engasgam com a queue, ou fizeste over-provisioning e ficam ali a desperdiçar compute caro a noite toda. O Kubernetes Scale: Actions Runner Controller resolve isto ao transformar o teu build pipeline num sistema dinâmico e nativo de containers. Os self-hosted runners normais são geralmente máquinas virtuais estáticas ou containers de longa duração. Configuras tudo, registas-os num repository, e ficam ali a fazer polling por trabalho. Esta configuração garante que estás a pagar por tempo ocioso e, quando ocorre um pico repentino de builds, a tua queue simplesmente acumula até que um runner existente termine a sua task atual. O Actions Runner Controller, ou ARC, muda fundamentalmente esse modelo. O ARC é um Kubernetes operator que orquestra runner scale sets com auto-scaling. Em vez de manter worker nodes de longa duração, faz o provisionamento de runners efémeros, Just-in-Time, com base no tamanho exato da tua queue. Para conseguir isto sem sobrecarregar os API rate limits, o ARC depende de dois componentes arquitetónicos principais dentro do teu Kubernetes cluster. O primeiro é o pod Listener. O Listener usa um HTTPS long poll para se ligar ao GitHub. Em vez de exigir que abras inbound firewall ports para receber webhooks, o Listener liga-se ao GitHub e mantém a ligação aberta. Fica ali silenciosamente a aguardar que o GitHub envie uma mensagem de Job Available. Quando o Listener recebe essa mensagem, passa a informação para o pod Controller. O Controller atua como o provisioning engine. Fala imediatamente com a Kubernetes API para fazer o spin up de um pod runner novo especificamente para esse único job pendente. Este pod é um runner efémero Just-in-Time. Faz boot, recebe um registration token de curta duração, executa o workflow e, em seguida, termina imediatamente. Vamos relembrar aquele code rush das nove da manhã. Cem developers fazem push de commits exatamente ao mesmo tempo. O pod Listener deteta o pico repentino de mensagens Job Available do GitHub. Alerta o Controller, que solicita instantaneamente cem pods efémeros do Kubernetes. O teu cluster faz scale out, alocando nodes se necessário, e os jobs são executados em paralelo. À medida que cada workflow termina, o seu pod é completamente destruído. Às nove e quinze, a queue está limpa e a tua contagem de runners faz scale back até zero. Utilizaste parallel compute massivo durante exatamente quinze minutos e, depois, paraste de pagar por isso. Aqui está o ponto chave. Como cada job corre num pod isolado e recém-provisionado, que é destruído logo após a execução, eliminas completamente a contaminação de estado entre builds. Uma cache suja, um background process remanescente ou uma environment variable alterada de uma run anterior simplesmente não podem quebrar a próxima. Ganhas a segurança de um build environment imaculado todas as vezes, aliada à exata compute efficiency do auto-scaling do Kubernetes. O verdadeiro valor do Actions Runner Controller é que te impede de tratar os continuous integration runners como infraestrutura pesada que tens de manter, transformando-os antes em transient compute puro que só existe enquanto um job está ativamente a correr. Obrigado por passares uns minutos comigo. Até à próxima, fica bem.
14

Integridade da Cadeia de Fornecimento com Attestations

3m 40s

Proteja a sua cadeia de fornecimento de software. Aprenda a gerar artifact attestations e proveniência infalsificáveis diretamente a partir dos seus workflows.

Download
Olá, daqui é o Alex da DEV STORIES DOT EU. GitHub Actions, episódio 14 de 14. Um utilizador descarrega a tua command line tool compilada a partir de uma página de release. Se uma dependência comprometida ou um agente malicioso trocar esse binary depois do build, uma verificação de checksum standard não o vai salvar. Hashes standard apenas provam que o ficheiro que descarregou corresponde ao ficheiro alojado, e não de onde ele realmente veio. Para garantir que um ficheiro foi gerado exatamente pelo teu código, precisas de Supply Chain Integrity com Attestations. Uma attestation não é apenas um build log ou um ficheiro de texto com um hash ao lado da tua release. É uma declaração assinada criptograficamente e infalsificável sobre a proveniência de um artifact. Ela vincula o teu binary final diretamente ao commit SHA exato, ao workflow run específico e à identidade OpenID Connect do ambiente de build. O processo acontece inteiramente dentro do teu workflow de GitHub Actions. Depois do teu código compilar, usas a action oficial de build provenance. Esta action calcula o checksum do teu artifact finalizado e contacta uma autoridade de assinatura centralizada, especificamente a Sigstore. O workflow troca o seu token OpenID Connect temporário e específico do job por um certificado de assinatura de curta duração. Como este token é gerado pelo GitHub Actions e mapeado diretamente para o teu repositório, funciona como um cartão de identidade infalsificável para o workflow runner. Esta interação gera um registo criptográfico permanente. Este registo declara inequivocamente que este file hash exato foi produzido pelo teu repositório, desencadeado por um commit específico, durante um workflow run específico. A assinatura é anexada ao artifact, criando um conjunto de provas que viaja com o ficheiro para onde quer que ele seja alojado. Aqui está o ponto chave. O verdadeiro valor de segurança acontece do lado do consumidor. Quando um utilizador descarrega a tua command line tool, não tem de confiar cegamente no provedor de alojamento ou no mirror de download. Antes de executar o binary, usa a GitHub CLI para verificar a attestation localmente. Corre um comando attestation verify contra o executável descarregado, especificando explicitamente o owner do teu repositório como a fonte esperada. A CLI inspeciona a assinatura criptográfica e compara-a com o transparency log público. Se a assinatura for válida, prova matematicamente que o ficheiro foi compilado pelo teu workflow oficial. Se um agente malicioso intercetar o download, adulterar a compilação, ou substituir o binary na página de release, a verificação falha instantaneamente. A assinatura não pode ser falsificada porque o atacante nunca poderá possuir o token de identidade OpenID Connect temporário gerado dentro do teu workflow run seguro. A identidade está inextricavelmente ligada à infraestrutura do GitHub Actions no momento exato do build. Este mecanismo fecha uma lacuna crítica na segurança da software supply chain. Já não estás a pedir aos utilizadores que confiem num local de armazenamento. Em vez disso, o artifact torna-se auto-autenticável. As attestations mudam o teu modelo de segurança, passando de confiar onde um ficheiro vive para provar matematicamente onde ele nasceu. Como este é o episódio final da nossa série de GitHub Actions, encorajo-te vivamente a pores as mãos na massa e a começares a construir estes workflows tu mesmo. Visita devstories dot eu para sugerires tópicos que queiras ver abordados nas nossas futuras séries. É tudo por este episódio. Obrigado por ouvires, e continua a construir!