GitHub Actions self-hosted runner: como evitar que seus workflows parem em setembro de 2026
O GitHub vai endurecer a exigência de atualização dos self-hosted runners em setembro. O risco não é apenas falhar no registro: runners antigos podem deixar jobs presos na fila.

GitHub Actions self-hosted runner: como evitar que seus workflows parem em setembro de 2026
Se você mantém GitHub Actions em runners próprios, setembro de 2026 não é um bom mês para descobrir que “o runner estava funcionando há meses, então deixei quieto”.
O GitHub está apertando duas coisas ao mesmo tempo:
- a versão mínima aceita para registrar ou registrar novamente um self-hosted runner;
- a idade máxima prática de uma versão para continuar recebendo jobs.
Além disso, o runtime Node 20 usado por Actions entra na reta final de remoção nos runners em 23 de setembro de 2026.
O risco operacional é simples: um runner pode continuar aparecendo como parte da sua infraestrutura, mas deixar de registrar, deixar de receber jobs ou manter workflows parados na fila.
A boa notícia é que dá para reduzir esse risco com uma revisão relativamente pequena.
O ponto mais importante: v2.329.0 não é um “número mágico” permanente
A documentação do GitHub separa duas regras.
A primeira é de registro: para configurar ou registrar novamente um runner no GitHub.com, a base mínima é a versão 2.329.0.
A segunda é mais importante para operação contínua: o runner precisa acompanhar as releases novas. Segundo o GitHub, um self-hosted runner com atualização automática desativada deve ser atualizado dentro de 30 dias depois que uma nova versão fica disponível.
Isso muda a forma correta de pensar o problema.
Não é:
estou na 2.329.0
↓
estou seguro para sempre
É:
runner >= mínimo de registro
+
runner dentro da janela suportada de atualização
↓
continua elegível para receber jobs
Em outras palavras, 2.329.0 é um piso de compatibilidade para registro, não uma versão para congelar indefinidamente.
Em 5 de setembro de 2026, a release estável mais recente do actions/runner é a v2.337.0, publicada em 26 de agosto.
O calendário de setembro merece atenção
Para GitHub Enterprise Cloud, o GitHub programou brownouts antes do enforcement completo.
As datas divulgadas são:
- 7 de setembro: bloqueio intermitente de configuração para versões incompatíveis;
- 9 de setembro: bloqueio intermitente de configuração e runtime;
- 11 de setembro: novo brownout de configuração;
- 14, 16 e 18 de setembro: brownouts de configuração e runtime;
- 23 de setembro: remoção do Node 20 dos runners;
- 25 de setembro: início do enforcement completo da política de versão mínima para GitHub Enterprise Cloud.
Os brownouts são úteis porque expõem runners desatualizados antes do corte definitivo.
Mas não vale tratar o brownout como teste em produção.
Se o seu deploy depende de self-hosted runner, descobrir a incompatibilidade quando o pipeline precisa subir uma correção urgente é o pior momento possível.
Quem está mais exposto
Nem todo self-hosted runner tem o mesmo risco.
Runners com atualização automática funcionando tendem a acompanhar a política de 30 dias sem intervenção.
O risco cresce principalmente quando existe algum destes cenários:
- runner registrado com
--disableupdate; - imagem Docker ou VM criada há meses e nunca reconstruída;
- runner efêmero criado a partir de template antigo;
- servidor Linux de longa duração com serviço configurado uma vez e esquecido;
- automação própria que instala uma versão fixa;
- Actions Runner Controller com imagem customizada e atualização controlada manualmente;
- ambientes isolados que não conseguem alcançar corretamente o serviço de atualização;
- pipelines que ainda dependem de Actions antigas baseadas em Node 20.
Esse último ponto merece uma distinção.
O Node usado internamente por uma JavaScript Action não é necessariamente o mesmo node instalado no seu sistema operacional.
Atualizar o Node do servidor não substitui a necessidade de atualizar Actions e runner.
Primeiro passo: descubra o que você realmente está executando
Antes de atualizar qualquer coisa, monte um inventário.
Para cada runner, registre pelo menos:
nome
repositório / organização
sistema operacional
arquitetura
versão do actions/runner
auto-update ligado ou desligado
labels
serviço responsável
imagem/template de origem
último job executado
Em instalações Linux tradicionais, uma forma útil de conferir a versão local é executar o listener dentro da pasta do runner:
cd /caminho/do/actions-runner
./bin/Runner.Listener --version
Se o runner estiver instalado como serviço pelo script oficial, confira também o estado:
sudo ./svc.sh status
O objetivo aqui não é apenas responder “está online?”.
Você quer responder:
se eu recriar esse runner hoje, ele volta com uma versão suportada e continua recebendo jobs?
Essa é uma pergunta muito melhor.
A nova API de depreciação ajuda a transformar manutenção em regra
Em 3 de setembro, o GitHub anunciou uma API REST específica para consultar a depreciação de versões de runners.
Ela retorna informações como:
runner_version;runtime_deprecates_at;registration_deprecates_at.
Isso é importante porque tira a manutenção do terreno do “lembra de olhar o changelog” e permite colocar a política dentro da própria operação.
Com GitHub CLI, a chamada no escopo de repositório segue esta ideia:
gh api repos/OWNER/REPO/actions/runners/deprecations/2.337.0
Para uma automação interna, o próximo passo natural é consultar a versão dos seus runners e disparar alerta antes do fim da janela suportada.
O melhor sistema não depende de alguém lembrar da data.
Ele torna a data observável.
Se você desativou auto-update, a atualização precisa virar processo
Existe um motivo legítimo para usar --disableupdate.
Em runners efêmeros, containers e imagens imutáveis, permitir que cada instância baixe uma atualização durante o boot pode ser lento, imprevisível e contrário ao modelo de infraestrutura.
O problema não é desligar auto-update.
O problema é desligar auto-update sem substituir por outro mecanismo de atualização.
Um modelo saudável fica parecido com isto:
nova release do runner
↓
pipeline de imagem detecta
↓
nova imagem é construída
↓
smoke test
↓
canário
↓
rollout
↓
imagem antiga deixa de criar runners
Assim, a versão do runner passa a ser uma dependência de infraestrutura, como qualquer outra.
Se você mantém uma imagem fixa com 2.330.0 por seis meses, não tem infraestrutura imutável.
Tem infraestrutura congelada.
Não atualize “no escuro”: use um canário
Atualizar todos os runners ao mesmo tempo resolve a obsolescência, mas pode criar outro problema.
Runner é infraestrutura de execução.
Mudanças de runtime, dependências do sistema operacional, permissões, Docker e ferramentas instaladas podem revelar incompatibilidades no seu ambiente.
Uma estratégia melhor é atualizar primeiro um runner canário.
Exemplo de fluxo:
1 runner atualizado
↓
workflow de smoke
↓
workflow real de baixo risco
↓
observação de fila e logs
↓
rollout restante
Você pode manter um workflow simples, acionado manualmente, apenas para provar que o ambiente consegue executar o básico:
name: runner-smoke
on:
workflow_dispatch:
jobs:
smoke:
runs-on: [self-hosted, linux, x64]
steps:
- name: Identidade do host
run: |
uname -a
id
- name: Ferramentas essenciais
run: |
git --version
docker --version || true
- name: Espaço em disco
run: df -h
- name: Conectividade externa
run: curl -fsS --max-time 10 https://github.com/ > /dev/null
Esse teste não prova que todos os seus projetos estão saudáveis.
Mas ele responde rapidamente se o runner:
- recebe job;
- executa shell;
- encontra ferramentas esperadas;
- tem disco;
- tem conectividade.
Depois disso, rode um workflow real representativo.
O problema de setembro não termina no runner: revise também suas Actions
O GitHub também confirmou a remoção do Node 20 dos runners para 23 de setembro.
Para quem mantém workflows, isso significa revisar Actions JavaScript antigas.
O caminho não é adicionar um node --version no servidor e considerar resolvido.
Você precisa verificar se as Actions usadas no workflow já publicaram versões compatíveis com o runtime atual.
Procure principalmente por:
- Actions internas da empresa;
- Actions próprias em repositórios privados;
- versões antigas de Actions de terceiros;
- reusable workflows pouco revisados;
- dependências fixadas há anos.
Se você mantém uma Action JavaScript própria, revise o runs.using do action.yml e siga a versão de runtime suportada pela documentação atual.
Se você apenas consome Actions, confira a versão suportada pelo mantenedor e atualize de forma controlada.
Atenção a dois ambientes específicos
A transição do Node 20 para Node 24 também tem impacto de plataforma.
O GitHub informa que Node 24 não é compatível com macOS 13.4 ou anterior.
Também não existe suporte oficial do Node 24 para ARM32, e o GitHub informa que self-hosted runners ARM32 deixam de ser suportados depois da depreciação do Node 20.
Se você tem hardware legado, não deixe essa revisão para o dia 22.
O problema pode exigir troca de sistema operacional ou arquitetura, não apenas um download novo do runner.
O que eu colocaria em um checklist operacional
Se o objetivo é passar setembro sem surpresa, eu faria esta revisão:
1. Inventário
- [ ] listar todos os self-hosted runners;
- [ ] identificar versão atual;
- [ ] identificar arquitetura e sistema operacional;
- [ ] localizar templates, imagens e scripts que criam runners.
2. Política de atualização
- [ ] confirmar se auto-update está habilitado;
- [ ] se estiver desabilitado, documentar quem atualiza e com qual frequência;
- [ ] impedir criação de runners a partir de imagens antigas;
- [ ] acompanhar releases do
actions/runner.
3. Compatibilidade
- [ ] revisar runners abaixo da versão atual suportada;
- [ ] revisar macOS antigo;
- [ ] revisar ARM32;
- [ ] revisar Actions que ainda dependem de Node 20.
4. Validação
- [ ] atualizar um canário;
- [ ] executar smoke workflow;
- [ ] executar workflow real;
- [ ] verificar fila;
- [ ] verificar logs;
- [ ] só então expandir o rollout.
5. Observabilidade
- [ ] monitorar runner offline;
- [ ] monitorar jobs presos em fila;
- [ ] alertar versão perto da depreciação;
- [ ] monitorar espaço em disco;
- [ ] registrar versão da imagem usada na criação.
Esse checklist é pequeno.
O custo de ignorá-lo pode ser descobrir durante um deploy que o problema não está no código — está na máquina que deveria executá-lo.
A lição maior: runner é produto de infraestrutura, não “PC que executa Actions”
É comum um self-hosted runner começar assim:
subi uma VM
instalei o runner
funcionou
deixei como serviço
Isso é suficiente para começar.
Não é suficiente para operar por anos.
Quando CI/CD passa a depender daquela máquina, ela entra no mesmo conjunto de responsabilidades de qualquer componente de produção:
- atualização;
- compatibilidade;
- observabilidade;
- rollback;
- capacidade;
- segurança;
- ownership.
O enforcement de setembro apenas deixa essa realidade mais visível.
Se o runner é parte da esteira que testa e publica seu software, manter o runner saudável faz parte de entregar software.
Onde a EngStack entra
Na EngStack, CI/CD não aparece como um arquivo YAML isolado. Ele entra junto de Docker, deploy, observabilidade, segurança, review e operação da aplicação.
Esse é o contexto que transforma “meu workflow está verde” em algo mais útil:
eu sei por que minha esteira continua confiável quando dependências, runtimes e infraestrutura mudam.
Conclusão
A mudança mais perigosa em um self-hosted runner não é aquela que quebra imediatamente.
É aquela que deixa tudo funcionando até o dia em que o serviço externo muda a regra.
Setembro de 2026 tem datas suficientes para justificar uma revisão agora.
A prioridade é simples:
- descubra suas versões;
- atualize o que estiver envelhecido;
- revise Actions ligadas a Node 20;
- valide em canário;
- transforme atualização do runner em processo contínuo.
Assim, o próximo deploy continua dependendo do seu código — e não da sorte de uma VM esquecida ainda ser aceita pelo GitHub.