
O Semaphore UI 2.19 é o maior lançamento da linha 2.x. Ele introduz Workflows com um editor gráfico, permite que os runners executem tarefas em contêineres Docker e pods Kubernetes, ensina o Semaphore a emitir tokens de identidade JWT de curta duração para tarefas em execução, adiciona rotação de chaves de criptografia, corrige de vez a confiabilidade dos runners e traz uma longa lista de mudanças de reforço de segurança.
A linha cobre as versões v2.19.0 até v2.19.14. As versões de correção estão listadas no final.
Destaques
- Workflows (Beta) — encadeie modelos de tarefa em um pipeline com portões de aprovação, desenhado em um editor gráfico e acompanhado ao vivo no mesmo canvas.
- Executores Docker e Kubernetes — os runners podem executar cada tarefa em um contêiner ou pod novo (Pro / Enterprise).
- Tokens de identidade JWT para tarefas — autenticação sem chaves a partir dos playbooks para Vault, AWS, GCP, Azure e qualquer outro serviço que aceite tokens OIDC.
- Rotação de chaves de criptografia — um keyring com rótulos, recarga a quente e um comando
vaults check. - Variáveis de survey como variáveis de ambiente, além dos tipos
int,texteenumcom editor reformulado. - Paginação real no servidor do histórico de tarefas — projetos com milhões de tarefas continuam rápidos.
- Confiabilidade dos runners — status online/offline, tokens de registro de uso único com hash e recuperação automática de tarefas presas em um runner morto.
- Log de depuração seletivo com
SEMAPHORE_DEBUG_FILTER. - Reforço de segurança: verificação da senha atual, validação de origem contra CSRF, cookies seguros, validação de entrada mais rigorosa em toda a API.
- BoltDB removido — apenas SQLite, MySQL e PostgreSQL.
Workflows (Beta)
Um workflow é um grafo de modelos de tarefa que é executado como uma única unidade. Cada nó é uma tarefa (executa um modelo), uma aprovação (pausa a execução até que um usuário aprove ou rejeite) ou uma nota (anotação livre que nunca é executada). As arestas carregam uma condição: em caso de sucesso, em caso de falha ou sempre.
Os workflows aparecem como um novo item Workflows na barra lateral do projeto, marcado com um selo Beta. Eles estão disponíveis na edição Pro; durante o beta, estão habilitados independentemente do plano.
Editor gráfico

O editor é um canvas de página inteira construído sobre o Drawflow:
- arraste nós da paleta e conecte-os arrastando a partir da alça de um nó;
- clique em uma aresta para alterar sua condição; as arestas são codificadas por cor e uma legenda fica no canto;
- clique em um nó para editar suas propriedades no painel lateral: modelo, modo de convergência (todos os pais / qualquer pai), tempo limite e mensagem da aprovação, texto da nota;
- auto-arestas e ciclos são rejeitados enquanto você os desenha, e um painel Problemas espelha a validação do servidor, de modo que um grafo quebrado não pode ser salvo;
- as posições dos nós são persistidas; workflows criados pela API sem posições recebem um layout topológico automático;
- use zoom pela barra de ferramentas ou com
Ctrl+ roda do mouse, arraste o canvas para mover a visão, recolha a paleta para ganhar espaço; - Versão inicial define o versionamento das execuções (
1.4.0,1.4.1, …); a versão é propagada para cada tarefa que a execução inicia.

Visualização da execução ao vivo
A visualização da execução reutiliza o mesmo canvas. Cada nó mostra o status da sua tarefa, o nó ativo
é destacado, e aprovações pendentes exibem os botões Aprovar / Rejeitar diretamente no canvas. Um
botão Parar interrompe à força todas as tarefas da execução, rejeita as aprovações pendentes e marca
a execução como stopped.

Os status de execução são running, approval, success, failed e stopped. A progressão do
workflow é conduzida pelo servidor: quando qualquer tarefa do workflow termina, os próximos nós são
agendados, de modo que um modelo sem filhos com autorun não trava mais a execução.

Parâmetros de tarefa por nó
Cada nó de tarefa pode sobrescrever os parâmetros que passa ao seu modelo (variáveis, inventário, branch, argumentos, versão, mensagem), da mesma forma que uma execução manual.
API
GET/POST /api/project/{id}/workflows
GET/PUT/DELETE /api/project/{id}/workflows/{workflow_id}
POST /api/project/{id}/workflows/{workflow_id}/run
GET /api/project/{id}/workflows/{workflow_id}/runs
GET /api/project/{id}/workflows/{workflow_id}/runs/{run_id}
POST /api/project/{id}/workflows/{workflow_id}/runs/{run_id}/stop
GET /api/project/{id}/workflows/{workflow_id}/runs/{run_id}/artifacts
GET /api/project/{id}/workflows/{workflow_id}/runs/{run_id}/approvals
POST /api/project/{id}/workflows/{workflow_id}/runs/{run_id}/approvals/{node_id}
Limitações conhecidas do beta: sem minimapa, desfazer/refazer ou seleção múltipla; os artefatos de
workflow (valores de set_stats) ainda não fluem entre tarefas executadas em runners remotos.
Executores Docker e Kubernetes (Pro / Enterprise)
Os runners podem executar cada tarefa em um ambiente isolado em vez de diretamente no host do runner.
O executor é selecionado uma vez por processo do runner com runner.executor.type (local, docker,
k8s).
Docker (runner.executor.docker, Pro):
| Opção | Variável de ambiente | Padrão |
|---|---|---|
host |
SEMAPHORE_RUNNER_DOCKER_HOST |
socket local |
tls_verify, cert_path |
SEMAPHORE_RUNNER_DOCKER_TLS_VERIFY, …_CERT_PATH |
|
image |
SEMAPHORE_RUNNER_DOCKER_IMAGE |
semaphoreui/job:latest |
helper_image |
SEMAPHORE_RUNNER_DOCKER_HELPER_IMAGE |
semaphoreui/helper:latest |
network |
SEMAPHORE_RUNNER_DOCKER_NETWORK |
bridge |
pull_policy |
SEMAPHORE_RUNNER_DOCKER_PULL_POLICY |
if-not-present |
cpu_limit, memory_limit |
SEMAPHORE_RUNNER_DOCKER_CPU_LIMIT, …_MEMORY_LIMIT |
|
privileged |
SEMAPHORE_RUNNER_DOCKER_PRIVILEGED |
false |
poll_interval_seconds, cleanup_grace_seconds |
…_POLL_INTERVAL_SECONDS, …_CLEANUP_GRACE_SECONDS |
2, 30 |
Kubernetes (runner.executor.k8s, Enterprise):
| Opção | Variável de ambiente | Padrão |
|---|---|---|
kubeconfig |
SEMAPHORE_RUNNER_K8S_KUBECONFIG |
dentro do cluster |
namespace |
SEMAPHORE_RUNNER_K8S_NAMESPACE |
semaphore |
image |
SEMAPHORE_RUNNER_K8S_IMAGE |
semaphoreui/job:latest |
helper_image |
SEMAPHORE_RUNNER_K8S_HELPER_IMAGE |
semaphoreui/helper:latest |
service_account |
SEMAPHORE_RUNNER_K8S_SERVICE_ACCOUNT |
default |
pull_secrets |
SEMAPHORE_RUNNER_K8S_PULL_SECRETS |
|
poll_interval_seconds, cleanup_grace_seconds |
…_POLL_INTERVAL_SECONDS, …_CLEANUP_GRACE_SECONDS |
3, 30 |
Duas novas imagens são publicadas pelo CI: semaphoreui/job (Ansible, Terraform, OpenTofu, Terragrunt,
paramiko) e semaphoreui/helper. Um modelo pode sobrescrever a imagem para suas próprias tarefas com
o novo campo Imagem do executor no formulário do modelo (exibido com um selo Upgrade to PRO quando
o recurso de executor não está licenciado).
A conexão do runner também ganhou runner.connection.server_ca_cert_file e
runner.connection.skip_tls_verify.
Tokens de identidade JWT para tarefas
O Semaphore pode atuar como um provedor de identidade no estilo OIDC para tarefas em execução, de modo que um playbook possa se autenticar no Vault, em endpoints STS de nuvem ou em serviços internos sem credenciais de longa duração.

- Habilite por modelo com Emitir JWT para o executor da tarefa; defina um ou mais audiences e um
TTL (limitado por
jwt.max_ttl). - A tarefa recebe o token na variável de ambiente
SEMAPHORE_JWT. - Os tokens são assinados com ES256 (ECDSA P‑256) e carregam apenas IDs:
task_id,project_id,template_id,user_id, além das claims padrãoiss,sub,aud,exp,nbf,iat,jti. - As chaves públicas são publicadas em
GET /.well-known/jwks.json.
Configuração do servidor:
"jwt": {
"enabled": true,
"issuer": "https://semaphore.example.com",
"default_ttl": "1h",
"max_ttl": "24h"
}
Variáveis de ambiente: SEMAPHORE_JWT_ENABLED, SEMAPHORE_JWT_ISSUER, SEMAPHORE_JWT_DEFAULT_TTL,
SEMAPHORE_JWT_MAX_TTL.
Variáveis de survey
Entregar uma variável como variável de ambiente
Uma variável de survey agora tem a configuração Passar variável como: pelo método de CLI específico
da aplicação (--extra-vars para Ansible, -var para Terraform/OpenTofu, um argumento de CLI para
scripts shell) ou como variável de ambiente do processo. O nome da variável é usado literalmente,
então um usuário de Terraform simplesmente a nomeia TF_VAR_region. Variáveis de ambiente não aparecem
na listagem de processos, o que torna essa a opção mais segura para segredos.

Novos tipos
int— entrada numérica com validação;text— texto de múltiplas linhas;enum— editor reformulado com pares nome/valor e um valor padrão.

O diálogo de tarefa renderiza cada tipo de acordo:

Armazenado no JSON survey_vars existente — nenhuma migração necessária.
Modelos e tarefas
-
Seletor dinâmico de playbook. O campo Caminho para o arquivo do playbook lista os playbooks encontrados no repositório (
GET /api/project/{id}/repositories/{repository_id}/playbooks). A lista acompanha a branch selecionada e recorre a texto livre quando o repositório não pode ser lido. -
Ignorar a instalação do galaxy — opção por modelo, opcionalmente sobrescrevível por tarefa, para pular a instalação de roles e collections do
requirements.yml. -
Variáveis tipadas nos grupos de variáveis, incluindo números:

-
Paginação do histórico de tarefas. A página Histórico costumava buscar as 200 tarefas mais recentes e paginá-las no cliente, então tudo que fosse mais antigo ficava inacessível. O backend agora retorna uma página por vez usando um cursor keyset (
?count=20&before=<task_id>, cabeçalho de respostaX-Has-Next), semCOUNT(*)e semOFFSET. O rodapé oferece Linhas por página e controles de anterior/próximo. A mesma paginação se aplica à lista de tarefas por modelo e ao dashboard.
-
As listas de tarefas são recarregadas no máximo uma vez a cada 5 segundos; várias requisições redundantes foram removidas.
-
Os agendamentos são validados com o parser de cron do servidor, então cliente e servidor não divergem mais.
-
A sobrescrita de branch em uma tarefa só é aceita quando o modelo permite.
-
As operações Git são serializadas por diretório de repositório. Modelos com Permitir tarefas paralelas compartilham uma única cópia de trabalho, e
git pull/git checkoutconcorrentes podiam corrompê-la. Atualização e checkout agora formam uma única seção crítica, tanto para execução local quanto em runner, incluindo repositórios de inventário.
Runners

-
Status online / offline na página Runners, derivado da vivacidade do heartbeat.
-
Tokens de registro de uso único. Um runner pode ser criado primeiro na UI e registrado depois com um token
smrs_…que é exibido uma única vez, armazenado apenas como hash SHA‑256 e expira após uma hora. O diálogo mostra comandos prontos para copiar para variáveis de ambiente, arquivo de configuração e Docker. Regenerar o token redefine um runner já registrado para que ele possa ser registrado novamente.
SEMAPHORE_WEB_ROOT=https://semaphore.example.com \ SEMAPHORE_RUNNER_REGISTRATION_TOKEN=smrs_… \ semaphore runner register --config ./config.runner.json semaphore runner start --config ./config.runner.json -
Recuperação de tarefas travadas. Os runners enviam a hora de início do seu processo (
X-Runner-Started-At). Um runner que para de fazer polling é marcado como offline apósrunners.offline_timeout_sec(120 s): ele não recebe novas tarefas e suas tarefas emstartingsão reatribuídas. Apósrunners.task_fail_timeout_sec(420 s), suas tarefas emrunningsão marcadas como falhas com uma mensagem clara. Um runner que reiniciou e perdeu seu pool de jobs em memória é detectado imediatamente. A reconciliação é executada a cadarunners.reconcile_interval_sec(30 s). -
Tarefas reatribuídas de um runner são encerradas no runner antigo.
-
O fallback para runners obsoletos foi removido: quando todos os runners estão offline, as tarefas aguardam na fila em vez de serem despachadas para um runner que não fez polling por até 30 minutos.
-
Chaves de criptografia RSA por runner removidas. O tráfego runner‑servidor depende de TLS; isso elimina a etapa de troca de chaves do registro e do
setup. -
Corrigido um vazamento de conexões TCP no cliente do runner; tokens de registro inválidos retornam
400.
Segredos e criptografia
- Rotação de chaves de criptografia. O novo bloco
encryptiondescreve um keyring com rótulos:keysinline (valor ou arquivo), ou umkeys_folderonde cada arquivo é uma chave nomeada pelo nome do arquivo, além de ponteirosactivepara a chave de segredos e a chave de opções. O texto cifrado agora carrega um ID de chave, então as chaves podem ser rotacionadas sem uma recriptografia em massa.encryption.keys_filecomkeys_poll_interval(padrão15s) recarrega o keyring a quente. Nova CLI:semaphore vaults check;semaphore vaults rekeyfoi reescrito em torno do keyring. O antigoaccess_key_encryptionplano continua funcionando. option_encryption— uma chave separada para as opções armazenadas no banco de dados.- Tipo de armazenamento de segredos OpenBao (roteado pelo provedor Vault) com ícone próprio.
- AWS Secrets Manager sem credenciais estáticas — uma caixa de seleção Usar role IAM.
- Opção para ignorar a verificação TLS nos armazenamentos Vault/OpenBao.
- Campos de segredos sincronizados e somente leitura não são mais apagados na atualização.
Observabilidade
- Log de depuração por namespace.
--debug-filter/SEMAPHORE_DEBUG_FILTERseleciona quais subsistemas emitem saída de depuração, no estilo dodebugdo Node.js:runner,runner,task_pool,task_*,*,*,-db. Namespaces disponíveis:runner,task_pool,task_runner,task_logger,git,terraform,session,ldap,schedule,db,ha. O filtro só se aplica quando o nível de log éDEBUG; ele nunca eleva o nível. Os hooks de syslog respeitam o mesmo filtro. - Muitas novas mensagens de depuração contextuais em runners, tarefas e autenticação; o workspace selecionado é impresso na inicialização.
Segurança

- Alterar a senha agora exige a senha atual (CWE‑620).
- Validação de Origin / Referer em requisições que alteram estado (reforço contra CSRF).
- Os cookies de sessão são marcados como
Securequando servidos por HTTPS. - Os tokens de registro de runners são armazenados com hash e expiram; as chaves de criptografia por runner foram removidas.
- A criação de roles personalizadas verifica as permissões de quem chama (correção de escalação de privilégios).
- Validação de URL do Git;
--end-of-optionsé passado ao git para que uma ref forjada não possa ser lida como flag; os hashes de commit têm o formato verificado; as branches são validadas antes da navegação no repositório; os caminhos de playbook são validados. - Os payloads das chaves de acesso e o campo
appdo modelo são validados. - As claims do JWT carregam apenas IDs — nenhum nome ou e‑mail vaza para sistemas externos.
- Os tokens de runner não são mais gravados nos backups do projeto.
- A API retorna após um erro de escrita em vez de continuar com uma resposta parcialmente escrita.
- SLA de segurança publicado em
SECURITY.md; os artefatos de lançamento são assinados com a chave GPG[email protected].
UI e localização

- Tradução para tcheco.
- Cartões suspensos para as seções de JWT e agendamento do formulário do modelo.
- O ícone de copiar para a área de transferência fica visível no modo claro; spinners de tarefas em execução corrigidos; espaçamento do formulário do modelo corrigido; rótulo Beta nos workflows.
- A extração de variáveis de integração preserva objetos e arrays JSON em vez de convertê-los em string.
Notas de atualização
Mudanças incompatíveis e de comportamento
- BoltDB foi removido.
boltnão é mais um dialeto válido; o servidor se recusa a iniciar com “Bolt is not supported starting from version 2.19”. Migre primeiro para SQLite, MySQL ou PostgreSQL. - Chaves de criptografia dos runners removidas. Servidor e runners devem estar ambos na 2.19. Garanta que o tráfego runner‑servidor esteja protegido por TLS. Provisionamento de runners por script que esperava a chave precisa ser atualizado.
- As APIs de lista de tarefas são paginadas.
GET /api/project/{id}/tasks/lastaceitacountebefore;limitainda é aceito, mas clientes que dependiam das 200 tarefas mais recentes em uma única resposta precisam paginar. - Sem fallback para runners obsoletos. Com todos os runners offline, as tarefas permanecem na fila.
- Flag
activedo runner removida do registro. - Os backups do projeto não contêm mais tokens de runner.
- SQLite: a
v2.19.14reconstrói as tabelassessionetaskpara adicionar chaves estrangeiras adequadas (corrige a exclusão de usuários). Sessões órfãs são removidas. Faça backup do banco de dados antes de atualizar.
Nova configuração
jwt, runners, encryption, option_encryption, secrets_path, db.dialect,
runner.executor.{type,docker,k8s}, runner.connection.{server_ca_cert_file,skip_tls_verify},
runner.registration_token_file, runner.token_file. Todas são opcionais; configurações existentes
continuam funcionando. O config.schema.yaml e a documentação de referência de configuração foram
regenerados.
Migrações do banco de dados
v2.18.6 (jwt_params do modelo), v2.18.15 (tabelas de workflow), v2.19.2 (runner.started_at),
v2.19.11 (project__workflow_node.task_params_id), v2.19.12 (project__template.executor_image),
v2.19.14 (reconstrução de session/task no SQLite). Compatibilidade de migração com MariaDB 12.1
corrigida.
Versões de correção
| Versão | Mudanças |
|---|---|
| 2.19.8 | Migração do SQLite corrigida; exclusão de usuários corrigida (chaves estrangeiras de session/task); comparação de strings sem diferenciar maiúsculas nas consultas ao BD |
| 2.19.9 | Variável de ambiente SEMAPHORE_RUNNER_EXECUTOR_TYPE; limpeza de omitempty na configuração |
| 2.19.10 | Correção da configuração do executor; correção da opção de build do Docker |
| 2.19.11 | Workspace selecionado impresso nos logs; tag latest para a imagem helper; testes de migração do BD |
| 2.19.12 | Corrigido ponteiro nulo nas opções de configuração do runner; correção da propagação de erros |
| 2.19.14 | Corrigido o tratamento legado de secrets_path na configuração |
Dependências
Go 1.26; go-git 5.19, go-oidc 3.19, golang.org/x/crypto 0.53, go-ldap 3.4.13,
modernc.org/sqlite 1.52. Documentação adicionada como submódulo git; THIRD-PARTY-LICENSES.md
regenerado.
