Locally verifying GitHub Actions Job Summaries
This post is over a year old, some of this information may be out of date.
GitHub Actions Job Summaries are a great way to provide more information on your job’s output. This summary is shown in the Actions tab of your repository.

In this post, I’ll explain how you can locally develop and test your GitHub Actions Job Summary outputs using the @actions/core dependency.
In my case, I used this approach to develop the GitHub Actions Reporter for Playwright. This npm package generates a summary output for your Playwright tests.
How to write a summary output
The easiest way to write a GitHub Actions summary is to use the @actions/core dependency. The @actions/core
dependency provides functions for inputs, outputs, logging, and more.
You can write the job summary using the core.summary
methods. Once completed, you can call the core.summary.write()
method to write the buffer to the Job Summary output on GitHub Actions.
import * as core from '@actions/core';
const summary = core.summary;
summary.addHeading("My job summary heading", 1);summary.addSeparator();
summary.addList(['item1','item2','item3'], true);
await summary.write();
The downside of this approach is that you have to push your changes to GitHub to see if your summary output is working as expected. When you try to run it locally, it will throw an error saying it is unable to find the GITHUB_STEP_SUMMARY
environment variable.
Testing your summary locally
To test your summary locally, you must set the GITHUB_STEP_SUMMARY
environment variable. This variable defines the file path where the summary output should be written. Locally, we can pass a local file path to this environment variable.
Here is an example of how to set the GITHUB_STEP_SUMMARY
environment variable when running your script locally.
import * as core from '@actions/core';import { join } from "path";import { existsSync, unlinkSync, writeFileSync } from "fs";
const __dirname = import.meta.dirname;
if (process.env.NODE_ENV === "development") { const summaryFile = join(__dirname, "summary.html"); if (existsSync(summaryFile)) { unlinkSync(summaryFile); } writeFileSync(summaryFile, "", "utf-8"); process.env.GITHUB_STEP_SUMMARY = summaryFile; process.env.GITHUB_ACTIONS = "true";}
const summary = core.summary;
summary.addHeading("My job summary heading", 1);summary.addSeparator();
summary.addList(['item1','item2','item3'], true);
await summary.write();
When you run your script locally, you will see that the summary.html
file is created with the content of your summary output. The generated file contents look like this:
<h1>My job summary heading</h1><hr><ol><li>item1</li><li>item2</li><li>item3</li></ol>
Related articles
Manual GitHub workflow triggers for Azure Static Web Site
Which service? Netlify vs Vercel vs Azure Static Web App
#DevHack: cross-platform testing your tool on GitHub Actions
Report issues or make changes on GitHub
Found a typo or issue in this article? Visit the GitHub repository to make changes or submit a bug report.
Comments
Let's build together
Manage content in VS Code
Present from VS Code