# Job Summary Create rich, formatted summaries for GitHub Actions workflows using a fluent builder API. Job summaries appear on the workflow run summary page and support tables, code blocks, images, collapsible sections, and more. ## Table of Contents - [Fluent Builder API](#fluent-builder-api) - [Basic Elements](#basic-elements) - [Tables](#tables) - [Code Blocks](#code-blocks) - [Images](#images) - [Collapsible Sections](#collapsible-sections) - [Template API](#template-api) - [Legacy Functions](#legacy-functions) - [Size Limits and Security](#size-limits-and-security) ## Fluent Builder API The `JobSummary` class provides a fluent API for building rich summaries. All methods return `self` for easy chaining. ### Basic Usage ```python from github_action_toolkit import JobSummary summary = JobSummary() summary.add_heading("Test Results", 1) summary.add_separator() summary.add_list(["Test 1: ✓ Passed", "Test 2: ✓ Passed", "Test 3: ✗ Failed"]) summary.write() ``` ### Fluent Chaining Chain multiple methods for concise code: ```python summary = JobSummary() (summary .add_heading("CI Pipeline Report", 1) .add_separator() .add_quote("All tests passed!") .add_break() .add_link("View Dashboard", "https://example.com") .write() ) ``` ## Basic Elements ### Headings Add headings at levels 1-6: ```python summary.add_heading("Main Title", 1) summary.add_heading("Subtitle", 2) summary.add_heading("Section", 3) ``` ### Text and Line Breaks Add raw text, line breaks, and separators: ```python summary.add_raw("Plain text content") summary.add_eol() # Add newline summary.add_break() # Add
summary.add_separator() # Add
``` ### Quotes Add blockquotes with optional citations: ```python summary.add_quote("This is a quote") summary.add_quote("Quote with citation", cite="Author Name") ``` ### Links Add hyperlinks: ```python summary.add_link("GitHub", "https://github.com") ``` ### Lists Create ordered or unordered lists: ```python # Unordered list summary.add_list(["Item 1", "Item 2", "Item 3"]) # Ordered list summary.add_list(["First", "Second", "Third"], ordered=True) ``` ## Tables Create tables with headers and rows. The first row is automatically treated as headers. ### Simple Tables ```python rows = [ ["Name", "Status", "Duration"], ["test_auth", "✓ Pass", "0.5s"], ["test_db", "✓ Pass", "1.2s"], ["test_api", "✗ Fail", "0.8s"], ] summary.add_table(rows) ``` ### Advanced Tables with Cell Options Use dictionaries for cells that need special attributes: ```python rows = [ [{"data": "Header 1", "header": True}, {"data": "Header 2", "header": True}], [{"data": "Spanning Cell", "colspan": "2"}], ["Regular", "Cells"], ] summary.add_table(rows) ``` Cell dictionary keys: - `data`: Cell content (required) - `header`: True to render as `` instead of `` - `colspan`: Number of columns to span - `rowspan`: Number of rows to span ## Code Blocks Add code blocks with optional syntax highlighting: ```python # Without language summary.add_code_block("print('hello world')") # With language summary.add_code_block(""" def greet(name): return f"Hello, {name}!" """, "python") ``` ## Images Add images with alt text and optional dimensions: ```python # Basic image summary.add_image("https://example.com/image.png", "Alt text") # With dimensions summary.add_image( "https://example.com/chart.png", "Performance Chart", width="400", height="300" ) ``` ## Collapsible Sections Create collapsible details sections: ```python summary.add_details( "Click to expand", "Hidden content that appears when expanded" ) ``` ## Template API The `JobSummaryTemplate` class provides pre-built templates for common use cases. ### Test Report ```python from github_action_toolkit import JobSummaryTemplate summary = JobSummaryTemplate.test_report( title="Unit Test Results", passed=45, failed=3, skipped=2, duration="12.5s" ) summary.write() ``` ### Coverage Report ```python coverage_data = { "core/auth.py": 98.5, "core/database.py": 92.3, "api/handlers.py": 87.6, } summary = JobSummaryTemplate.coverage_report( "Code Coverage", coverage_data ) summary.write() ``` ### Deployment Report ```python summary = JobSummaryTemplate.deployment_report( title="Production Deployment", environment="production", status="success", version="v2.5.0", url="https://app.example.com" ) summary.write() ``` ### Benchmark Report ```python benchmarks = { "API Response Time": { "Average": "125ms", "P95": "250ms", "P99": "500ms", }, "Database Query": { "Average": "45ms", "P95": "80ms", }, } summary = JobSummaryTemplate.benchmark_report( "Performance Benchmarks", benchmarks ) summary.write() ``` ### Combining Templates Templates return `JobSummary` objects, so you can add custom content: ```python summary = JobSummaryTemplate.test_report( title="CI Results", passed=50, failed=0, duration="15.2s" ) # Add custom content summary.add_separator() summary.add_heading("Additional Notes", 2) summary.add_quote("All quality gates passed!") summary.write() ``` ## Legacy Functions These functions provide backward compatibility with earlier versions. ### `append_job_summary(markdown_text)` Append markdown text to the job summary: ```python from github_action_toolkit import append_job_summary append_job_summary("# Test Summary") append_job_summary("- Point 1") ``` ### `overwrite_job_summary(markdown_text)` Replace the entire job summary: ```python from github_action_toolkit import overwrite_job_summary overwrite_job_summary("# New Summary") ``` ### `remove_job_summary()` Remove the job summary file: ```python from github_action_toolkit import remove_job_summary remove_job_summary() ``` ## Size Limits and Security ### Size Limits Job summaries are limited to 1 MiB (1,048,576 bytes). The API automatically enforces this limit: ```python summary = JobSummary() summary.add_raw("..." * 1000000) # Large content summary.write() # Raises ValueError if too large ``` ### Content Sanitization All content is automatically sanitized to prevent XSS attacks. HTML special characters are escaped: ```python summary = JobSummary() summary.add_heading("") # Rendered as: <script>alert('xss')</script> ``` ### Buffer Management Control when content is written: ```python summary = JobSummary() summary.add_heading("Title", 1) summary.add_raw("Content") # Check if empty if not summary.is_empty(): # Get as string without writing content = summary.stringify() # Clear buffer summary.clear() # Write to file (buffer is cleared after write) summary.write() # Overwrite file summary.write(overwrite=True) ``` ## Complete Example Here's a complete example combining multiple features: ```python from github_action_toolkit import JobSummary, JobSummaryTemplate # Use template for test results summary = JobSummaryTemplate.test_report( title="CI Pipeline Results", passed=42, failed=0, duration="8.5s" ) # Add coverage information summary.add_separator() summary.add_heading("Code Coverage", 2) summary.add_table([ ["Module", "Coverage"], ["Core", "95%"], ["API", "92%"], ["Utils", "87%"], ]) # Add deployment info summary.add_separator() summary.add_heading("Deployment", 2) summary.add_quote("✓ Successfully deployed to staging") summary.add_link("View Application", "https://staging.example.com") # Add collapsible logs summary.add_break() summary.add_details("View Build Logs", """ Building... Running tests... All tests passed! Deploying... Deployment successful! """) # Write the summary summary.write() ``` ## Reference For more information, see the [GitHub Actions documentation on job summaries](https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#adding-a-job-summary).