Esecuzione di workflow in attesa di approvazione

Semaphore UI 2.19 è la release più grande della linea 2.x. Introduce i Workflow con un editor grafico, consente ai runner di eseguire le attività in container Docker e pod Kubernetes, insegna a Semaphore a emettere token di identità JWT di breve durata per le attività in esecuzione, aggiunge la rotazione delle chiavi di crittografia, risolve definitivamente l’affidabilità dei runner e include una lunga lista di interventi di hardening della sicurezza.

La linea copre le release da v2.19.0 a v2.19.14. Le release correttive sono elencate alla fine.

Novità principali

  • Workflow (Beta) — concatena i modelli di attività in una pipeline con punti di approvazione, disegnata in un editor grafico e seguita in tempo reale sulla stessa tela.
  • Esecutori Docker e Kubernetes — i runner possono eseguire ogni attività in un container o pod nuovo (Pro / Enterprise).
  • Token di identità JWT per le attività — autenticazione senza chiavi dai playbook verso Vault, AWS, GCP, Azure e qualsiasi altro servizio che accetti token OIDC.
  • Rotazione delle chiavi di crittografia — un keyring etichettato con ricaricamento a caldo e un comando vaults check.
  • Variabili di survey come variabili d’ambiente, più i tipi int, text e un enum rinnovato.
  • Vera paginazione lato server della cronologia delle attività — i progetti con milioni di attività restano veloci.
  • Affidabilità dei runner — stato online/offline, token di registrazione monouso con hash e ripristino automatico delle attività bloccate su un runner morto.
  • Logging di debug selettivo con SEMAPHORE_DEBUG_FILTER.
  • Hardening della sicurezza: verifica della password attuale, validazione dell’origine CSRF, cookie sicuri, validazione più rigorosa degli input in tutta l’API.
  • BoltDB rimosso — solo SQLite, MySQL e PostgreSQL.

Workflow (Beta)

Un workflow è un grafo di modelli di attività che viene eseguito come un’unica unità. Ogni nodo è un’attività (esegue un modello), un’approvazione (sospende l’esecuzione finché un utente non approva o rifiuta) oppure una nota (annotazione libera che non viene mai eseguita). Gli archi portano una condizione: in caso di successo, in caso di errore o sempre.

I Workflow compaiono come nuova voce Workflow nella barra laterale del progetto, contrassegnata da un’etichetta Beta. Sono disponibili nell’edizione Pro; durante la beta sono abilitati indipendentemente dal piano.

Editor grafico

Editor dei workflow

L’editor è una tela a pagina intera costruita su Drawflow:

  • trascina i nodi dalla palette e collegali trascinando da una maniglia del nodo;
  • fai clic su un arco per cambiarne la condizione; gli archi sono codificati per colore e una legenda si trova nell’angolo;
  • fai clic su un nodo per modificarne le proprietà nel pannello laterale: modello, modalità di convergenza (tutti i genitori / qualsiasi genitore), timeout e messaggio di approvazione, testo della nota;
  • gli archi su sé stessi e i cicli vengono rifiutati mentre li disegni, e un pannello Problemi rispecchia la validazione lato server, così un grafo non valido non può essere salvato;
  • le posizioni dei nodi vengono salvate; i workflow creati tramite API senza posizioni ricevono un layout topologico automatico;
  • zoom con la barra degli strumenti o Ctrl + rotellina del mouse, trascina la tela per spostarti, comprimi la palette per guadagnare spazio;
  • Versione iniziale avvia il versionamento delle esecuzioni (1.4.0, 1.4.1, …); la versione viene propagata a ogni attività avviata dall’esecuzione.

Pannello delle proprietà del nodo

Vista dell’esecuzione in tempo reale

La vista dell’esecuzione riutilizza la stessa tela. Ogni nodo mostra lo stato della propria attività, il nodo attivo è evidenziato e le approvazioni in sospeso mostrano i pulsanti Approva / Rifiuta direttamente sulla tela. Un pulsante Ferma interrompe forzatamente ogni attività dell’esecuzione, rifiuta le approvazioni in sospeso e contrassegna l’esecuzione come stopped.

Vista dell'esecuzione con tema scuro

Gli stati dell’esecuzione sono running, approval, success, failed e stopped. L’avanzamento del workflow è guidato dal server: quando una qualsiasi attività del workflow termina, i nodi successivi vengono pianificati, quindi un modello senza figli in autorun non blocca più l’esecuzione.

Elenco dei workflow

Parametri dell’attività per nodo

Ogni nodo attività può sovrascrivere i parametri che passa al proprio modello (variabili, inventario, branch, argomenti, versione, messaggio), esattamente come un’esecuzione manuale.

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}

Limitazioni note della beta: nessuna minimappa, annulla/ripeti o selezione multipla; gli artefatti del workflow (valori set_stats) non fluiscono ancora tra le attività eseguite su runner remoti.


Esecutori Docker e Kubernetes (Pro / Enterprise)

I runner possono eseguire ogni attività in un ambiente isolato invece che direttamente sull’host del runner. L’esecutore viene selezionato una volta per processo runner con runner.executor.type (local, docker, k8s).

Docker (runner.executor.docker, Pro):

Opzione Variabile d’ambiente Predefinito
host SEMAPHORE_RUNNER_DOCKER_HOST socket locale
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):

Opzione Variabile d’ambiente Predefinito
kubeconfig SEMAPHORE_RUNNER_K8S_KUBECONFIG in‑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

La CI pubblica due nuove immagini: semaphoreui/job (Ansible, Terraform, OpenTofu, Terragrunt, paramiko) e semaphoreui/helper. Un modello può sovrascrivere l’immagine per le proprie attività con il nuovo campo Immagine dell’esecutore nel modulo del modello (mostrato con un badge Passa a PRO quando la funzionalità esecutore non è coperta dalla licenza).

La connessione del runner ha inoltre acquisito runner.connection.server_ca_cert_file e runner.connection.skip_tls_verify.


Token di identità JWT per le attività

Semaphore può agire come identity provider in stile OIDC per le attività in esecuzione, così un playbook può autenticarsi verso Vault, endpoint STS cloud o servizi interni senza credenziali di lunga durata.

Modulo del modello: opzioni avanzate con JWT

  • Abilitalo per modello con Emetti JWT al task runner; imposta una o più audience e un TTL (limitato da jwt.max_ttl).
  • L’attività riceve il token nella variabile d’ambiente SEMAPHORE_JWT.
  • I token sono firmati ES256 (ECDSA P‑256) e contengono solo ID: task_id, project_id, template_id, user_id più i claim standard iss, sub, aud, exp, nbf, iat, jti.
  • Le chiavi pubbliche sono pubblicate su GET /.well-known/jwks.json.

Configurazione del server:

"jwt": {
  "enabled": true,
  "issuer": "https://semaphore.example.com",
  "default_ttl": "1h",
  "max_ttl": "24h"
}

Variabili d’ambiente: SEMAPHORE_JWT_ENABLED, SEMAPHORE_JWT_ISSUER, SEMAPHORE_JWT_DEFAULT_TTL, SEMAPHORE_JWT_MAX_TTL.


Variabili di survey

Passare una variabile come variabile d’ambiente

Una variabile di survey ora ha un’impostazione Passa la variabile come: la modalità CLI specifica dell’applicazione (--extra-vars per Ansible, -var per Terraform/OpenTofu, un argomento CLI per gli script shell) oppure una variabile d’ambiente del processo. Il nome della variabile viene usato letteralmente, quindi un utente Terraform la chiama semplicemente TF_VAR_region. Le variabili d’ambiente non compaiono negli elenchi dei processi, il che le rende la scelta più sicura per i secret.

Variabile di survey passata come variabile d'ambiente

Nuovi tipi

  • int — input numerico con validazione;
  • text — testo multiriga;
  • enum — editor rinnovato con coppie nome/valore e un valore predefinito.

Editor della variabile di survey enum

La finestra di dialogo dell’attività mostra ogni tipo di conseguenza:

Finestra di nuova attività con variabili di survey tipizzate

Salvate nel JSON survey_vars esistente — nessuna migrazione necessaria.


Modelli e attività

  • Selettore dinamico del playbook. Il campo Percorso del file playbook elenca i playbook trovati nel repository (GET /api/project/{id}/repositories/{repository_id}/playbooks). L’elenco segue il branch selezionato e ripiega sul testo libero quando il repository non può essere letto.

  • Salta l’installazione di Ansible Galaxy — opzione per modello, sovrascrivibile facoltativamente per attività, per saltare l’installazione di ruoli e collection da requirements.yml.

  • Variabili tipizzate nei gruppi di variabili, numeri inclusi:

    Gruppo di variabili con variabili tipizzate

  • Paginazione della cronologia delle attività. La pagina Cronologia recuperava le 200 attività più recenti e le sfogliava lato client, quindi tutto ciò che era più vecchio risultava irraggiungibile. Il backend ora restituisce una pagina alla volta usando un cursore keyset (?count=20&before=<task_id>, header di risposta X-Has-Next) senza COUNT(*) e senza OFFSET. Il piè di pagina offre Righe per pagina e i controlli precedente/successivo. La stessa paginazione si applica all’elenco delle attività per modello e alla dashboard.

    Cronologia con paginazione lato server

  • Gli elenchi delle attività si ricaricano al massimo una volta ogni 5 secondi; diverse richieste ridondanti sono state rimosse.

  • Le pianificazioni vengono validate con il parser cron lato server, così client e server non sono più in disaccordo.

  • La sovrascrittura del branch in un’attività è accettata solo quando il modello lo consente.

  • Le operazioni Git sono serializzate per directory del repository. I modelli con Consenti attività parallele condividono un’unica copia di lavoro, e git pull / git checkout concorrenti potevano corromperla. Aggiornamento e checkout formano ora un’unica sezione critica, sia per l’esecuzione locale sia su runner, inclusi i repository degli inventari.


Runner

Pagina dei runner con stato online/offline

  • Stato online / offline nella pagina Runner, derivato dalla vitalità dell’heartbeat.

  • Token di registrazione monouso. Un runner può essere creato prima nella UI e registrato in seguito con un token smrs_… che viene mostrato una sola volta, memorizzato solo come hash SHA‑256 e scade dopo un’ora. La finestra di dialogo mostra comandi pronti da copiare per variabili d’ambiente, file di configurazione e Docker. Rigenerare il token reimposta un runner già registrato, così può essere registrato di nuovo.

    Finestra del token di registrazione del 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
    
  • Ripristino delle attività bloccate. I runner inviano l’ora di avvio del proprio processo (X-Runner-Started-At). Un runner che smette di interrogare il server viene contrassegnato offline dopo runners.offline_timeout_sec (120 s): non riceve nuove attività e le sue attività starting vengono riassegnate. Dopo runners.task_fail_timeout_sec (420 s) le sue attività running vengono fatte fallire con un messaggio chiaro. Un runner che si è riavviato e ha perso il proprio pool di job in memoria viene rilevato immediatamente. La riconciliazione viene eseguita ogni runners.reconcile_interval_sec (30 s).

  • Le attività riassegnate da un runner vengono terminate sul vecchio runner.

  • Il fallback ai runner obsoleti è stato rimosso: quando tutti i runner sono offline, le attività attendono in coda invece di essere inviate a un runner che non ha interrogato il server per fino a 30 minuti.

  • Chiavi di crittografia RSA per runner rimosse. Il traffico runner‑server si affida a TLS; questo elimina il passaggio di scambio delle chiavi dalla registrazione e da setup.

  • Corretta una perdita di connessioni TCP nel client del runner; i token di registrazione non validi restituiscono 400.


Secret e crittografia

  • Rotazione delle chiavi di crittografia. Il nuovo blocco encryption descrive un keyring etichettato: keys inline (valore o file), oppure una keys_folder in cui ogni file è una chiave con il nome del file, più puntatori active per la chiave dei secret e la chiave delle opzioni. Il testo cifrato ora contiene un ID di chiave, quindi le chiavi possono essere ruotate senza una ricifratura totale. encryption.keys_file con keys_poll_interval (predefinito 15s) ricarica a caldo il keyring. Nuova CLI: semaphore vaults check; semaphore vaults rekey è stato riscritto attorno al keyring. Il vecchio access_key_encryption piatto continua a funzionare.
  • option_encryption — una chiave separata per le opzioni memorizzate nel database.
  • Tipo di archiviazione dei secret OpenBao (instradato tramite il provider Vault) con icona propria.
  • AWS Secrets Manager senza credenziali statiche — una casella di controllo Usa ruolo IAM.
  • Opzione per saltare la verifica TLS per le archiviazioni Vault/OpenBao.
  • I campi dei secret sincronizzati e in sola lettura non vengono più cancellati all’aggiornamento.

Osservabilità

  • Logging di debug con namespace. --debug-filter / SEMAPHORE_DEBUG_FILTER seleziona quali sottosistemi emettono output di debug, nello stile di debug di Node.js: runner, runner,task_pool, task_*, *, *,-db. Namespace disponibili: runner, task_pool, task_runner, task_logger, git, terraform, session, ldap, schedule, db, ha. Il filtro si applica solo quando il livello di log è DEBUG; non alza mai il livello. Gli hook syslog rispettano lo stesso filtro.
  • Molte nuove istruzioni di debug contestuali tra runner, attività e autenticazione; il workspace selezionato viene stampato all’avvio.

Sicurezza

Il cambio password richiede la password attuale

  • Cambiare la password ora richiede la password attuale (CWE‑620).
  • Validazione di Origin / Referer sulle richieste che modificano lo stato (hardening CSRF).
  • I cookie di sessione sono contrassegnati Secure quando serviti tramite HTTPS.
  • I token di registrazione dei runner sono memorizzati con hash e scadono; le chiavi di crittografia per runner sono state rimosse.
  • La creazione di ruoli personalizzati verifica i permessi del chiamante (correzione di escalation dei privilegi).
  • Validazione degli URL Git; --end-of-options viene passato a git così un ref costruito ad arte non può essere letto come flag; gli hash dei commit vengono controllati nel formato; i branch vengono validati prima della navigazione del repository; i percorsi dei playbook vengono validati.
  • I payload delle chiavi di accesso e il campo app del modello vengono validati.
  • I claim JWT contengono solo ID — nessun nome o e‑mail trapela verso sistemi esterni.
  • I token dei runner non vengono più scritti nei backup del progetto.
  • L’API termina dopo un errore di scrittura invece di continuare con una risposta parzialmente scritta.
  • SLA di sicurezza pubblicato in SECURITY.md; gli artefatti delle release sono firmati con la chiave GPG [email protected].

UI e localizzazione

Selettore della lingua con il ceco

  • Traduzione in ceco.
  • Schede a discesa per le sezioni JWT e pianificazione del modulo del modello.
  • L’icona copia negli appunti è visibile in modalità chiara; corretti gli spinner delle attività in esecuzione; corretto il padding del modulo del modello; etichetta Beta dei workflow.
  • L’estrazione delle variabili delle integrazioni preserva oggetti e array JSON invece di convertirli in stringhe.

Note di aggiornamento

Modifiche incompatibili e di comportamento

  1. BoltDB non c’è più. bolt non è più un dialetto valido; il server rifiuta di avviarsi con “Bolt is not supported starting from version 2.19”. Migra prima a SQLite, MySQL o PostgreSQL.
  2. Chiavi di crittografia dei runner rimosse. Server e runner devono essere entrambi alla 2.19. Assicurati che il traffico runner‑server sia protetto da TLS. Il provisioning automatizzato dei runner che si aspettava la chiave deve essere aggiornato.
  3. Le API degli elenchi di attività sono paginate. GET /api/project/{id}/tasks/last accetta count e before; limit è ancora accettato, ma i client che contavano sulle 200 attività più recenti in un’unica risposta devono paginare.
  4. Nessun fallback ai runner obsoleti. Con tutti i runner offline, le attività restano in coda.
  5. Flag active del runner rimosso dalla registrazione.
  6. I backup del progetto non contengono più i token dei runner.
  7. SQLite: v2.19.14 ricostruisce le tabelle session e task per aggiungere chiavi esterne corrette (corregge l’eliminazione degli utenti). Le sessioni orfane vengono rimosse. Esegui un backup del database prima di aggiornare.

Nuova configurazione

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. Sono tutti facoltativi; le configurazioni esistenti continuano a funzionare. config.schema.yaml e la documentazione di riferimento della configurazione sono stati rigenerati.

Migrazioni del database

v2.18.6 (jwt_params del modello), v2.18.15 (tabelle dei 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 (ricostruzione di session/task in SQLite). Corretta la compatibilità delle migrazioni con MariaDB 12.1.


Release correttive

Versione Modifiche
2.19.8 Corretta la migrazione SQLite; corretta l’eliminazione degli utenti (chiavi esterne session/task); confronto di stringhe senza distinzione tra maiuscole e minuscole nelle query DB
2.19.9 Variabile d’ambiente SEMAPHORE_RUNNER_EXECUTOR_TYPE; pulizia degli omitempty nella configurazione
2.19.10 Correzione della configurazione dell’esecutore; correzione dell’opzione di build Docker
2.19.11 Workspace selezionato stampato nei log; tag latest per l’immagine helper; test delle migrazioni DB
2.19.12 Corretto un puntatore nil nelle opzioni di configurazione del runner; correzione della propagazione degli errori
2.19.14 Corretta la gestione del vecchio secrets_path nella configurazione

Dipendenze

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. Documentazione aggiunta come sottomodulo git; THIRD-PARTY-LICENSES.md rigenerato.

You might find this interesting