承認待ちのワークフロー実行

Semaphore UI 2.19 は 2.x 系列で最大のリリースです。グラフィカルエディターを備えた ワークフロー を導入し、 ランナーが Docker コンテナや Kubernetes Pod でタスクを実行できるようになり、実行中のタスクに 短命な JWT アイデンティティトークン を発行できるようになりました。さらに 暗号化キーのローテーション を追加し、 ランナーの信頼性の問題を根本的に修正し、多数のセキュリティ強化の変更を含んでいます。

この系列は v2.19.0 から v2.19.14 までのリリースを対象としています。パッチリリースは末尾に一覧があります。

ハイライト

  • ワークフロー (Beta) — 承認ゲート付きのパイプラインとしてタスクテンプレートを連結し、 グラフィカルエディターで描画して、同じキャンバス上でライブに監視できます。
  • Docker および Kubernetes エグゼキューター — ランナーが各タスクを新しいコンテナまたは Pod で実行できます (Pro / Enterprise)。
  • タスク向け JWT アイデンティティトークン — プレイブックから Vault、AWS、GCP、Azure、 その他 OIDC トークンを受け付けるあらゆるサービスへのキーレス認証。
  • 暗号化キーのローテーション — ラベル付きキーリング、ホットリロード、vaults check コマンド。
  • サーベイ変数の環境変数としての受け渡し、および inttext 型と再設計された enum 型。
  • タスク履歴の本格的なサーバーサイドページネーション — 数百万件のタスクを持つプロジェクトでも高速なままです。
  • ランナーの信頼性 — オンライン/オフラインステータス、ワンタイムのハッシュ化された登録トークン、 停止したランナーで滞留したタスクの自動リカバリー。
  • 選択的なデバッグログSEMAPHORE_DEBUG_FILTER による。
  • セキュリティ強化: 現在のパスワードの確認、CSRF オリジン検証、セキュアクッキー、 API 全体でのより厳密な入力検証。
  • BoltDB の削除 — SQLite、MySQL、PostgreSQL のみをサポート。

ワークフロー (Beta)

ワークフローとは、1 つの単位として実行されるタスクテンプレートのグラフです。各ノードは タスク (テンプレートを 実行)、承認 (ユーザーが承認または却下するまで実行を一時停止)、ノート (実行されない自由形式の 注釈) のいずれかです。エッジには条件があります: 成功時失敗時常に のいずれかです。

ワークフローは、プロジェクトのサイドバーに新しい ワークフロー 項目として表示され、Beta チップが付いています。 Pro エディションで利用可能ですが、ベータ期間中はプランに関係なく有効になっています。

グラフィカルエディター

ワークフローエディター

エディターは Drawflow をベースに構築されたフルページのキャンバスです:

  • パレットからノードをドラッグし、ノードのハンドルからドラッグして接続します;
  • エッジをクリックして条件を変更します; エッジは色分けされ、凡例が隅に表示されます;
  • ノードをクリックするとサイドパネルでプロパティを編集できます: テンプレート、収束モード (すべての親 / いずれかの親)、承認のタイムアウトとメッセージ、ノートのテキスト;
  • 自己エッジと循環は描画時に拒否され、問題 パネルがサーバーサイドの検証をミラーするため、 壊れたグラフは保存できません;
  • ノードの位置は保持されます; 位置を指定せずに API 経由で作成されたワークフローには、自動的に トポロジカルレイアウトが適用されます;
  • ツールバーまたは Ctrl + マウスホイールでズーム、キャンバスをドラッグしてパン、パレットを折りたたんで スペースを確保できます;
  • 開始バージョン は実行のバージョニング (1.4.01.4.1、…) の起点となります; バージョンは実行が 起動するすべてのタスクに伝播されます。

ノードのプロパティパネル

ライブ実行ビュー

実行ビューは同じキャンバスを再利用します。各ノードにはタスクのステータスが表示され、アクティブなノードはハイライトされ、 保留中の承認はキャンバス上に直接 承認 / 却下 ボタンとして表示されます。停止 ボタンは 実行中のすべてのタスクを強制停止し、保留中の承認を却下して、実行を stopped としてマークします。

ダークテーマの実行ビュー

実行ステータスは runningapprovalsuccessfailedstopped です。ワークフローの進行は サーバーによって駆動されます: いずれかのワークフロータスクが完了すると次のノードがスケジュールされるため、 自動実行の子を持たないテンプレートで実行が停滞することはなくなりました。

ワークフロー一覧

ノードごとのタスクパラメーター

すべてのタスクノードは、手動実行と同じように、テンプレートに渡すパラメーター (変数、インベントリ、ブランチ、 引数、バージョン、メッセージ) を上書きできます。

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}

ベータ版の既知の制限: ミニマップ、元に戻す/やり直し、複数選択はありません; ワークフローアーティファクト (set_stats の値) は、リモートランナーで実行されたタスク間ではまだ受け渡されません。


Docker および Kubernetes エグゼキューター (Pro / Enterprise)

ランナーは、ランナーホスト上で直接実行する代わりに、各タスクを隔離された環境で実行できます。 エグゼキューターはランナープロセスごとに runner.executor.type (localdockerk8s) で一度だけ選択します。

Docker (runner.executor.docker、Pro):

オプション 環境変数 デフォルト
host SEMAPHORE_RUNNER_DOCKER_HOST ローカルソケット
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):

オプション 環境変数 デフォルト
kubeconfig SEMAPHORE_RUNNER_K8S_KUBECONFIG クラスター内
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

CI により 2 つの新しいイメージが公開されます: semaphoreui/job (Ansible、Terraform、OpenTofu、Terragrunt、 paramiko) と semaphoreui/helper です。テンプレートは、テンプレートフォームの新しい エグゼキューターイメージ フィールドで自身のタスク用のイメージを上書きできます (エグゼキューター機能が ライセンスされていない場合は PRO にアップグレード バッジ付きで表示されます)。

ランナー接続には runner.connection.server_ca_cert_filerunner.connection.skip_tls_verify も追加されました。


タスク向け JWT アイデンティティトークン

Semaphore は実行中のタスクに対して OIDC 風のアイデンティティプロバイダーとして機能できるため、プレイブックは 長期的な認証情報なしで Vault、クラウドの STS エンドポイント、または内部サービスに対して認証できます。

テンプレートフォーム: JWT を含む詳細オプション

  • テンプレートごとに タスクランナーに JWT を発行 で有効化し、1 つ以上の オーディエンスTTL (jwt.max_ttl が上限) を設定します。
  • タスクは SEMAPHORE_JWT 環境変数でトークンを受け取ります。
  • トークンは ES256 (ECDSA P‑256) で署名され、ID のみを含みます: task_idproject_idtemplate_iduser_id に加えて、標準の isssubaudexpnbfiatjti クレーム。
  • 公開鍵は GET /.well-known/jwks.json で公開されます。

サーバー設定:

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

環境変数: SEMAPHORE_JWT_ENABLEDSEMAPHORE_JWT_ISSUERSEMAPHORE_JWT_DEFAULT_TTLSEMAPHORE_JWT_MAX_TTL


サーベイ変数

変数を環境変数として渡す

サーベイ変数に 変数の受け渡し方法 設定が追加されました: アプリ固有の CLI 方式 (Ansible では --extra-vars、 Terraform/OpenTofu では -var、シェルスクリプトでは CLI 引数) または プロセス環境変数 です。 変数名はそのまま使用されるため、Terraform ユーザーは単に TF_VAR_region と名付けるだけで済みます。 環境変数はプロセス一覧に表示されないため、シークレットにとってはより安全な選択肢です。

環境変数として渡されるサーベイ変数

新しい型

  • int — 検証付きの数値入力;
  • text — 複数行テキスト;
  • enum — 名前/値のペアとデフォルト値を持つ再設計されたエディター。

Enum サーベイ変数エディター

タスクダイアログは各型をそれに応じて表示します:

型付きサーベイ変数を含む新規タスクダイアログ

既存の survey_vars JSON に保存されます — マイグレーションは不要です。


テンプレートとタスク

  • 動的なプレイブックピッカー。 プレイブックファイルへのパス フィールドに、リポジトリ内で見つかった プレイブックが一覧表示されます (GET /api/project/{id}/repositories/{repository_id}/playbooks)。一覧は 選択されたブランチに追従し、リポジトリを読み取れない場合は自由入力にフォールバックします。

  • Ansible Galaxy インストールのスキップ — テンプレートごとのオプションで、タスクごとに上書きも可能です。 requirements.yml からのロールとコレクションのインストールをスキップします。

  • 変数グループでの型付き変数 (数値を含む):

    型付き変数を含む変数グループ

  • タスク履歴のページネーション。 履歴ページはこれまで最新の 200 件のタスクを取得してクライアント側で ページ送りしていたため、それより古いものにはアクセスできませんでした。バックエンドはキーセットカーソル (?count=20&before=<task_id>X-Has-Next レスポンスヘッダー) を使って 1 ページずつ返すようになり、COUNT(*)OFFSET も使いません。フッターには 1 ページあたりの行数 と前へ/次へのコントロールがあります。同じページネーションは テンプレートごとのタスク一覧とダッシュボードにも適用されます。

    サーバーサイドページネーション付きの履歴

  • タスク一覧の再読み込みは最大でも 5 秒に 1 回になりました; 冗長なリクエストがいくつか削除されました。

  • スケジュールはサーバーサイドの cron パーサーで検証されるため、クライアントとサーバーの解釈が食い違わなくなりました。

  • タスクでのブランチ上書きは、テンプレートが許可している場合にのみ受け付けられます。

  • Git 操作はリポジトリディレクトリごとに直列化されます。 並列タスクを許可 が有効なテンプレートは 1 つの作業コピーを共有しており、同時に実行される git pull / git checkout がそれを破損させる可能性がありました。更新と チェックアウトは、ローカル実行とランナー実行の両方で、インベントリリポジトリを含めて単一のクリティカル セクションを形成するようになりました。


ランナー

オンライン/オフラインステータス付きのランナーページ

  • ランナーページに、ハートビートの生存確認から導出される オンライン / オフラインステータス が表示されます。

  • ワンタイム登録トークン。 ランナーを先に UI で作成し、後から smrs_… トークンで登録できます。 トークンは一度だけ表示され、SHA‑256 ハッシュとしてのみ保存され、1 時間で期限切れになります。 ダイアログには環境変数、設定ファイル、Docker 用のコピーしてすぐ使えるコマンドが表示されます。トークンを再生成すると 登録済みのランナーがリセットされ、再登録できるようになります。

    ランナー登録トークンダイアログ

    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
    
  • ハングしたタスクのリカバリー。 ランナーはプロセスの開始時刻 (X-Runner-Started-At) を送信します。ポーリングを 停止したランナーは runners.offline_timeout_sec (120 秒) 後に オフライン としてマークされます: 新しいタスクは 割り当てられず、starting 状態のタスクは再割り当てされます。runners.task_fail_timeout_sec (420 秒) 後には、 running 状態のタスクが明確なメッセージとともに失敗扱いになります。再起動してメモリ内のジョブプールを失った ランナーは即座に検出されます。整合処理は runners.reconcile_interval_sec (30 秒) ごとに実行されます。

  • ランナーから再割り当てされたタスクは、元のランナー上で終了されます。

  • 古いランナーへのフォールバックは廃止されました: すべてのランナーがオフラインの場合、最大 30 分間ポーリングしていない ランナーにディスパッチされる代わりに、タスクはキューで待機します。

  • ランナーごとの RSA 暗号化キーを削除。 ランナーとサーバー間の通信は TLS に依存します; これにより登録と setup からキー交換ステップが削除されます。

  • ランナークライアントの TCP 接続リークを修正; 無効な登録トークンには 400 を返します。


シークレットと暗号化

  • 暗号化キーのローテーション。 新しい encryption ブロックはラベル付きキーリングを記述します: インラインの keys (値またはファイル)、またはファイル名をキー名とするファイルを格納した keys_folder、さらにシークレットキーと オプションキー用の active ポインター。暗号文にはキー ID が含まれるようになったため、一括再暗号化なしでキーを ローテーションできます。encryption.keys_filekeys_poll_interval (デフォルト 15s) によりキーリングをホットリロードします。新しい CLI: semaphore vaults check; semaphore vaults rekey は キーリングを中心に書き直されました。従来のフラットな access_key_encryption も引き続き機能します。
  • option_encryption — データベースに保存されるオプション用の別のキー。
  • OpenBao シークレットストレージタイプ (Vault プロバイダー経由でルーティング) と専用アイコン。
  • 静的な認証情報なしの AWS Secrets ManagerIAM ロールを使用 チェックボックス。
  • Vault/OpenBao ストレージ向けの TLS 検証スキップオプション。
  • 同期済みおよび読み取り専用のシークレットフィールドが更新時に消去されなくなりました。

オブザーバビリティ

  • 名前空間付きデバッグログ。 --debug-filter / SEMAPHORE_DEBUG_FILTER で、どのサブシステムが デバッグ出力を行うかを Node.js の debug 風に選択します: runnerrunner,task_pooltask_***,-db。 利用可能な名前空間: runnertask_pooltask_runnertask_loggergitterraformsessionldapscheduledbha。フィルターはログレベルが DEBUG のときにのみ適用され、 レベルを引き上げることはありません。Syslog フックも同じフィルターに従います。
  • ランナー、タスク、認証にわたって多数のコンテキスト付きデバッグ文を追加; 選択されたワークスペースが 起動時に出力されます。

セキュリティ

パスワード変更には現在のパスワードが必要

  • パスワードの変更に現在のパスワードが必要になりました (CWE‑620)。
  • 状態を変更するリクエストに対する Origin / Referer 検証 (CSRF 強化)。
  • HTTPS 経由で配信される場合、セッションクッキーに Secure が付与されます。
  • ランナー登録トークンはハッシュ化して保存され、期限切れになります; ランナーごとの暗号化キーは削除されました。
  • カスタムロールの作成時に呼び出し元の権限を確認します (権限昇格の修正)。
  • Git URL の検証; 細工された ref がフラグとして解釈されないように git に --end-of-options を渡します; コミットハッシュの形式チェック; リポジトリ閲覧前のブランチ検証; プレイブックパスの 検証。
  • アクセスキーのペイロードとテンプレートの app フィールドを検証します。
  • JWT クレームには ID のみが含まれます — 名前やメールアドレスが外部システムに漏れることはありません。
  • ランナートークンはプロジェクトのバックアップに書き込まれなくなりました。
  • API は書き込みエラー後に処理を継続せず、部分的に書き込まれたレスポンスを返さずに終了します。
  • セキュリティ SLA を SECURITY.md で公開; リリースアーティファクトは [email protected] の GPG キーで署名されています。

UI とローカライズ

チェコ語を含む言語選択

  • チェコ語 翻訳。
  • テンプレートフォームの JWT セクションとスケジュールセクション用のドロップダウンカード。
  • ライトモードでクリップボードにコピーするアイコンが表示されるように; 実行中タスクのスピナーを修正; テンプレートフォームの パディングを修正; ワークフローの Beta ラベル。
  • インテグレーション変数の抽出で、JSON オブジェクトと配列を文字列化せずにそのまま保持します。

アップグレードに関する注意事項

破壊的変更と動作の変更

  1. BoltDB は廃止されました。 bolt は有効なダイアレクトではなくなり、サーバーは “Bolt is not supported starting from version 2.19” というメッセージで起動を拒否します。先に SQLite、MySQL、または PostgreSQL に移行してください。
  2. ランナーの暗号化キーを削除。 サーバーとランナーの両方が 2.19 である必要があります。ランナーとサーバー間の 通信が TLS で保護されていることを確認してください。キーの存在を前提とするスクリプト化されたランナーのプロビジョニングは更新が必要です。
  3. タスク一覧 API はページネーションされます。 GET /api/project/{id}/tasks/lastcountbefore を受け取ります; limit も引き続き受け付けますが、1 回のレスポンスで最新 200 件のタスクを得ることに依存していたクライアントはページ送りが必要です。
  4. 古いランナーへのフォールバックの廃止。 すべてのランナーがオフラインの場合、タスクはキューに留まります。
  5. 登録から ランナーの active フラグを削除
  6. プロジェクトのバックアップにランナートークンが含まれなくなりました。
  7. SQLite: v2.19.14session テーブルと task テーブルを再構築 し、適切な外部キーを追加します (ユーザー削除を 修正)。孤立したセッションは削除されます。アップグレード前にデータベースをバックアップしてください。

新しい設定

jwtrunnersencryptionoption_encryptionsecrets_pathdb.dialectrunner.executor.{type,docker,k8s}runner.connection.{server_ca_cert_file,skip_tls_verify}runner.registration_token_filerunner.token_file。すべて省略可能で、既存の設定はそのまま 機能します。config.schema.yaml と設定リファレンスドキュメントは再生成されました。

データベースマイグレーション

v2.18.6 (テンプレートの jwt_params)、v2.18.15 (ワークフローテーブル)、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 (SQLite の session/task 再構築)。MariaDB 12.1 とのマイグレーション互換性を修正。


パッチリリース

バージョン 変更内容
2.19.8 SQLite マイグレーションを修正; ユーザー削除を修正 (session/task の外部キー); DB クエリで大文字小文字を区別しない文字列比較
2.19.9 SEMAPHORE_RUNNER_EXECUTOR_TYPE 環境変数; 設定の omitempty の整理
2.19.10 エグゼキューター設定の修正; Docker ビルドオプションの修正
2.19.11 選択されたワークスペースをログに出力; ヘルパーイメージの latest タグ; DB マイグレーションテスト
2.19.12 ランナー設定オプションの nil ポインターを修正; エラー伝播の修正
2.19.14 設定内の従来の secrets_path の処理を修正

依存関係

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。ドキュメントを git サブモジュールとして追加; THIRD-PARTY-LICENSES.md を再生成。

You might find this interesting