# The Build Configuration Stays Expressible as Forgejo Actions **Status:** - proposed: 2026-10-03 - accepted: 2026-10-03 - rejected: - - superseded: - **Decision [accepted]:** Werkator's build configuration moves towards the Forgejo Actions workflow format. From now on, a key or concept is added to a build definition only when a Forgejo Actions workflow can express it. A feature request that a workflow cannot express is reshaped until one can, or it is turned down. The first step is [RFC 0006](../rfcs/0006-one-workflow-for-forgejo-and-werkator.md): a developer can write one workflow for their own project that runs on Forgejo and on Werkator unchanged. This ADR records the direction and the rule, not an implementation. ## Context and Problem Statement Werkator has its own configuration format: `.werkator.yml` with named `builds`, each with a `trigger` block (ADR 0007). Forgejo and Gitea ship Forgejo Actions and Gitea Actions, both of them dialects of the GitHub Actions workflow format. A project that wants to build on both, or move from one to the other, has to describe its CI twice today and keep the two in step. Every new key in `.werkator.yml` widens the gap, unless it is chosen with the workflow format in mind. The gap is cheap to avoid while it is small, and expensive to close once it is large. Full compatibility is not the goal: running arbitrary foreign workflows needs an action runtime (`uses:`), an expression language and an artifact and cache server, which is what forgejo-runner is, and is not what a lightweight CI is. ### Technical Background Most of today's build definition already has a workflow counterpart: | Werkator | Forgejo Actions | | ---------------------------------------------------------- | -------------------------------------- | | a build definition | a job | | `trigger.onPush`, `trigger.branches` (globs, `!` excludes) | `on.push.branches` | | `trigger.atTimes` (daily `HH:MM` UTC) | `on.schedule` with `cron: "M H * * *"` | | `trigger.afterSuccessOf` | `needs` | | `buildCommand`, `cleanCommand` | `steps[].run` | | `artifactDirs` | `actions/upload-artifact` with `path` | | `docker.image` | `container.image` | | `docker.env` | `container.env`, `env` | | `timeout` | `timeout-minutes` | Some existing concepts have no counterpart, and stay what they are: - `trigger.activeWithin` — no workflow filter on the age of a branch head. - `docker.dockerfile` and `docker.context` — a workflow names a prebuilt image; Werkator builds it from the repository. - `stdoutLog`, `stderrLog`, and the retention keys — they shape Werkator's own storage, not the build. Host-side configuration is outside the rule. In Forgejo terms, it is the runner's and the instance's configuration, not the workflow's: `server`, `executor`, `watcher`, `gitea`, `git`, `metrics`, the registry, and the pinned sandbox and trust policy (`docker.enabled`, `docker.network`, `docker.socket`, `werkdock.*`, `requirePullRequest`, `statusContext`, `restartsInstance`). A new host-side key needs no workflow counterpart. ## Considered Options * Constrain the build configuration to what a workflow can express — chosen * Keep the own format free * Replace the own format by the workflow format now ### Constrain the Build Configuration Good: - The gap stops growing, and closing it later stays possible. - A feature request gets checked against a format that many developers already know. - No code changes now; the rule costs a question per new key. Bad: - Some features have to be reshaped, or fall away. - The existing deviations listed above remain until somebody decides about them. ### Keep the Own Format Free Good: - Every feature can take the shape that suits Werkator best. Bad: - Each new key makes a shared workflow less likely, and none of them is ever paid back. ### Replace the Own Format Now Good: - One format, no translation. Bad: - Without `uses:`, expressions and matrix support, most real workflows would still not run, and with them Werkator becomes a second forgejo-runner. - Every existing `.werkator.yml` would have to be migrated, for no gain on the hosts that run Werkator today. ## Decision Outcome The build configuration is constrained to what a Forgejo Actions workflow can express. Before a new key or concept goes into a build definition, its design names the workflow construct it corresponds to. If there is none, the feature is reshaped until there is one, or it stays out; a host-side key is exempt. RFC 0006 describes the first step: a defined subset of the workflow format that Werkator reads, so that one file serves both systems for projects that write it on purpose.