Repository navigation
v1.18.0
Highlights
- A template that cannot be evaluated now fails the step, instead of sending the error text to the action. This can change the result of an existing workflow.
- Workflow
varscan read other vars. - A background
shellstep waits until the command is ready, withready.log. httptakesbasic_auth, andshellandsshdecode JSON output intores.jsonand reportres.timed_out.- For library users: the packages of the built-in actions moved under
actions/.
A template that cannot be evaluated fails the step
A template that does not parse or fails while it runs used to be replaced by the error text, such as [RuntimeError: cannot fetch token from <nil>], and that text was sent to the action as a URL, a header or a command. Now the step fails before the action runs, and the error names the value and the template. This can change the result of an existing workflow.
headers:
# Fails the step when no earlier step published outputs.login
authorization: "Bearer {{outputs.login.token}}"
# Falls back instead
# authorization: "Bearer {{outputs.login?.token ?? 'none'}}"- In a step's
with,varsorname: the step fails with the new failure kindtemplate, and Probe exits with status 1. - In a workflow's
vars: the run stops before the first job with exit status 2. - In
echo: the error is shown in place of the text, and the step's result does not change. - A name that is not defined still reads as nil and is not an error, so
vars.none ?? 'x'works as before. - When the failing value is a credential, such as
with.password, the error names the value but leaves out the reason, since the template or the error could contain the credential.
See Expressions and Templates and the failure kinds in the CLI reference.
Workflow vars can read other vars
A var can read another var as vars.<name>, in any order within the vars block. Each var is evaluated once, after the vars it reads, so a random value is the same in every var built from it.
vars:
http_port: "{{HTTP_PORT ?? '18080'}}"
base: "http://localhost:{{vars.http_port}}"
password: "{{PASSWORD ?? random_str(24)}}"
basic_auth: "Basic {{encode_base64('alice:' + vars.password)}}"- A var that reads itself, directly or through other vars, stops the run before the first job with an error such as
vars: circular reference: a -> b -> a. - A list at the top level of
varsnow has its templates evaluated, as a list inside a map already did.
See vars.
Wait for a background command to be ready
A background shell step now takes ready.log, the text the command writes once it is ready. The step returns when that text appears in stdout or stderr, so the next step can use the server without retrying.
- name: Start the server
uses: shell
with:
cmd: python3 -u -m http.server 8080 --bind 127.0.0.1
background: true
ready:
log: Serving HTTP
test: status == -1- If the command exits first, the step fails with its exit code in
res.codeand its output inres.stdout. Iftimeout(default30s) passes first, the step fails withres.timed_outset totrue, and the command is stopped. - The text is matched as plain text, not as a pattern.
- A program that buffers its output when not writing to a terminal, such as Python, has to be told to write at once, as with
python3 -u.
See ready.
HTTP Basic authentication
The http action takes basic_auth with a username and a password and builds the Authorization header from them.
defaults:
http:
url: "{{vars.api_url}}"
basic_auth:
username: "{{vars.admin_user}}"
password: "{{vars.admin_password}}"- The request is refused before it is sent when the username is missing or contains a colon, when
basic_authhas another key, or when anauthorizationheader is also given. - The password and the header built from it are hidden in the output.
See the http action.
JSON output of a command as res.json
When the whole of a command's stdout is one JSON object or array, shell and ssh also decode it into res.json, so expressions no longer need parse_json(res.stdout).
test: res.code == 0 && res.json.count == 1
outputs:
id: res.json.emails[0].idres.stdoutstill holds the text. Any other output, such as plain text, a single number or JSON Lines, leavesres.jsonunset (nil).- This also applies to an external action that returns
stdout, unless it setsjsonitself.
See the shell action and the ssh action.
Command timeouts in shell and ssh
A command stopped at its timeout now sets res.timed_out to true and keeps what it wrote until then in res.stdout and res.stderr. It is still a result, not an action error.
shell:res.codeis-1. The timeout now holds when the command has started a process that keeps the output open, assleep 30 & echo donedoes; such a step used to wait for that process.ssh:res.codeis the status the command exits with afterSIGTERM. A command still running 5 seconds later givesres.code-1with the output read so far, where it used to be an action error without output.
Passwords hidden wherever Probe shows them
Credentials passed to an action are now hidden in --verbose output, in the request printed for a failed step and in the action's log records, even when they are not listed in secrets.
- The value of any
passwordorkey_passphrasefield at any depth ofwith, including a password written as a number. - The password in a database URL such as
postgres://app:secret@db/main, as written and percent-decoded. The rest of the URL stays visible. - A long token or password is hidden before an action's log shortens values to 200 bytes, so its first part no longer shows.
See secrets.
Fixes
probe daglooks for an embedded job file in the working directory, as the run does, instead of first looking next to the workflow file.- A job that could not start, because a step is invalid or its name cannot be evaluated, now prints why.
- A step in a job with
repeatkeeps why its first failing iteration failed, so a JSON report keeps the kind and JUnit reports an<error>for an action or template failure instead of a<failure>. - The details under a failed step are indented to the step's name.
- An action result holding a map whose keys are not strings, such as numbers, is now sent with the keys as text; keys that cannot be told apart that way fail the step instead of the entries being dropped.
- Every YAML example in the docs now parses, and expressions such as
filter(res.body.users, #.active == true)are quoted so that YAML does not read#as the start of a comment.
For library users
The Go API breaks in this minor version. The packages of the built-in actions moved under actions/, such as github.com/linyows/probe/http to github.com/linyows/probe/actions/http, with no aliases left. The mail package was split into actions/smtp and actions/mail-latency (package maillatency). expr.EvalTemplateMap now returns (map[string]any, error), and expr.EvalTemplate returns an error for a template that cannot be evaluated instead of writing it into the string. mapping.AssignStruct now enforces validate:"required" on an int field. See the CHANGELOG for the full list of moves.
New public API: expr.Refs returns the keys a value's templates read under a name, such as vars; template errors are *expr.TemplateError, and EvalTemplateMap joins one *expr.FieldError per failed value, naming its path.
Changelog
- 413e63d Build each release platform in a job of its own
- 9e4c45c Bump github.com/jarcoal/httpmock from 1.4.1 to 1.4.2
- 0956d46 Bump github.com/pb33f/libopenapi from 0.37.2 to 0.41.2
- 5465e6c Bump go.yaml.in/yaml/v4 from 4.0.0-rc.4 to 4.0.0-rc.6
- c97892b Check ready as given, report an exit that beats the deadline, and narrow detaching
- ee38c25 Document template errors and show why a job could not start
- f522131 Enforce required on int fields in AssignStruct
- 320efd0 Evaluate vars against a copy and keep orders stable
- 4e4c936 Expect the reason of the first failing iteration in the e2e reports
- ec2fba3 Fail a step whose template cannot be evaluated
- 3c10ebc Find an embedded job file in the graph where the run finds it
- fbf4068 Give every run on main a concurrency group of its own
- 202e933 Hide credentials before an action's log truncates them
- 00327ed Hide every basic_auth credential, also as an action receives it
- 8c435b1 Hide passwords passed to actions wherever Probe shows them
- b5ed053 Indent a failed step's error as its other details are
- 8395526 Keep credentials out of template errors and keep failure kinds in repeats
- acd2a31 Keep the Do tests in client_test.go next to the others
- 09aa0f5 Let a workflow var read another var
- f71ec8d List the gRPC test service and the STARTTLS constants as moved
- 6a8ca0c Make every yaml example in the docs one Probe can load
- ea6ad2b Mark a command stopped at its timeout, and stop shell's in time
- 725a587 Mark a timeout only when the timeout stopped the command
- 29a9814 Merge pull request #234 from linyows/dependabot/go_modules/go.yaml.in/yaml/v4-4.0.0-rc.6
- 65f7771 Merge pull request #235 from linyows/dependabot/go_modules/github.com/pb33f/libopenapi-0.38.7
- c0d64bc Merge pull request #236 from linyows/dependabot/go_modules/github.com/jarcoal/httpmock-1.4.2
- 5113b60 Merge pull request #297 from linyows/fix/mask-action-credentials
- 9714d50 Merge pull request #298 from linyows/ci/e2e-on-pull-request
- c4f4112 Merge pull request #299 from linyows/ci/organize-workflows
- 8ce7a0c Merge pull request #301 from linyows/refactor/embedded
- e37c5dd Merge pull request #302 from linyows/test/ssh-in-process-server
- 32a064a Merge pull request #303 from linyows/refactor/imap-uid-variants
- a4c056a Merge pull request #304 from linyows/test/pure-helpers
- 1d07497 Merge pull request #305 from linyows/fix/dag-embedded-path
- 8f80434 Merge pull request #306 from linyows/fix/command-timeouts
- 83799b2 Merge pull request #307 from linyows/fix/assignstruct-required-int
- 93bdb24 Merge pull request #308 from linyows/refactor/group-actions
- 037c90a Merge pull request #309 from linyows/feat/vars-reference-vars
- 238da0e Merge pull request #310 from linyows/fix/template-errors
- f0b3f70 Merge pull request #311 from linyows/feat/stdout-json
- b43e08f Merge pull request #312 from linyows/ci/build-matrix
- 55d98bd Merge pull request #313 from linyows/feat/http-basic-auth
- 276e004 Merge pull request #314 from linyows/feat/shell-ready
- 4b62ed6 Merge pull request #315 from linyows/docs/yaml-examples
- 8724f48 Merge pull request #316 from linyows/release/v1.18.0
- 3899573 Move each built-in action's package under actions/
- 1cc5605 Name the merged workflow test.yml after what it does
- 1c4f3d5 Organize the workflows by what they check
- c819603 Point the cgo-less db test at actions/db
- e351d18 Prepare the changelog for v1.18.0
- f06fd7c Quote expressions whose predicate YAML read as a comment
- ccb7af9 Read OpenAPI examples as pb33f/go-yaml nodes
- 2145cf9 Read a command's JSON output as res.json
- f78beb3 Remove jsonutil.deepMatchWithDiffs, which nothing calls
- 0e9e521 Resolve actions only as steps run them in RunIndependently
- 5dea98e Run embedded jobs through a typed result instead of a message
- 2a4391a Run the end-to-end tests on every pull request
- 81dfbb0 Send HTTP Basic authentication from basic_auth
- 8333cb9 Send map keys that are not strings instead of dropping their entries
- 6d6f2d5 Share one body between the sequence and UID variants of imap commands
- c382ad2 Show jobs by their lowercase IDs
- 23d16cc Test convertForProtobuf, AssignStruct and truncate.Map
- 1b73080 Test the ssh client against an SSH server in the test process
- 950a705 Wait for a background command to be ready with ready.log