vole
Clone
Read only, no credentials:
https://rodent.software/git/vole.git
Write over SSH with a registered key:
git clone ssh://git@0.0.0.0:2222/vole.git
A free and open-source forge that lives in your Git repo.
Say why workflows have no expression language
390e3404503477342ae434ef92e9ceb2729b7218 · Keenan Nemetz · 7d ago · parent e82bbe7d
Say why workflows have no expression language
The format has no `${{ }}` and no interpolation, but the reference listed that
only as a missing feature. The decision is now recorded where a reader will meet
it: the shell is the expression language, the event file is the context, and
event text stays data instead of becoming part of a command.
The reference gains a Context and expressions section with a manual-input
example, and the workflows guide says the same beside the trigger examples.
Part of #138.
docs/reference/workflow-reference.md +44−1
| @@ -687,6 +687,48 @@ Only one job in a workflow may declare `pages`. The target branch is set by the | |||
| 687 | 687 | instance (`pages_ref`), not by the workflow. The deploy is refused if the run is no | |
| 688 | 688 | longer the newest commit on its branch. See [Workflows § Publish a website](../workflows.md#publish-a-website). | |
| 689 | 689 | ||
| 690 | ## Context and expressions | ||
| 691 | |||
| 692 | A workflow file is not a template. There is no `${{ }}` and no substitution in a | ||
| 693 | step's `run`: `env` values are literal, a step executes the shell it is given, and | ||
| 694 | everything the run knows arrives as an environment variable, a declared secret, or | ||
| 695 | the event file. A manual input is read from the event file like any other event | ||
| 696 | data: | ||
| 697 | |||
| 698 | ```yaml | ||
| 699 | on: | ||
| 700 | workflow-dispatch: | ||
| 701 | inputs: | ||
| 702 | environment: | ||
| 703 | type: choice | ||
| 704 | options: [staging, production] | ||
| 705 | jobs: | ||
| 706 | deploy: | ||
| 707 | image: alpine:3.22 | ||
| 708 | steps: | ||
| 709 | - run: | | ||
| 710 | environment="$(jq -r '.inputs.environment' "$VOLE_EVENT_PATH")" | ||
| 711 | [ "$environment" = production ] || exit 0 | ||
| 712 | ./deploy.sh | ||
| 713 | ``` | ||
| 714 | |||
| 715 | `jq` is an example, not a dependency: the image is the dependency manifest, so | ||
| 716 | install the JSON reader the step uses. | ||
| 717 | |||
| 718 | This is a decision, not an unfinished feature: | ||
| 719 | |||
| 720 | - The shell is already the expression language. A second one would mean two ways | ||
| 721 | to write the same comparison, with its own parser, type rules, functions, and | ||
| 722 | escaping, all validated on every push. | ||
| 723 | - Event data is untrusted. A comment body, an issue title, or a manual input is | ||
| 724 | text someone else wrote; substituting it into `run` would turn data into code. | ||
| 725 | A file keeps it data, and the shell's quoting rules apply. | ||
| 726 | - A secret is a value, not a name to build. It already arrives as an environment | ||
| 727 | variable; an expression would invite it into a command line or a log line. | ||
| 728 | - The parts of a workflow that usually need expressions — `if`, `needs`, matrix | ||
| 729 | values, outputs — are not in the format. If they arrive, they can be typed | ||
| 730 | fields with their own small, checkable rules instead of a general language. | ||
| 731 | |||
| 690 | 732 | ## What a workflow cannot express | |
| 691 | 733 | ||
| 692 | 734 | The format deliberately supports push and event triggers with jobs of shell steps. | |
| @@ -696,7 +738,8 @@ It does not support: | |||
| 696 | 738 | - a build matrix or per-step conditions (`strategy`, `if`, `continue-on-error`) | |
| 697 | 739 | - step-scoped secrets, expressions for building a secret name, or a value written | |
| 698 | 740 | in the workflow file; secrets are job-scoped and the instance holds the values | |
| 699 | - expressions or contexts (`${{ }}`); nothing outside the shell is interpolated | ||
| 741 | - expressions or `${{ }}` contexts; the shell is the expression language and the | ||
| 742 | event file is the context. See [Context and expressions](#context-and-expressions). | ||
| 700 | 743 | - service containers, cache keys, or artifact downloads between jobs | |
| 701 | 744 | - job-level timeouts, concurrency groups, or cancel-in-progress | |
| 702 | 745 | - workflow-level `env`, working directories, or shells; `env` is per job and every | |