Files
wfe/CHANGELOG.md

239 lines
12 KiB
Markdown
Raw Normal View History

# Changelog
All notable changes to this project will be documented in this file.
## [1.9.0] - 2026-04-07
### Added
- **wfectl**: New command-line client for wfe-server with 17 subcommands
(login, logout, whoami, register, validate, definitions, run, get, list,
cancel, suspend, resume, publish, watch, logs, search-logs). Supports
OAuth2 PKCE login flow via Ory Hydra, direct bearer-token auth, and
configurable output formats (table/JSON).
- **wfectl validate**: Local YAML validation command that compiles workflow
files in-process via `wfe-yaml` with the full executor feature set
(rustlang, buildkit, containerd, kubernetes, deno). No server round-trip
or auth required — instant feedback before push.
- **Human-friendly workflow names**: `WorkflowInstance` now has a `name`
field (unique alongside the UUID primary key). The host auto-assigns
`{definition_id}-{N}` using a per-definition monotonic counter, with
optional caller override via `start_workflow_with_name` /
`StartWorkflowRequest.name`. All gRPC read/mutate APIs accept either the
UUID or the human name interchangeably. `WorkflowDefinition` now has an
optional display `name` declared in YAML (e.g. `name: "Continuous
Integration"`) that surfaces in listings.
- **wfe-server**: Full executor feature set enabled in the shipped binary —
kubernetes, deno, buildkit, containerd, rustlang step types all compiled
in.
- **wfe-server**: Dockerfile switched from `rust:alpine` to
`rust:1-bookworm` + `debian:bookworm-slim` runtime because `deno_core`'s
bundled v8 only ships glibc binaries.
- **wfe-ci**: New `Dockerfile.ci` builder image with rust stable,
cargo-nextest, cargo-llvm-cov, sccache, buildctl, kubectl, tea, git.
Used as the base image for kubernetes-executed CI steps.
- **wfe-kubernetes**: `run:` scripts now execute under `/bin/bash -c`
instead of `/bin/sh -c` so workflows can rely on `set -o pipefail`,
process substitution, arrays, and other bashisms dash doesn't support.
### Fixed
- **wfe**: `WorkflowHost::start()` now calls
`persistence.ensure_store_exists()`, which was previously defined but
never invoked — the Postgres/SQLite schema was never auto-created on
startup, causing `relation "wfc.workflows" does not exist` errors on
first run.
- **wfe-core**: `SubWorkflowStep` now inherits the parent workflow's data
when no explicit inputs are set, so child workflows see the same
top-level fields (e.g. `$REPO_URL`, `$COMMIT_SHA`) without every
`type: workflow` step having to re-declare them.
- **workflows.yaml**: Restructured all step references from
`<<: *ci_step` / `<<: *ci_long` (which relied on YAML 1.1 shallow merge
over-writing the `config:` block) to inner-config merges of the form
`config: {<<: *ci_config, ...}`. Secret env vars moved into the shared
`ci_env` anchor so individual steps don't fight the shallow merge.
## [1.8.1] - 2026-04-06
### Added
- **wfe-server**: gRPC reflection support via `tonic-reflection`
- **wfe-server**: Schema endpoints: `/schema/workflow.json` (JSON Schema), `/schema/workflow.yaml` (YAML Schema), `/schema/workflow.proto` (raw proto)
- **wfe-yaml**: Auto-generated JSON Schema from `schemars` derives on all YAML types
- **wfe-server**: Dockerfile for multi-stage alpine build with all executor features
- **wfe-server**: Comprehensive configuration reference (README.md)
### Fixed
- **wfe-yaml**: Added missing `license`, `repository`, `homepage` fields to Cargo.toml
- **wfe-buildkit-protos**: Removed vendored Go repos (166MB -> 356K), kept only .proto files
- **wfe-containerd-protos**: Removed vendored Go repos (53MB -> 216K), kept only .proto files
- Filesystem loop warnings from circular symlinks in vendored Go modules eliminated
- Pinned `icu_calendar <2.2` to work around `temporal_rs`/`deno_core` incompatibility
## [1.8.0] - 2026-04-06
### Added
- **wfe-kubernetes**: New crate -- Kubernetes executor for running workflow steps as K8s Jobs
- Namespace-per-workflow isolation with automatic cleanup
- Job manifest builder with env, resources, pull policy, node selector support
- Pod log streaming to LogSink with real-time output capture
- `##wfe[output key=value]` parsing from Job stdout
- Timeout handling with Job cleanup on expiry
- `KubernetesServiceProvider`: provisions infrastructure services as K8s Pods + Services with DNS resolution and readiness polling
- 100% test coverage on service provider, 91% overall crate coverage
- **wfe-core**: `ServiceDefinition`, `ServicePort`, `ReadinessProbe`, `ServiceEndpoint` types for declaring infrastructure services
- **wfe-core**: `ServiceProvider` trait for pluggable service provisioning
- **wfe-core**: `services` field on `WorkflowDefinition` for declaring required services
- **wfe**: Capability-based workflow routing -- hosts check `can_execute()` before accepting workflows
- Verifies all step types are registered in the StepRegistry
- Verifies ServiceProvider is configured and can provision required services
- Re-queues workflows that can't be handled by this host
- **wfe**: Service lifecycle in dequeue loop -- provision before execution, teardown after completion/failure
- **wfe**: `use_service_provider()` on `WorkflowHostBuilder`
- **wfe-containerd**: `ContainerdServiceProvider` for running services via containerd gRPC API on host network
- **wfe-yaml**: `services:` block in workflow YAML definitions with readiness probes (exec, tcp, http)
- **wfe-yaml**: `kubernetes`/`k8s` step type with lazy client creation
## [1.7.0] - 2026-04-05
### Added
- **wfe-deno**: New crate -- Deno/JS/TS bindings for the WFE workflow engine
- Full API surface via 23 deno_core ops: host lifecycle, workflow management, fluent builder, step registration, event publishing
- Channel-based execution bridge: JS step functions called from tokio executor via mpsc/oneshot channels
- High-level JS API classes: `WorkflowHost`, `WorkflowBuilder`, `ExecutionResult`
- 52 tests (26 unit + 26 integration), 93% line coverage
- **wfe-core**: `WorkflowBuilder.steps` and `last_step` fields now public
## [1.6.3] - 2026-04-05
### Fixed
- **wfe-core**: Propagate `step_name` into execution pointers when advancing to next steps, compensation steps, and parallel branch children
- **wfe**: Set `step_name` on initial execution pointer when starting a workflow instance
## [1.6.2] - 2026-04-05
### Added
- **wfe-core**: `WorkflowBuilder::add_step_typed()` for adding named, configured steps in parallel branch closures
- **wfe-core**: `WorkflowBuilder::wire_outcome()` now public for custom graph wiring
## [1.6.1] - 2026-04-05
### Added
- **wfe-core**: `StepBuilder::config()` for attaching arbitrary JSON configuration to individual steps, readable at runtime via `context.step.step_config`
## [1.6.0] - 2026-04-01
### Added
- **wfe-server**: Headless workflow server (single binary)
- gRPC API with 13 RPCs: workflow CRUD, lifecycle streaming, log streaming, log search
- HTTP webhooks: GitHub and Gitea with HMAC-SHA256 verification, configurable triggers
- OIDC/JWT authentication with JWKS discovery and asymmetric algorithm allowlist
- Static bearer token auth with constant-time comparison
- Lifecycle event broadcasting via `WatchLifecycle` server-streaming RPC
- Real-time log streaming via `StreamLogs` with follow mode and history replay
- Full-text log search via OpenSearch with `SearchLogs` RPC
- Layered config: CLI flags > env vars > TOML file
- **wfe-server-protos**: gRPC service definitions (tonic 0.14, server + client stubs)
- **wfe-core**: `LogSink` trait for real-time step output streaming
- **wfe-core**: Lifecycle publisher wired into executor (StepStarted, StepCompleted, Error, Completed, Terminated)
- **wfe**: `use_log_sink()` on `WorkflowHostBuilder`
- **wfe-yaml**: Shell step streaming mode with `tokio::select!` interleaved stdout/stderr
### Security
- JWT algorithm confusion prevention: derive algorithm from JWK, reject symmetric algorithms
- Constant-time static token comparison via `subtle` crate
- OIDC issuer HTTPS validation to prevent SSRF
- Fail-closed on OIDC discovery failure (server won't start with broken auth)
- Authenticated generic webhook endpoint
- 2MB webhook payload size limit
- Config parse errors fail loudly (no silent fallback to open defaults)
- Blocked sensitive env var injection (PATH, LD_PRELOAD, etc.) from workflow data
- Security regression tests for all critical and high findings
### Fixed
- Shell step streaming path now respects `timeout_ms` with `child.kill()` on timeout
- LogSink properly threaded from WorkflowHostBuilder through executor to StepExecutionContext
- LogStore.with_search() wired in server main.rs for OpenSearch indexing
- OpenSearch `index_chunk` returns Err on HTTP failure instead of swallowing it
- Webhook publish failures return 500 instead of 200
## [1.5.0] - 2026-03-29
### Added
- **wfe-rustlang**: New crate with Rust toolchain step executors
- Cargo steps: `cargo-build`, `cargo-test`, `cargo-check`, `cargo-clippy`, `cargo-fmt`, `cargo-doc`, `cargo-publish`
- External tool steps with auto-install: `cargo-audit`, `cargo-deny`, `cargo-nextest`, `cargo-llvm-cov`
- Rustup steps: `rust-install`, `rustup-toolchain`, `rustup-component`, `rustup-target`
- `cargo-doc-mdx`: generates MDX documentation from rustdoc JSON output using the `rustdoc-types` crate
- **wfe-yaml**: `rustlang` feature flag enabling all cargo/rustup step types
- **wfe-yaml**: Schema fields for Rust steps (`package`, `features`, `toolchain`, `profile`, `output_dir`, etc.)
- **wfe-containerd**: Remote daemon support via `WFE_IO_DIR` environment variable
- **wfe-containerd**: Image chain ID resolution from content store for proper rootfs snapshots
- **wfe-containerd**: Docker-default Linux capabilities for root containers
- Lima `wfe-test` VM config (Alpine + containerd + BuildKit, TCP socat proxy)
- Containerd integration tests running Rust toolchain in containers
### Fixed
- **wfe-containerd**: Empty rootfs — snapshot parent now resolved from image chain ID instead of empty string
- **wfe-containerd**: FIFO deadlock with remote daemons — replaced with regular file I/O
- **wfe-containerd**: `sh: not found` — use absolute `/bin/sh` path in OCI process spec
- **wfe-containerd**: `setgroups: Operation not permitted` — grant capabilities when running as UID 0
### Changed
- Lima `wfe-test` VM uses Alpine apk packages instead of GitHub release binaries
- Container tests use TCP proxy (`http://127.0.0.1:2500`) instead of Unix socket forwarding
- CI pipeline (`workflows.yaml`) updated with `wfe-rustlang` in test, package, and publish steps
879 tests. 88.8% coverage on wfe-rustlang.
## [1.4.0] - 2026-03-26
### Added
- Type-safe `when:` conditions on workflow steps with compile-time validation
- Full boolean combinator set: `all` (AND), `any` (OR), `none` (NOR), `one_of` (XOR), `not` (NOT)
- Task file includes with cycle detection
- Self-hosting CI pipeline (`workflows.yaml`) demonstrating all features
- `readFile()` op for deno runtime
- Auto-typed `##wfe[output]` annotations (bool, number conversion)
- Multi-workflow YAML files, SubWorkflow step type, typed input/output schemas
- HostContext for programmatic child workflow invocation
- BuildKit image builder and containerd container runner as standalone crates
- gRPC clients generated from official upstream proto files (tonic 0.14)
### Fixed
- Pipeline coverage step produces valid JSON, deno reads it with `readFile()`
- Host context field added to container executor test contexts
- `.outputs.` paths resolved flat for child workflows
- Pointer status conversion for Skipped in postgres provider
629 tests. 87.7% coverage.
## [1.0.0] - 2026-03-23
### Added
- **wfe-core**: Workflow engine with step primitives, executor, fluent builder API
- **wfe**: WorkflowHost, registry, sync runner, and purger
- **wfe-sqlite**: SQLite persistence provider
- **wfe-postgres**: PostgreSQL persistence provider
- **wfe-opensearch**: OpenSearch search index provider
- **wfe-valkey**: Valkey provider for locks, queues, and lifecycle events
- **wfe-yaml**: YAML workflow definitions with shell and deno executors
- **wfe-yaml**: Deno JS/TS runtime with sandboxed permissions, HTTP ops, npm support via esm.sh
- OpenTelemetry tracing support behind `otel` feature flag
- In-memory test support providers