ci.summary
The ci.summary function appends Markdown to the job summary of the current run. Locally, it renders the Markdown
as formatted text on stderr.
Usage
ci.summary(markdown = "", template = "", data = None)
Arguments
markdownThe Markdown to append, as a string. Each call adds to the summary rather than replacing it, so a script can build the summary in several steps. Required unless
templateis given, and it cannot be combined withtemplateordata, even when it is an empty string.template(Optional) The name of a template file to render into the summary, instead of passing
markdown. It is a file name underci.templates.base_path, or an absolute path. There is no default template, sodataalways needs atemplate.data(Optional) A dict that becomes the template context. Keys are read in the template as
.key. Passingdatawithouttemplatefails with an argument error that saystemplate=is required.
Templates
A script can keep the layout of a summary in a template file and pass only the values:
- A call with
template=renders that file, withdataas the context. A call with onlymarkdownappends the text as written. - There is no configured default template. The
ci.summary.templatekey belongs to the summaries Atmos writes for commands, and scripts never read it. - The name is resolved against
ci.templates.base_path. A relativebase_pathresolves against the Atmosbase_path. When no file has exactly that name, the name with a.mdsuffix is tried. - Templates use Go template syntax with the same functions as the built-in plan templates. The
datadict is the template context. - A key that the template reads but
datadoes not contain fails the render and names the key, so a typo does not write<no value>into the summary.
See script report templates for the configuration.
Returns
The return value is None.
Behavior
- On GitHub Actions, the text is appended to the job summary file that the runner provides. The summary appears on the run page.
- Locally, the Markdown is rendered as terminal Markdown on stderr.
- The text is masked before it leaves the process, so secrets that Atmos knows about do not reach the summary.
- In CI the call is gated by
ci.summary.enabled. When it is off, the call warns, renders locally, and the script continues. See gating.
Examples
Report a short result
ci.summary("## Deploy\n\nDeployed **api** to `prod` in 42 seconds.")
Build a table
rows = ["| Stack | Result |", "| --- | --- |"]
for stack, result in {"dev": "ok", "prod": "ok"}.items():
rows.append("| " + stack + " | " + result + " |")
ci.summary("\n".join(rows))
Render a summary from a template
## Deploy to {{ .stack }}
{{ .count }} services deployed.
{{ range .services }}
- {{ . }}
{{ end }}
ci.summary(template = "deploy.md", data = {"stack": "prod", "count": 2, "services": ["api", "web"]})
Errors
- A missing or non-string
markdownfails with an argument error that namesci.summary. - Passing
markdowntogether withtemplateordata(an empty string counts), adatavalue that is not a dict, ordatawithouttemplatefails with an argument error. - A template that does not exist fails the script with an error that names the resolved path and the value of
ci.templates.base_path. A template that reads a key missing fromdata, or that fails to render, fails the script. - A failure to write the summary fails the script. A gated-off call never fails.
Related
cidescribes the module and the shared behavior rules.- CI job summaries configures the native summaries that Atmos writes for commands.
ci.commentposts Markdown to the pull request instead.