@cloud-cli/on 0.1.7 → 0.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +180 -0
  2. package/dist/on.js +620 -589
  3. package/package.json +1 -1
package/README.md ADDED
@@ -0,0 +1,180 @@
1
+ # Workflow Design
2
+
3
+ This is a task runner using webhooks to process incoming events.
4
+
5
+ Every event is sent to a daemon as an HTTP request, with a JSON body, and can trigger one or more workflows.
6
+ Every workflow is a set of steps, which can run on containers or in a shell on the host.
7
+
8
+ ## Running on Docker
9
+
10
+ - Steps run inside a docker container.
11
+ - All steps run in the same workspace folder.
12
+ - The current folder is mounted as a volume at /workspace by default. This can be changed by specifying a volume with `.` as the host path.
13
+
14
+ ## Running on the host machine
15
+
16
+ - Steps are sent as stdin to a shell subprocess
17
+
18
+ ## General configuration syntax
19
+
20
+ Running with Docker:
21
+
22
+ ```sh
23
+ curl -X POST http://localhost:11235/ -d '{ "event-name": {...} }'
24
+ ```
25
+
26
+ ```yaml
27
+ description: Run tests and build
28
+
29
+ vars: &vars
30
+ image: node:latest
31
+
32
+ on:
33
+ event-name:
34
+ runner: docker
35
+ if:
36
+ - ${inputs.action} == 'published'
37
+ secrets:
38
+ - /path/to/secrets
39
+ - /path/to/.env
40
+ mappings:
41
+ <field>: <path.to.value.in.inputs>
42
+ env:
43
+ A_SECRET: "${secrets.A_SECRET}"
44
+ A_VALUE: "${inputs.some.value}"
45
+ defaults:
46
+ <<: *vars
47
+ volumes:
48
+ .: /home
49
+ /dev/shm: /dev/shm
50
+ args:
51
+ net: host
52
+ dns: 1.2.3.4
53
+ steps:
54
+ - pnpm i
55
+ - pnpm run build
56
+ - pnpm run test
57
+ triggers:
58
+ - path/to/output.json
59
+ ```
60
+
61
+ Running with a shell on the same machine as the server:
62
+
63
+ ```sh
64
+ curl -X POST http://localhost:11235/ -d '{ "package": {...} }'
65
+ ```
66
+
67
+ ```yaml
68
+ description: Auto-release library
69
+ on:
70
+ event-name:
71
+ runner: shell
72
+ secrets:
73
+ - /path/to/secrets
74
+ - /path/to/.env
75
+ mappings:
76
+ <field>: <path.to.value.in.json.payload>
77
+ env:
78
+ A_SECRET: "${secrets.A_SECRET}"
79
+ A_VALUE: "${inputs.some.value}"
80
+ steps:
81
+ - pnpm i
82
+ - pnpm run build
83
+ - pnpm run release
84
+ triggers:
85
+ - path/to/output.json
86
+ ```
87
+
88
+ ### Event Payload
89
+
90
+ The webhooks can have any shape. To match events to workflows, we look for the top-level keys in the request body, and matching workflows that expect them to be present.
91
+
92
+ For example, given the request:
93
+
94
+ ```sh
95
+ curl -X POST http://localhost:11235/ -d '{ "published": { "value" : 123 } }'
96
+ ```
97
+
98
+ Then the workflow should map the `published` key:
99
+
100
+ ```yaml
101
+ on:
102
+ published:
103
+ steps:
104
+ - echo ${inputs.value}
105
+ ```
106
+
107
+ Here, the expression `inputs` in the workflow context is defined as the value set in the `published` key from the parsed JSON.
108
+ The expression `${inputs.value}` contains `123`.
109
+
110
+ To differentiate between events coming from the same place, multiple webhooks can be created.
111
+ The incoming webhook URL can have a path, and that is considered as the event source.
112
+
113
+ Consider this request:
114
+
115
+ ```sh
116
+ curl -X POST http://localhost:11235/source -d '{ "event": { "value" : 123 } }'
117
+ ```
118
+
119
+ The key `source` is added to the event payload. The workflow should now be defined as:
120
+
121
+ ```yaml
122
+ on:
123
+ source:
124
+ published:
125
+ steps:
126
+ - echo ${inputs.value}
127
+ ```
128
+
129
+ This difference in payload processing allows multiple webhooks from the same source, to separate different events with a similar JSON body.
130
+
131
+ ### Secrets
132
+
133
+ The daemon can fetch secrets from its host environment, or from a file.
134
+
135
+ ### Inputs
136
+
137
+ Inputs are defined from the incoming JSON payload. The payload is parsed and made available as the `inputs` variable
138
+
139
+ ### Mappings
140
+
141
+ These are shortcuts to make scripting easier.
142
+
143
+ After the JSON payload is parsed, these mappings are evaluated, and added to `inputs` as shortcuts for long/deep properties in the payload.
144
+
145
+ For example: from a GitHub webhook event that contains a lot of fields, we can define `image` from `package.package_version.package_url`
146
+
147
+ ```yaml
148
+ mappings:
149
+ image: ${inputs.package.package_version.package_url}
150
+ ```
151
+
152
+ ### Environment variables
153
+
154
+ After resolving secrets and mappings, we proceed to resolve env variables from template strings or literal strings.
155
+
156
+ An env variable is interpreted a JS template string, with `${value}` syntax used to interpolate values from `inputs` or `secrets`.
157
+
158
+ ## Sequence of operation
159
+
160
+ For every incoming event, these steps are followed:
161
+
162
+ - Parse and validate payload
163
+ - Load secrets
164
+ - Map inputs
165
+ - Populate env with secrets
166
+ - Populate env with additional workflow definitions (section `env`)
167
+ - Create a temporary working directory
168
+ - Add a volume to defaults at `/workspace`, or a custom path, if a volume with a host path `.` is defined in the workflow
169
+ - Run steps:
170
+ - For every step, either a string, or a step definition is accepted.
171
+ - If string, run with the defaults defined in the workflow
172
+ - If a definition, merge defaults into it, and run the step
173
+ - The step is a shell command, executed inside a short-lived container
174
+ - Trigger new events
175
+
176
+ ## Triggers
177
+
178
+ After steps are executed, a list of one or more JSON files can be defined to trigger new workflows.
179
+
180
+ These files are read one by one and sent back to the daemon as new events.