Execução de workflow aguardando aprovação

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, text e enum com 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

Editor de workflow

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.

Painel de propriedades do nó

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.

Visualização da execução no tema escuro

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.

Lista de workflows

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.

Formulário do modelo: opções avançadas com JWT

  • 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ão iss, 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.

Variável de survey entregue como variável de ambiente

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.

Editor de variável de survey do tipo enum

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

Diálogo de nova tarefa com variáveis de survey tipadas

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:

    Grupo de variáveis com variáveis tipadas

  • 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 resposta X-Has-Next), sem COUNT(*) e sem OFFSET. 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.

    Histórico com paginação no servidor

  • 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 checkout concorrentes 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

Página de runners com status online/offline

  • 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.

    Diálogo de token de registro do runner

    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ós runners.offline_timeout_sec (120 s): ele não recebe novas tarefas e suas tarefas em starting são reatribuídas. Após runners.task_fail_timeout_sec (420 s), suas tarefas em running sã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 cada runners.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 encryption descreve um keyring com rótulos: keys inline (valor ou arquivo), ou um keys_folder onde cada arquivo é uma chave nomeada pelo nome do arquivo, além de ponteiros active para 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_file com keys_poll_interval (padrão 15s) recarrega o keyring a quente. Nova CLI: semaphore vaults check; semaphore vaults rekey foi reescrito em torno do keyring. O antigo access_key_encryption plano 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_FILTER seleciona quais subsistemas emitem saída de depuração, no estilo do debug do 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 senha exige a senha atual

  • 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 Secure quando 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 app do 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

Seletor de idioma com tcheco

  • 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

  1. BoltDB foi removido. bolt nã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.
  2. 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.
  3. As APIs de lista de tarefas são paginadas. GET /api/project/{id}/tasks/last aceita count e before; limit ainda é aceito, mas clientes que dependiam das 200 tarefas mais recentes em uma única resposta precisam paginar.
  4. Sem fallback para runners obsoletos. Com todos os runners offline, as tarefas permanecem na fila.
  5. Flag active do runner removida do registro.
  6. Os backups do projeto não contêm mais tokens de runner.
  7. SQLite: a v2.19.14 reconstrói as tabelas session e task para 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.

You might find this interesting