An action to capture console logs from a web application and post them as a comment on a pull request.
Even when having a CI/CD pipeline with tests, screenshots and other checks in place, it can occur that small changes or versions of dependencies can break the application in a way that is not covered by the tests. This action helps to capture console logs from the web application and post them as a comment on a pull request, so that issues arise as early as possible - especially when the pull request was opened automatically by a bot like dependabot or renovate.
- Capture console logs from a web application deployed on a server
- Capture console logs from a web application that was built in a previous workflow
- Capture console logs from authenticated areas after a login flow
This action uses http-server to serve the web application (only when passing localhost as input, see details below) and playwright to capture the console logs.
Furthermore, thanks to thollander/actions-comment-pull-request for the comment functionality.
To use this action, include it in your GitHub Actions workflow:
name: Capture Console Logs
on: [push, pull_request]
permissions:
pull-requests: write
jobs:
capture-console-logs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Have your web-app built
run: build stuff or get from other build action
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: your-artifact-name
path: path-to-app/
- name: Capture Console Logs
uses: Primajin/webapp-console-log-action@v1
with:
artifact-name: your-artifact-name
webapp-url: 'http://localhost'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}name: Capture Console Logs
on: [push, pull_request]
permissions:
pull-requests: write
jobs:
capture-console-logs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Capture Console Logs
uses: Primajin/webapp-console-log-action@v1
with:
webapp-url: 'https://your-deployed-app.com'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}For more examples, see the workflow examples.
Create a repo-local script that logs in before the capture window starts:
import process from 'node:process';
export default async function loginAndCapture({page, startCapture}) {
await page.getByLabel('Username').fill(process.env.DEMO_LOGIN_USERNAME);
await page.getByLabel('Password').fill(process.env.DEMO_LOGIN_PASSWORD);
await startCapture();
await Promise.all([
page.waitForURL('**/secure'),
page.getByRole('button', {name: 'Login'}).click(),
]);
await page.getByText('You logged into a secure area!').waitFor();
await page.getByRole('link', {name: 'Logout'}).waitFor();
}Then reference it from the workflow:
- name: Capture Console Logs
uses: Primajin/webapp-console-log-action@v1
with:
max-log-level: error
pre-script-path: .github/scripts/the-internet-login.js
pre-script-timeout: 30000
regexp-error: '^Failed to load resource: net::ERR_NAME_NOT_RESOLVED$'
wait-time: 1000
webapp-url: 'https://the-internet.herokuapp.com/login'
env:
DEMO_LOGIN_PASSWORD: ${{ secrets.DEMO_LOGIN_PASSWORD }}
DEMO_LOGIN_USERNAME: ${{ secrets.DEMO_LOGIN_USERNAME }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}The action opens webapp-url, runs the pre-script, and starts collecting console output. Call startCapture() inside the script if you want to begin collecting before the script ends. In the example above, the script proves login succeeded by waiting for the secure-area success message and the Logout link after the redirect. The public demo site can emit unrelated ERR_NAME_NOT_RESOLVED resource errors in CI, so the workflow filters those out. See docs/pre-scripts.md for the full contract.
| Input | Description | Required | Default |
|---|---|---|---|
artifact-name |
The name of the artifact to download (required if webapp-url points to localhost) |
false | |
comment-tag |
The tag to use for the comment - so that consecutive pushes will update the same comment | false | console-log |
headline |
The headline for the console logs | false | Console Logs |
max-log-level |
The maximum log level to allow (verbose, info, warning, error) | false | info |
min-log-level |
The minimum log level to capture (verbose, info, warning, error) | false | verbose |
pre-script-path |
Path to a JavaScript module in GITHUB_WORKSPACE that prepares the app before console capture begins |
false | |
pre-script-timeout |
Timeout for the pre-script in milliseconds | false | 30000 |
port |
The port to run the http-server on (set to 3000 if webapp-url is localhost and port is not set) |
false | |
regexp-error |
Regular expression pattern to filter1 matching parts from error logs | false | |
regexp-info |
Regular expression pattern to filter1 matching parts from info logs | false | |
regexp-verbose |
Regular expression pattern to filter1 matching parts from verbose logs | false | |
regexp-warning |
Regular expression pattern to filter1 matching parts from warning logs | false | |
show-emoji |
Whether to show emojis in the output | false | true |
wait-time |
The wait time before capturing logs (in milliseconds) | false | 2500 |
webapp-url |
The URL of the web application | true |
-
Log messages (or parts of them) that match the regular expression pattern will be replaced with empty string.
If everything is replaced with empty string, the log will not be captured.
This is useful to filter out parts of the log that are expected or contain sensitive information.
| Output | Description |
|---|---|
console |
The captured console log |
This project is licensed under the Unlicense license - see the LICENSE file for details.
The comment will look something like this:
| github-actions (bot) commented 2 minutes ago | |
|
|