Skip to content

Instantly share code, notes, and snippets.

@caugner
Created January 16, 2026 16:19
Show Gist options
  • Select an option

  • Save caugner/be1254f9e837ed8c898cc84e28be40b3 to your computer and use it in GitHub Desktop.

Select an option

Save caugner/be1254f9e837ed8c898cc84e28be40b3 to your computer and use it in GitHub Desktop.
MDN Test with Check Annotations (from https://github.com/mdn/curriculum/pull/104)
name: Report build issues
on:
workflow_call:
inputs:
build-issues-artifact-id:
description: The ID of the artifact containing the issues.json file
required: true
type: string
content-path:
description: The path to the content directory to strip from file paths
required: true
type: string
permissions:
checks: write
pull-requests: read
jobs:
report-build-issues:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
persist-credentials: false
- name: Download artifact
id: download
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
artifact-ids: ${{ inputs.build-issues-artifact-id }}
path: ./rari-issues
- name: Report build issues
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
env:
CONTENT_PATH: ${{ inputs.content-path }}
ISSUES_PATH: ${{ steps.download.outputs.download-path }}/issues.json
with:
script: |
const fs = require("fs");
const path = require("path");
const issuesByPath = JSON.parse(fs.readFileSync(process.env.ISSUES_PATH, "utf8"));
const issuesByFile = {};
const annotations = [];
for (const [filepath, issues] of Object.entries(issuesByPath)) {
const prefix = process.env.CONTENT_PATH.replace(/\/$/, '');
if (!filepath.includes(prefix)) {
continue;
}
const file = filepath.replace(prefix, "").replace(/^\//, '');
issuesByFile[file] = issues.length;
for (const issue of issues) {
const {
line: startLine,
col: startColumn,
end_line: endLine,
end_col: endColumn,
} = issue;
const {
source = "unknown",
...otherFields
} = Object.fromEntries(issue.fields);
const payload = Object.entries(otherFields)
.map(([key, value]) => `${key}: ${value}`)
.join(" • ");
const message = source ? `(${source}) ${payload}` : payload;
annotations.push({
path: file,
start_line: startLine,
end_line: endLine,
start_column: startColumn,
end_column: endColumn,
annotation_level: "warning",
message: message,
});
}
}
// Create check run with annotations if this is a pull request
if (context.payload.pull_request) {
const { owner, repo } = context.repo;
const sha = context.payload.pull_request.head.sha;
const fileCount = Object.keys(issuesByFile).length;
const issueCount = annotations.length;
await github.rest.checks.create({
owner,
repo,
name: "Build Issues",
head_sha: sha,
status: "completed",
conclusion: issueCount > 0 ? "neutral" : "success",
output: {
title: issueCount > 0 ? `Found ${issueCount} issue(s) in ${fileCount} file(s)` : "No issues found",
summary: `<details><summary>Issues by file</summary><ul>${Object.entries(issuesByFile).map(([file, issueCount]) => `<li><code>${file}</code> (${issueCount})</li>`).join("")}</ul></details>`,
annotations: annotations.slice(0, 50),
},
});
core.info(`Created check run`);
} else {
// Fallback to warnings for non-PR contexts
for (const annotation of annotations) {
core.warning(annotation.message, {
file: annotation.path,
startLine: annotation.start_line,
endLine: annotation.end_line,
startColumn: annotation.start_column,
endColumn: annotation.end_column,
});
}
}
name: Test
on:
push:
branches:
- main
pull_request:
env:
BUILD_OUT_ROOT: ${{ github.workspace }}/mdn/content/node_modules/@mdn/fred/out
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
outputs:
artifact-id: ${{ steps.upload.outputs.artifact-id }}
content-path: ${{ github.workspace }}/mdn/curriculum
steps:
- name: Checkout mdn/content
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
repository: mdn/content
path: mdn/content
persist-credentials: false
- name: Checkout mdn/curriculum
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
path: mdn/curriculum
persist-credentials: false
- name: Setup Node
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
with:
node-version-file: mdn/content/.nvmrc
cache: npm
cache-dependency-path: mdn/content/package-lock.json
- name: Install
run: npm ci
working-directory: mdn/content
- name: Build
working-directory: mdn/content
env:
CONTENT_ROOT: ${{ github.workspace }}/mdn/content/files
CURRICULUM_ROOT: ${{ github.workspace }}/mdn/curriculum
GITHUB_TOKEN: ${{ github.token }}
run: npx rari build --no-basic --curriculum --issues "$BUILD_OUT_ROOT/issues.json" --templ-stats
- name: Upload issues
id: upload
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
path: ${{ env.BUILD_OUT_ROOT }}/issues.json
retention-days: 1
report:
needs: build
uses: ./.github/workflows/_report-build-issues.yml
permissions:
contents: read
checks: write
pull-requests: read
with:
build-issues-artifact-id: ${{ needs.build.outputs.artifact-id }}
content-path: ${{ needs.build.outputs.content-path }}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment