repomatic.github.outputs module¶
What a command hands back to GitHub Actions: step outputs and annotations.
A step output travels in $GITHUB_OUTPUT, inline when its size is bounded and
as a file path when it is a report. An annotation is a workflow command printed
to the log. Both have size and format rules that this module applies in one
place.
- repomatic.github.outputs.MAX_STEP_OUTPUT_BYTES = 130048¶
Ceiling for a single
$GITHUB_OUTPUTvalue, in UTF-8 bytes.A step output only exists to be read by a later step, and the two ways of reading one both land it in the consumer’s environment:
env:mapping asteps.*.outputs.*expression, and action inputs, which the runner exports asINPUT_*. Linux caps a singleargv/envpstring atMAX_ARG_STRLEN, 32 pages, so a value past that makes the runner’sexecve()of/usr/bin/bashfail withE2BIGbefore the step’s own command exists:##[error]An error occurred trying to start process '/usr/bin/bash' with working directory '/home/runner/work/orchard/orchard'. Argument list too long
The 1 KiB reserve covers the
NAME=prefix the kernel counts as part of the same string, well beyond the longest name in use.This ceiling only binds a value the environment has to carry. A report that grows without bound belongs in a file instead: see
format_file_output(), which hands the consumer a path and leaves the content untrimmed.Caution
This is a transport limit, counted in bytes, and is deliberately looser than
repomatic.github.pr_body.GITHUB_BODY_MAX_CHARS, which is a content limit counted in UTF-16 code units. A value can clear this one and still be trimmed later byrepomatic.github.pr_body.build_pr_body(), which is the layer that leaves the reader a truncation notice.
- class repomatic.github.outputs.AnnotationLevel(*values)[source]¶
Bases:
EnumAnnotation levels for GitHub Actions workflow commands.
Mirrors the three levels GitHub supports, even where the codebase only emits a subset.
- ERROR = 'error'¶
- WARNING = 'warning'¶
- NOTICE = 'notice'¶
- repomatic.github.outputs.generate_delimiter()[source]¶
Generate a unique delimiter for GitHub Actions multiline output.
GitHub Actions requires a unique delimiter to encode multiline values in
$GITHUB_OUTPUT. This function generates a random delimiter that is extremely unlikely to appear in the output content.The delimiter format is
GHA_DELIMITER_NNNNNNNNNwhere N is a digit, producing a 9-digit random suffix.- Return type:
- Returns:
A unique delimiter string.
- repomatic.github.outputs.trim_to_budget(text, budget, measure)[source]¶
Keep the leading whole lines of text that fit in budget.
Cutting on line boundaries keeps the trimmed markdown rendering: a table missing rows still renders, one cut mid-row does not.
The one trimming loop behind both of GitHub’s size ceilings, which count in different units: measure prices a line in whatever unit the caller’s budget is denominated in (UTF-8 bytes for a step output, UTF-16 code units for a PR or issue body).
- repomatic.github.outputs.trim_to_byte_budget(text, budget)[source]¶
Keep the leading whole lines of text that fit in budget UTF-8 bytes.
trim_to_budget()in the step-output unit. Trimming whole lines also keeps the result valid UTF-8, which slicing a byte string cannot promise.
- repomatic.github.outputs.format_multiline_output(name, value)[source]¶
Format a multiline value for GitHub Actions output.
Produces output in the heredoc format required by
$GITHUB_OUTPUT:name<<GHA_DELIMITER_NNNNNNNNN value line 1 value line 2 GHA_DELIMITER_NNNNNNNNN
Values over
MAX_STEP_OUTPUT_BYTESare trimmed to fit, so a step reading this output cannot be killed byE2BIGbefore it starts.
- repomatic.github.outputs.write_output_file(name, value)[source]¶
Write a step output’s value to a file, and return that file’s path.
The file lands in
RUNNER_TEMPwhere the runner exports it, which is per-job and cleaned up by the runner itself, and in the system temporary directory otherwise. Either is shared by every step of a job, which is what makes the handoff work: producer and consumer are separate processes on one filesystem.
- repomatic.github.outputs.format_file_output(name, value)[source]¶
Format a value as a file-backed output, for a consumer to read back.
Writes value out with
write_output_file()and names the step output<name>_file, so the consuming step receives a path instead of content:harvest_file=/home/runner/work/_temp/repomatic-harvest-8m1t0p.md
This is the escape hatch from
MAX_STEP_OUTPUT_BYTES. A report grows with the repository it describes and has no ceiling of its own: the release notes of a dependency sweep can reach twice what the environment carries, and trimming to fit loses content. A path keeps the environment holding a hundred-odd bytes whatever the report weighs, and leaves any trimming torepomatic.github.pr_body.build_pr_body(), which is the layer that knows GitHub’s own body limit and marks the cut for the reader.
- repomatic.github.outputs.read_file_output(name)[source]¶
Read the content of a file-backed value, from its
<NAME>_FILEpath.The consuming half of
format_file_output(): the workflow maps the<name>_filestep output to the<NAME>_FILEvariable of the step that reads it.
- repomatic.github.outputs.write_text_output(content, output)[source]¶
Write content to an
--outputpath, then close what was opened.For
-,prep_pathreturns the livesys.stdoutwhen stdout has no file descriptor, as under a test runner. Only a stream it opened is closed: closing the live one would end every later write of the run.
- repomatic.github.outputs.emit_report(body, output, output_format, key='diff_table', outputs=None)[source]¶
Write a markdown report to
--output, optionally as a step output.The shared tail of every report-producing command: nothing is written when no output path is set or the body is empty; with
--output-format github-actionsthe body is spilled to a file and the step output named<key>_filecarries its path, for$GITHUB_OUTPUTconsumption.A report is the one value here with no ceiling of its own, so it is the one that must not travel inline: see
format_file_output().- Parameters:
body (
str) – The markdown report.output (
Path|None) – The--outputpath (Noneto skip,-for stdout).output_format (
str) –markdownorgithub-actions.key (
str) – The step output variable name, before the_filesuffix, for thegithub-actionsformat.outputs (
Mapping[str,str] |None) – Single-line step outputs written beside the report’s path, for thegithub-actionsformat only.prep_pathtruncates the file it opens, so every output of a step has to go through this one write.
- Return type:
- repomatic.github.outputs.emit_annotation(level, message)[source]¶
Emit a GitHub Actions workflow annotation.
Prints a workflow command that creates an annotation visible in the GitHub Actions UI and PR checks.
- Parameters:
level (
AnnotationLevel) – The annotation level.message (
str) – The annotation message.
- Return type:
- repomatic.github.outputs.add_problem_matcher(path)[source]¶
Register the problem matcher at path with the GitHub Actions runner.
The runner reads the file when it processes the command, so the file must outlast the process that prints it. The command is flushed at once: a tool started next writes its findings to the same stream, and the runner must read the command before the first of them.
- Return type:
- repomatic.github.outputs.remove_problem_matcher(owner)[source]¶
Unregister the problem matcher of owner from the GitHub Actions runner.
- Return type:
- repomatic.github.outputs.report_finding(level, message)[source]¶
Report one finding in the log and as a workflow annotation.
Emits the annotation first, then prints the line the terminal reader sees, opened by the
AnnotationLevel.glyphof level. Every lint that reports a failure goes through here, so the symbol and the annotation level of a finding always agree.- Parameters:
level (
AnnotationLevel) – Severity of the finding.message (
str) – The finding, one line.
- Return type: