Complex scenarios, as one workflow.
Probe runs workflows defined in YAML. The definition looks like GitHub Actions, and the actions come built in: HTTP, DB, Shell, SSH, gRPC, SMTP, IMAP, Browser. The result of an action can be checked, so the same file serves for testing and monitoring too.
An example sign-up scenario
Create account posts the form and publishes the id that comes back. Database and Mailbox both depend on it, so Probe runs them at the same time — one asks SQLite for the row, the other opens the mailbox over IMAP. Activate waits for both before following the confirmation link.
1name: Sign-up Flow2 3vars:4 api: https://api.example.com5 mail_user: ada@example.com6 mail_pass: "{{MAIL_PASS}}"7 8jobs:9- name: Create account10 id: signup11 defaults:12 http:13 url: "{{vars.api}}"14 steps:15 - name: Post the form16 id: create17 uses: http18 with:19 post: /signup20 test: res.code == 201 && res.body.status == "pending"21 outputs:22 user_id: res.body.id23 24- name: Database25 id: db26 needs: [signup]27 defaults:28 db:29 dsn: file:./app.db30 steps:31 - name: Row is pending32 uses: db33 with:34 query: SELECT status FROM users WHERE id = ?35 params: ["{{outputs.create.user_id}}"]36 test: res.code == 0 && res.rows[0].status == "pending"37 38- name: Mailbox39 id: mailbox40 needs: [signup]41 defaults:42 imap:43 host: imap.example.com44 username: "{{vars.mail_user}}"45 password: "{{vars.mail_pass}}"46 steps:47 - name: Confirmation arrived48 uses: imap49 with:50 commands:51 - name: select52 mailbox: INBOX53 - name: fetch54 sequence: "1"55 dataitem: ALL56 test: |57 res.code == 0 &&58 res.data.fetch.messages[0].subject == "Confirm your address" &&59 res.data.fetch.messages[0].to == vars.mail_user60 61- name: Activate62 needs: [db, mailbox]63 defaults:64 http:65 url: "{{vars.api}}"66 steps:67 - name: Follow the link68 uses: http69 with:70 get: "/users/{{outputs.create.user_id}}"71 test: res.code == 200 && res.body.status == "active"
Sign-up Flow ⏺ Create account (Completed in 0.11s) ⎿ 0. ✓ Post the form ⏺ Database (Completed in 0.02s) ⎿ 0. ✓ Row is pending ⏺ Mailbox (Completed in 0.03s) ⎿ 0. ✓ Confirmation arrived ⏺ Activate (Completed in 0.01s) ⎿ 0. ✓ Follow the link Total workflow time: 0.15s ✓ All jobs succeeded
What a workflow is made of
A workflow is a set of jobs, and a job is a sequence of steps. Steps run one after another, in the order you wrote them. Jobs run in parallel by default; only the ones with needs wait for what they depend on. Add repeat to a job and the same file runs on an interval and reports a success rate.
Supported actions
A step names an action in uses, and Probe starts that action as its own process and talks to it over gRPC. The built-in actions go through exactly the same handshake an out-of-tree plugin does, so none of them is a special case. What Probe cannot reach yet, you can add.
What a step can say
Whatever action a step names, these fields are available to it.
test
A step passes when the expression is true. Everything about the response is in scope.
1test: res.code == 200 && res.body.status == "ok"outputs
Name a value once, then read it from any later step or job.
1outputs:2 token: res.body.access_token
iteration
Run one step once per set of variables, without copying it.
1iteration:2- {name: Alice, role: admin}3- {name: Bob, role: user}
retry
Give a flaky step another go, after a pause.
1retry:2 max_attempts: 33 interval: 5s
skipif
Leave the step out when the condition holds.
1skipif: vars.env == "local"wait
Pause before the step runs, for whatever has to settle first.
1wait: 5sInstall
Probe is a single Go binary with no runtime dependencies.
$ go install github.com/linyows/probe/cmd/probe@latestOr build from source
git clone https://github.com/linyows/probe.git cd probe go build -o probe ./cmd/probe