Ir para o conteúdo

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.

Palavras: 1911Tempo de Leitura: 10 Minutos

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:

  1. descubra suas versões;
  2. atualize o que estiver envelhecido;
  3. revise Actions ligadas a Node 20;
  4. valide em canário;
  5. 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.

Publicado em