ci(pr-intake): make template/format checks advisory (#595)

* fix(workflows): standardize runner configuration for security jobs

* ci(actionlint): add Blacksmith runner label to config

Add blacksmith-2vcpu-ubuntu-2404 to actionlint self-hosted-runner labels config
to suppress "unknown label" warnings during workflow linting.

This label is used across all workflows after the Blacksmith migration.

* fix(actionlint): adjust indentation for self-hosted runner labels

* feat(security): enhance security workflow with CodeQL analysis steps

* fix(security): update CodeQL action to version 4 for improved analysis

* fix(security): remove duplicate permissions in security workflow

* fix(security): revert CodeQL action to v3 for stability

The v4 version was causing workflow file validation failures.
Reverting to proven v3 version that is working on main branch.

* fix(security): remove duplicate permissions causing workflow validation failure

The permissions block had duplicate security-events and actions keys,
which caused YAML validation errors and prevented workflow execution.

Fixes: workflow file validation failures on main branch

* fix(security): remove pull_request trigger to reduce costs

* fix(security): restore PR trigger but skip codeql on PRs

* fix(security): resolve YAML syntax error in security workflow

* refactor(security): split CodeQL into dedicated scheduled workflow

* fix(security): update workflow name to Rust Package Security Audit

* fix(codeql): remove push trigger, keep schedule and on-demand only

* feat(codeql): add CodeQL configuration file to ignore specific paths

* Potential fix for code scanning alert no. 39: Hard-coded cryptographic value

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>

* fix(ci): resolve auto-response workflow merge markers

* fix(build): restore ChannelMessage reply_target usage

* ci(workflows): run workflow sanity on workflow pushes for all branches

* ci(workflows): rename auto-response workflow to PR Auto Responder

* ci(workflows): require owner approval for workflow file changes

* ci: add lint-first PR feedback gate

* ci(workflows): split label policy checks from workflow sanity

* ci(workflows): consolidate policy and rust workflow setup

* ci: add safe pull request intake sanity checks

* ci(security): switch audit to pinned rustsec audit-check

* fix(providers): clarify reliable failure entries for custom providers

* ci(pr-intake): make template/format checks advisory

Keep PR Intake Sanity non-blocking for template completeness and formatting findings, while still failing on dangerous merge-conflict markers in added lines.

---------

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
This commit is contained in:
Will Sarg 2026-02-17 14:02:47 -05:00 committed by GitHub
parent 3c4ed2e28e
commit b80840307a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -62,7 +62,8 @@ jobs:
per_page: 100,
});
const formatProblems = [];
const formatWarnings = [];
const dangerousProblems = [];
for (const file of files) {
const patch = file.patch || "";
if (!patch) continue;
@ -73,13 +74,13 @@ jobs:
const added = line.slice(1);
const lineNo = idx + 1;
if (/\t/.test(added)) {
formatProblems.push(`${file.filename}:patch#${lineNo} contains tab characters`);
formatWarnings.push(`${file.filename}:patch#${lineNo} contains tab characters`);
}
if (/[ \t]+$/.test(added)) {
formatProblems.push(`${file.filename}:patch#${lineNo} contains trailing whitespace`);
formatWarnings.push(`${file.filename}:patch#${lineNo} contains trailing whitespace`);
}
if (/^(<<<<<<<|=======|>>>>>>>)/.test(added)) {
formatProblems.push(`${file.filename}:patch#${lineNo} contains merge conflict markers`);
dangerousProblems.push(`${file.filename}:patch#${lineNo} contains merge conflict markers`);
}
}
}
@ -88,15 +89,19 @@ jobs:
.map((file) => file.filename)
.filter((name) => name.startsWith(".github/workflows/"));
const failures = [];
const advisoryFindings = [];
const blockingFindings = [];
if (missingSections.length > 0) {
failures.push(`Missing required PR template sections: ${missingSections.join(", ")}`);
advisoryFindings.push(`Missing required PR template sections: ${missingSections.join(", ")}`);
}
if (missingFields.length > 0) {
failures.push(`Incomplete required PR template fields: ${missingFields.join(", ")}`);
advisoryFindings.push(`Incomplete required PR template fields: ${missingFields.join(", ")}`);
}
if (formatProblems.length > 0) {
failures.push(`Formatting/safety issues in added lines (${formatProblems.length})`);
if (formatWarnings.length > 0) {
advisoryFindings.push(`Formatting issues in added lines (${formatWarnings.length})`);
}
if (dangerousProblems.length > 0) {
blockingFindings.push(`Dangerous patch markers found (${dangerousProblems.length})`);
}
const comments = await github.paginate(github.rest.issues.listComments, {
@ -107,7 +112,7 @@ jobs:
});
const existing = comments.find((comment) => (comment.body || "").includes(marker));
if (failures.length === 0) {
if (advisoryFindings.length === 0 && blockingFindings.length === 0) {
if (existing) {
await github.rest.issues.deleteComment({
owner,
@ -120,13 +125,22 @@ jobs:
}
const runUrl = `${context.serverUrl}/${owner}/${repo}/actions/runs/${context.runId}`;
const details = [];
if (formatProblems.length > 0) {
details.push(...formatProblems.slice(0, 20).map((entry) => `- ${entry}`));
if (formatProblems.length > 20) {
details.push(`- ...and ${formatProblems.length - 20} more issue(s)`);
const advisoryDetails = [];
if (formatWarnings.length > 0) {
advisoryDetails.push(...formatWarnings.slice(0, 20).map((entry) => `- ${entry}`));
if (formatWarnings.length > 20) {
advisoryDetails.push(`- ...and ${formatWarnings.length - 20} more issue(s)`);
}
}
const blockingDetails = [];
if (dangerousProblems.length > 0) {
blockingDetails.push(...dangerousProblems.slice(0, 20).map((entry) => `- ${entry}`));
if (dangerousProblems.length > 20) {
blockingDetails.push(`- ...and ${dangerousProblems.length - 20} more issue(s)`);
}
}
const isBlocking = blockingFindings.length > 0;
const ownerApprovalNote = workflowFilesChanged.length > 0
? [
@ -140,14 +154,19 @@ jobs:
const commentBody = [
marker,
"### PR intake checks failed",
isBlocking
? "### PR intake checks failed (blocking)"
: "### PR intake checks found warnings (non-blocking)",
"",
"Fast safe checks ran before full CI and found issues:",
...failures.map((entry) => `- ${entry}`),
isBlocking
? "Fast safe checks found blocking safety issues:"
: "Fast safe checks found advisory issues. CI lint/test/build gates still enforce merge quality.",
...(blockingFindings.length > 0 ? blockingFindings.map((entry) => `- ${entry}`) : []),
...(advisoryFindings.length > 0 ? advisoryFindings.map((entry) => `- ${entry}`) : []),
"",
"Action items:",
"1. Complete the required PR template sections/fields.",
"2. Remove tabs, trailing whitespace, and conflict markers from added lines.",
"1. Complete required PR template sections/fields.",
"2. Remove tabs, trailing whitespace, and merge conflict markers from added lines.",
"3. Re-run local checks before pushing:",
" - `./scripts/ci/rust_quality_gate.sh`",
" - `./scripts/ci/rust_strict_delta_gate.sh`",
@ -155,8 +174,11 @@ jobs:
"",
`Run logs: ${runUrl}`,
"",
"Detected line issues (sample):",
...(details.length > 0 ? details : ["- none"]),
"Detected blocking line issues (sample):",
...(blockingDetails.length > 0 ? blockingDetails : ["- none"]),
"",
"Detected advisory line issues (sample):",
...(advisoryDetails.length > 0 ? advisoryDetails : ["- none"]),
ownerApprovalNote,
].join("\n");
@ -176,4 +198,9 @@ jobs:
});
}
core.setFailed("PR intake sanity checks failed. See sticky comment for details.");
if (isBlocking) {
core.setFailed("PR intake sanity checks found blocking issues. See sticky comment for details.");
return;
}
core.info("PR intake sanity checks found advisory issues only.");