Add workflow run link to external plugin intake comments (#1915)

* Add workflow run link to external plugin intake comments

- Include a link to the GitHub Actions workflow run in intake comment
- Helps users trace which action run generated the intake report
- Works for both initial intake and re-run intake flows
- Link appears at bottom of comment for all intake states (passed/failed/quality gates)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Address PR review feedback on intake comment formatting

- Remove leading spaces from runLink construction to preserve markdown formatting
- Remove unnecessary newline prefix before runLink in quality gates section
- Move workflow run link to the very end of all comment types (after warnings)
- For merged intake comments, append link as final element
- Remove unused runId parameter from applyExternalPluginIntakeEvaluation

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Aaron Powell
2026-06-04 12:30:39 -07:00
committed by GitHub
parent 36cdc52037
commit d11fb21f3a
3 changed files with 22 additions and 10 deletions
+15 -6
View File
@@ -424,13 +424,14 @@ function getIntakeStateFromQualityResult(baseResult, qualityResult) {
return "ready-for-review";
}
function buildMergedIntakeComment(baseResult, qualityResult) {
function buildMergedIntakeComment(baseResult, qualityResult, runId, owner, repo) {
if (!baseResult.valid) {
return baseResult.commentBody;
}
const marker = baseResult.commentMarker ?? EXTERNAL_PLUGIN_INTAKE_COMMENT_MARKER;
const qualitySection = buildQualityGatesCommentSection(qualityResult);
const runLink = runId && owner && repo ? `_[View workflow run](https://github.com/${owner}/${repo}/actions/runs/${runId})_` : "";
const intro =
qualityResult.failure_class === "submitter_fixes"
@@ -467,10 +468,11 @@ function buildMergedIntakeComment(baseResult, qualityResult) {
baseResult.warnings?.length
? ["", "### Warnings", "", ...baseResult.warnings.map((warning) => `- ${warning}`)].join("\n")
: "",
runLink ? `\n${runLink}` : "",
].filter(Boolean).join("\n");
}
export function applyQualityGateResult(baseEvaluation, qualityGateResult) {
export function applyQualityGateResult(baseEvaluation, qualityGateResult, runId, owner, repo) {
const baseResult = typeof baseEvaluation === "string" ? JSON.parse(baseEvaluation) : baseEvaluation;
const qualityResult = normalizeQualityGateResult(
typeof qualityGateResult === "string" ? JSON.parse(qualityGateResult) : qualityGateResult,
@@ -481,11 +483,11 @@ export function applyQualityGateResult(baseEvaluation, qualityGateResult) {
...baseResult,
qualityGates: qualityResult,
intakeState,
commentBody: buildMergedIntakeComment(baseResult, qualityResult),
commentBody: buildMergedIntakeComment(baseResult, qualityResult, runId, owner, repo),
};
}
export async function evaluateExternalPluginIssue({ issue, token } = {}) {
export async function evaluateExternalPluginIssue({ issue, token, runId, owner, repo } = {}) {
const issueBody = issue?.body ?? "";
const parsed = parseExternalPluginIssueBody(issueBody);
const errors = [...parsed.errors];
@@ -529,6 +531,8 @@ export async function evaluateExternalPluginIssue({ issue, token } = {}) {
].join("\n")
: "```json\n{}\n```";
const runLink = runId && owner && repo ? `_[View workflow run](https://github.com/${owner}/${repo}/actions/runs/${runId})_` : "";
const commentBody = valid
? [
marker,
@@ -552,6 +556,7 @@ export async function evaluateExternalPluginIssue({ issue, token } = {}) {
dedupedWarnings.length > 0
? ["", "### Warnings", "", ...dedupedWarnings.map((warning) => `- ${warning}`)].join("\n")
: "",
runLink ? `\n${runLink}` : "",
].filter(Boolean).join("\n")
: [
marker,
@@ -566,6 +571,7 @@ export async function evaluateExternalPluginIssue({ issue, token } = {}) {
dedupedWarnings.length > 0
? ["", "### Warnings", "", ...dedupedWarnings.map((warning) => `- ${warning}`)].join("\n")
: "",
runLink ? `\n${runLink}` : "",
].filter(Boolean).join("\n");
return {
@@ -585,11 +591,14 @@ const isCli = process.argv[1] && fileURLToPath(import.meta.url) === path.resolve
if (isCli) {
const eventPath = process.argv[2];
if (!eventPath) {
console.error("Usage: node ./eng/external-plugin-intake.mjs <github-event.json>");
console.error("Usage: node ./eng/external-plugin-intake.mjs <github-event.json> [runId] [owner] [repo]");
process.exit(1);
}
const event = JSON.parse(fs.readFileSync(eventPath, "utf8"));
const result = await evaluateExternalPluginIssue({ issue: event.issue, token: process.env.GITHUB_TOKEN });
const runId = process.argv[3];
const owner = process.argv[4];
const repo = process.argv[5];
const result = await evaluateExternalPluginIssue({ issue: event.issue, token: process.env.GITHUB_TOKEN, runId, owner, repo });
process.stdout.write(JSON.stringify(result));
}