eslint-factory: recognize JSDoc @param {typeof import('@actions/core')} as core-alias signal - #49502
Conversation
…lve.ts Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
PR Triage
Note: Draft, no diff yet (still generating)
|
…/core')} in core-method-resolve Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
@param {typeof import('@actions/core')} as core-alias signal
There was a problem hiding this comment.
Pull request overview
Extends shared ESLint core-method resolution to recognize JSDoc-typed dependency-injection parameters.
Changes:
- Adds JSDoc-based core parameter detection.
- Adds direct-call coverage for two ESLint rules.
- Regenerates an unrelated workflow lock file.
Show a summary per file
| File | Description |
|---|---|
core-method-resolve.ts |
Adds JSDoc-aware alias resolution. |
require-return-after-core-setfailed.test.ts |
Tests annotated setFailed calls. |
no-core-setoutput-non-string.test.ts |
Tests annotated setOutput calls. |
daily-byok-ollama-test.lock.yml |
Adds generated model and pricing configuration. |
Review details
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 4/4 changed files
- Comments generated: 4
- Review effort level: Balanced
| * in a JSDoc block-comment value. Used as an unambiguous signal that a parameter | ||
| * is a dependency-injected `@actions/core`-like object. | ||
| */ | ||
| const JSDOC_CORE_PARAM_RE = /@param\s*\{typeof\s+import\(['"]@actions\/core['"]\)\}\s+(\w+)/g; |
There was a problem hiding this comment.
Fixed in 9cfa1fa — changed JSDOC_CORE_PARAM_RE to use ([$\w]+) so identifiers containing $ (e.g. $core) are captured correctly.
| // Slow path: JSDoc @param {typeof import('@actions/core')} annotation on | ||
| // the enclosing function is an unambiguous signal for DI-style parameters | ||
| // with non-canonical names (e.g. `coreArg`, `coreLib`). | ||
| return hasJSDocCoreParamAnnotation(def.node, identifier.name, sourceCode); |
There was a problem hiding this comment.
Fixed in 9cfa1fa — the variable branch in isCoreAliasIdentifier now checks || isJSDocCoreParamInScope(declarator.init as TSESTree.Identifier, sourceCode) so const c = coreArg is recognized when coreArg is JSDoc-annotated.
| const declarator = def.node as TSESTree.VariableDeclarator; | ||
| if (!declarator.init) return false; | ||
| if (declarator.id.type === AST_NODE_TYPES.ObjectPattern && declarator.init.type === AST_NODE_TYPES.Identifier && CORE_ALIASES.has(declarator.init.name)) { | ||
| if (declarator.id.type === AST_NODE_TYPES.ObjectPattern && declarator.init.type === AST_NODE_TYPES.Identifier && (CORE_ALIASES.has(declarator.init.name) || isJSDocCoreParamInScope(declarator.init, sourceCode))) { |
| (umask 177 && touch /tmp/gh-aw/threat-detection/detection.log) | ||
| GH_AW_MAX_AI_CREDITS="${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }}" | ||
| printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.43/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"github.com\",\"host.docker.internal\",\"raw.githubusercontent.com\",\"registry.npmjs.org\",\"telemetry.enterprise.githubcopilot.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5,\"targets\":{\"copilot\":{\"host\":\"host.docker.internal:11434\"}}},\"container\":{\"imageTag\":\"0.27.43,squid=sha256:26be5e0b8c8f4c41c8a59126b29bb5d80b07253597472ded2a16bdd75abcbf9d,agent=sha256:04e2d1987a565000a8f114b89d806ae7a3864dd4f944be65275b28c93d8690e6,api-proxy=sha256:d85f57975af5ea23af4996e41ed73fbc8f5b4a47402472bfe82e508f352cb0c1,cli-proxy=sha256:65c45ea2967984d0024f3df61bc71335658a77ede96c8d9665da7a5f33a795ab\"},\"logging\":{\"proxyLogsDir\":\"/tmp/gh-aw/sandbox/firewall/logs\",\"auditDir\":\"/tmp/gh-aw/sandbox/firewall/audit\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json" | ||
| printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.43/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"github.com\",\"host.docker.internal\",\"raw.githubusercontent.com\",\"registry.npmjs.org\",\"telemetry.enterprise.githubcopilot.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5,\"defaultAiCreditsPricing\":{\"input\":0.000001,\"output\":0.000001},\"targets\":{\"copilot\":{\"host\":\"host.docker.internal:11434\"}},\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-5.4\",\"gpt-5.5\",\"gpt-5.6\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"auto\":[\"copilot/auto\",\"large\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\",\"kimi\"],\"computer-use\":[\"copilot/*computer-use*\",\"google/*computer-use*\",\"gemini/*computer-use*\",\"openai/*computer-use*\"],\"copilot\":[\"agent\"],\"deep-research\":[\"copilot/deep-research*\",\"copilot/o3-deep-research*\",\"copilot/o4-mini-deep-research*\",\"google/deep-research*\",\"gemini/deep-research*\",\"openai/o3-deep-research*\",\"openai/o4-mini-deep-research*\"],\"fable\":[\"copilot/*fable*\",\"anthropic/*fable*\"],\"gemini\":[\"agent\"],\"gemini-3-flash\":[\"copilot/gemini-3*flash*\",\"google/gemini-3*flash*\",\"gemini/gemini-3*flash*\"],\"gemini-3-pro\":[\"copilot/gemini-3*pro*\",\"google/gemini-3*pro*\",\"google/nano-banana*\",\"gemini/gemini-3*pro*\"],\"gemini-3.1-flash\":[\"copilot/gemini-3.1*flash*\",\"google/gemini-3.1*flash*\",\"gemini/gemini-3.1*flash*\"],\"gemini-3.1-pro\":[\"copilot/gemini-3.1*pro*\",\"google/gemini-3.1*pro*\",\"gemini/gemini-3.1*pro*\"],\"gemini-3.5-flash\":[\"copilot/gemini-3.5*flash*\",\"google/gemini-3.5*flash*\",\"gemini/gemini-3.5*flash*\"],\"gemini-3.6-flash\":[\"copilot/gemini-3.6*flash*\",\"google/gemini-3.6*flash*\",\"gemini/gemini-3.6*flash*\"],\"gemini-flash\":[\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"],\"gemini-flash-lite\":[\"copilot/gemini-*flash*lite*\",\"google/gemini-*flash*lite*\",\"gemini/gemini-*flash*lite*\"],\"gemini-omni\":[\"copilot/gemini-omni*\",\"google/gemini-omni*\",\"gemini/gemini-omni*\"],\"gemini-pro\":[\"copilot/gemini-*pro*\",\"google/gemini-*pro*\",\"gemini/gemini-*pro*\"],\"gemma\":[\"copilot/gemma*\",\"google/gemma*\",\"gemini/gemma*\"],\"gpt-5\":[\"copilot/gpt-5*\",\"openai/gpt-5*\"],\"gpt-5-codex\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\"],\"gpt-5-mini\":[\"copilot/gpt-5*mini*\",\"openai/gpt-5*mini*\"],\"gpt-5-nano\":[\"copilot/gpt-5*nano*\",\"openai/gpt-5*nano*\"],\"gpt-5-pro\":[\"copilot/gpt-5*pro*\",\"openai/gpt-5*pro*\"],\"gpt-5.1\":[\"copilot/gpt-5.1*\",\"openai/gpt-5.1*\"],\"gpt-5.2\":[\"copilot/gpt-5.2*\",\"openai/gpt-5.2*\"],\"gpt-5.3\":[\"copilot/gpt-5.3*\",\"openai/gpt-5.3*\"],\"gpt-5.4\":[\"copilot/gpt-5.4*\",\"openai/gpt-5.4*\"],\"gpt-5.5\":[\"copilot/gpt-5.5*\",\"openai/gpt-5.5*\"],\"gpt-5.6\":[\"copilot/gpt-5.6*\",\"openai/gpt-5.6*\"],\"grok\":[\"copilot/*grok*\",\"openai/*grok*\"],\"haiku\":[\"copilot/*haiku*\",\"anthropic/*haiku*\"],\"image-generation\":[\"copilot/gpt-image*\",\"openai/gpt-image*\",\"openai/chatgpt-image*\",\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"google/imagen*\"],\"kimi\":[\"copilot/kimi*\",\"openai/kimi*\"],\"kiwi\":[\"copilot/kiwi*\",\"openai/kiwi*\"],\"large\":[\"sonnet\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"lyria\":[\"google/lyria*\",\"gemini/lyria*\",\"copilot/lyria*\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"mai-code-1-flash-picker\":[\"copilot/MAI-Code-1-Flash-picker*\",\"copilot/mai-code-1-flash-picker*\",\"openai/MAI-Code-1-Flash-picker*\"],\"mini\":[\"haiku\",\"gpt-5-mini\",\"gpt-5-nano\",\"gemini-flash-lite\"],\"nano-banana\":[\"copilot/nano-banana*\",\"google/nano-banana*\",\"gemini/nano-banana*\"],\"opus\":[\"copilot/*opus*\",\"anthropic/*opus*\"],\"opusplan\":[\"opus?effort=high\"],\"raptor-mini\":[\"copilot/raptor*\",\"openai/raptor*\"],\"reasoning\":[\"copilot/o1*\",\"copilot/o3*\",\"copilot/o4*\",\"openai/o1*\",\"openai/o3*\",\"openai/o4*\"],\"robotics\":[\"copilot/*robotics*\",\"google/*robotics*\",\"gemini/*robotics*\"],\"small\":[\"mini\"],\"small-agent\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash\"],\"sonnet\":[\"copilot/*sonnet*\",\"anthropic/*sonnet*\"],\"sonnet-6x\":[\"copilot/*sonnet-4.5*\",\"copilot/*sonnet-4.6*\",\"copilot/*sonnet-5*\",\"copilot/*sonnet-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\",\"anthropic/*sonnet-5*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"veo\":[\"google/veo*\",\"gemini/veo*\"],\"vision\":[\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.27.43,squid=sha256:26be5e0b8c8f4c41c8a59126b29bb5d80b07253597472ded2a16bdd75abcbf9d,agent=sha256:04e2d1987a565000a8f114b89d806ae7a3864dd4f944be65275b28c93d8690e6,api-proxy=sha256:d85f57975af5ea23af4996e41ed73fbc8f5b4a47402472bfe82e508f352cb0c1,cli-proxy=sha256:65c45ea2967984d0024f3df61bc71335658a77ede96c8d9665da7a5f33a795ab\"},\"logging\":{\"proxyLogsDir\":\"/tmp/gh-aw/sandbox/firewall/logs\",\"auditDir\":\"/tmp/gh-aw/sandbox/firewall/audit\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json" |
There was a problem hiding this comment.
This lock file change cannot be reverted without breaking check-workflow-drift. The .md source is unchanged in this PR, but make recompile now generates the extended content (fallback pricing + model-routing policy) due to updates in the compilation tooling. The check-workflow-drift gate requires lock files to always match what compilation produces. The lock file stays in sync with the compiler output.
|
✅ Test Quality Sentinel completed test quality analysis. No test files were added or modified in this PR. Test Quality Sentinel skipped. |
|
✅ PR Code Quality Reviewer completed the code quality review. |
|
🧠 Matt Pocock Skills Reviewer has completed the skills-based review. ✅ |
|
✅ Design Decision Gate 🏗️ completed the design decision gate check. No ADR enforcement needed: PR #49502 does not have the 'implementation' label and has 0 new lines of code in business logic directories (threshold: 100). |
There was a problem hiding this comment.
The JSDoc-based slow path is well-structured. Global regex lastIndex is correctly reset before each exec loop. def.node for Parameter defs correctly points to the enclosing function, so getCommentsBefore finds the JSDoc. Arrow-function assignments are handled by walking up to VariableDeclarator.parent. Test coverage is thorough: valid and invalid cases for both affected rules, including the double-quote variant and the un-annotated-parameter must-not-match case.
🧵 Reviewed using Impeccable skills by Impeccable Skills Reviewer · sonnet46 · 20.3 AIC · ⌖ 8.88 AIC · ⊞ 5.3K
There was a problem hiding this comment.
Skills-Based Review
Applied /diagnosing-bugs and /tdd — requesting changes on correctness gaps and missing test coverage.
Key Themes and Highlights
Key Themes
- Regex
\w+excludes$in param names —JSDOC_CORE_PARAM_REwon't match$coreor_core-style parameters (already flagged inline at line 9). - Destructuring path has no test coverage —
isDestructuredCoreMethodIdentifierwas extended to accept destructuring from JSDoc-annotated params, but neither test file exercises this path (flagged inline). - Reassignment blind spot undocumented —
const c = coreArg; c.setOutput(...)silently escapes all rules because scope lookup only followsParameterdefs, not variable assignments. A negative test and a note in the PR description would set expectations (flagged inline). VariableDeclaratorJSDoc path untested —const f = function(coreArg) {}with JSDoc on theconstis code-path present but has no test case.
Positive Highlights
- Dual-gate strategy (fast path / slow path) is clean and well-documented
lastIndex = 0reset before eachexecon the sharedg-flag regex prevents stateful bugs- Negative tests (un-annotated
coreArgstays invisible) are a strong regression guard - Both single- and double-quote JSDoc variants are covered
🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · sonnet46 · 36.8 AIC · ⌖ 7.56 AIC · ⊞ 7K
Comment /matt to run again
There was a problem hiding this comment.
Verdict: Request changes — solid, well-tested fix but with real false-negative gaps and an unexplained unrelated file change.
💡 Themes and highlights
The core logic (two-gate isCoreAliasIdentifier, scope-based isJSDocCoreParamInScope) is sound and well-documented, and the new test coverage for the DI + JSDoc pattern is genuinely good (valid/invalid/negative cases across two rule test suites).
However:
- Missed
export function/export async functioncase — a pattern already used in this codebase (main()entrypoints) — becausegetCommentsBeforeis only checked against the function node and itsVariableDeclarationparent, never anExportNamedDeclaration/ExportDefaultDeclarationwrapper. This silently defeats the annotation for a real, existing usage pattern. - The
\w+parameter-name regex excludes$and other legal identifier characters, narrowing the very guarantee this PR is trying to widen (flagged by a prior reviewer as well). - The destructuring branch (
isDestructuredCoreMethodIdentifier) gained JSDoc-alias support but has no direct test coverage exercising it (also flagged previously). - The bundled
.github/workflows/daily-byok-ollama-test.lock.ymldiff (fallback pricing + model routing policy) is unrelated to the stated ESLint fix and unexplained in the PR description — this should be reverted from this PR or justified separately (also flagged previously).
The export-wrapped function gap is a new, concrete finding that should be fixed before merge since it silently reintroduces the exact false-negative class this PR sets out to close.
🔎 Code quality review by PR Code Quality Reviewer · auto · 58.9 AIC · ⌖ 9.31 AIC · ⊞ 7.8K
Comment /review to run again
| function hasJSDocCoreParamAnnotation(functionNode: TSESTree.Node, paramName: string, sourceCode: TSESLint.SourceCode): boolean { | ||
| const nodesToCheck: TSESTree.Node[] = [functionNode]; | ||
| const parent = functionNode.parent; | ||
| if (parent?.type === AST_NODE_TYPES.VariableDeclarator && parent.parent) { |
There was a problem hiding this comment.
JSDoc lookup misses a real, used pattern in this codebase: export function/export async function (e.g. main).
💡 Details
hasJSDocCoreParamAnnotation only checks comments before functionNode itself, and, when the parent is a VariableDeclarator, before the enclosing VariableDeclaration. It never checks a preceding ExportNamedDeclaration/ExportDefaultDeclaration wrapper. For:
/**
* `@param` {typeof import('`@actions/core`')} coreArg
*/
export async function main(coreArg) { coreArg.setFailed("x"); }sourceCode.getCommentsBefore(functionNode) returns an empty array because the JSDoc precedes the ExportNamedDeclaration, not the FunctionDeclaration node — so the annotation is silently ignored and the rule falls through to false-negative behavior. This pattern is already used elsewhere in this codebase (e.g. export async function main() fixtures in no-core-error-then-process-exitcode.test.ts), so this is a concrete gap, not a hypothetical one. Fix: also check functionNode.parent when it is an ExportNamedDeclaration/ExportDefaultDeclaration.
There was a problem hiding this comment.
Fixed in 60e26fa — hasJSDocCoreParamAnnotation now also pushes functionNode.parent onto nodesToCheck when the parent is an ExportNamedDeclaration or ExportDefaultDeclaration, so JSDoc before export async function main(coreArg) is correctly recognized. ESM valid and invalid test cases were added to both test files.
| * in a JSDoc block-comment value. Used as an unambiguous signal that a parameter | ||
| * is a dependency-injected `@actions/core`-like object. | ||
| */ | ||
| const JSDOC_CORE_PARAM_RE = /@param\s*\{typeof\s+import\(['"]@actions\/core['"]\)\}\s+(\w+)/g; |
There was a problem hiding this comment.
The \w+ parameter-name matcher silently rejects valid JS identifiers containing $ or Unicode letters.
💡 Details
JSDOC_CORE_PARAM_RE captures the JSDoc param name with (\w+), which is [A-Za-z0-9_]. Real, legal JS identifiers like $core, core$, or coréArg won't match, so a correctly-annotated function using such a name is silently treated as un-annotated — a false negative with no test coverage or fallback warning. Given the whole point of this PR is closing false-negative gaps for non-canonical parameter names, this narrows the fix's own guarantee. Consider [$\w]+ at minimum, or a broader identifier-safe character class.
There was a problem hiding this comment.
Fixed in 9cfa1fa — JSDOC_CORE_PARAM_RE now captures ([$\w]+) instead of (\w+) so identifiers with $ (e.g. $core) match correctly.
| (umask 177 && touch /tmp/gh-aw/threat-detection/detection.log) | ||
| GH_AW_MAX_AI_CREDITS="${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }}" | ||
| printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.43/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"github.com\",\"host.docker.internal\",\"raw.githubusercontent.com\",\"registry.npmjs.org\",\"telemetry.enterprise.githubcopilot.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5,\"targets\":{\"copilot\":{\"host\":\"host.docker.internal:11434\"}}},\"container\":{\"imageTag\":\"0.27.43,squid=sha256:26be5e0b8c8f4c41c8a59126b29bb5d80b07253597472ded2a16bdd75abcbf9d,agent=sha256:04e2d1987a565000a8f114b89d806ae7a3864dd4f944be65275b28c93d8690e6,api-proxy=sha256:d85f57975af5ea23af4996e41ed73fbc8f5b4a47402472bfe82e508f352cb0c1,cli-proxy=sha256:65c45ea2967984d0024f3df61bc71335658a77ede96c8d9665da7a5f33a795ab\"},\"logging\":{\"proxyLogsDir\":\"/tmp/gh-aw/sandbox/firewall/logs\",\"auditDir\":\"/tmp/gh-aw/sandbox/firewall/audit\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json" | ||
| printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.43/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"github.com\",\"host.docker.internal\",\"raw.githubusercontent.com\",\"registry.npmjs.org\",\"telemetry.enterprise.githubcopilot.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5,\"defaultAiCreditsPricing\":{\"input\":0.000001,\"output\":0.000001},\"targets\":{\"copilot\":{\"host\":\"host.docker.internal:11434\"}},\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-5.4\",\"gpt-5.5\",\"gpt-5.6\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"auto\":[\"copilot/auto\",\"large\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\",\"kimi\"],\"computer-use\":[\"copilot/*computer-use*\",\"google/*computer-use*\",\"gemini/*computer-use*\",\"openai/*computer-use*\"],\"copilot\":[\"agent\"],\"deep-research\":[\"copilot/deep-research*\",\"copilot/o3-deep-research*\",\"copilot/o4-mini-deep-research*\",\"google/deep-research*\",\"gemini/deep-research*\",\"openai/o3-deep-research*\",\"openai/o4-mini-deep-research*\"],\"fable\":[\"copilot/*fable*\",\"anthropic/*fable*\"],\"gemini\":[\"agent\"],\"gemini-3-flash\":[\"copilot/gemini-3*flash*\",\"google/gemini-3*flash*\",\"gemini/gemini-3*flash*\"],\"gemini-3-pro\":[\"copilot/gemini-3*pro*\",\"google/gemini-3*pro*\",\"google/nano-banana*\",\"gemini/gemini-3*pro*\"],\"gemini-3.1-flash\":[\"copilot/gemini-3.1*flash*\",\"google/gemini-3.1*flash*\",\"gemini/gemini-3.1*flash*\"],\"gemini-3.1-pro\":[\"copilot/gemini-3.1*pro*\",\"google/gemini-3.1*pro*\",\"gemini/gemini-3.1*pro*\"],\"gemini-3.5-flash\":[\"copilot/gemini-3.5*flash*\",\"google/gemini-3.5*flash*\",\"gemini/gemini-3.5*flash*\"],\"gemini-3.6-flash\":[\"copilot/gemini-3.6*flash*\",\"google/gemini-3.6*flash*\",\"gemini/gemini-3.6*flash*\"],\"gemini-flash\":[\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"],\"gemini-flash-lite\":[\"copilot/gemini-*flash*lite*\",\"google/gemini-*flash*lite*\",\"gemini/gemini-*flash*lite*\"],\"gemini-omni\":[\"copilot/gemini-omni*\",\"google/gemini-omni*\",\"gemini/gemini-omni*\"],\"gemini-pro\":[\"copilot/gemini-*pro*\",\"google/gemini-*pro*\",\"gemini/gemini-*pro*\"],\"gemma\":[\"copilot/gemma*\",\"google/gemma*\",\"gemini/gemma*\"],\"gpt-5\":[\"copilot/gpt-5*\",\"openai/gpt-5*\"],\"gpt-5-codex\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\"],\"gpt-5-mini\":[\"copilot/gpt-5*mini*\",\"openai/gpt-5*mini*\"],\"gpt-5-nano\":[\"copilot/gpt-5*nano*\",\"openai/gpt-5*nano*\"],\"gpt-5-pro\":[\"copilot/gpt-5*pro*\",\"openai/gpt-5*pro*\"],\"gpt-5.1\":[\"copilot/gpt-5.1*\",\"openai/gpt-5.1*\"],\"gpt-5.2\":[\"copilot/gpt-5.2*\",\"openai/gpt-5.2*\"],\"gpt-5.3\":[\"copilot/gpt-5.3*\",\"openai/gpt-5.3*\"],\"gpt-5.4\":[\"copilot/gpt-5.4*\",\"openai/gpt-5.4*\"],\"gpt-5.5\":[\"copilot/gpt-5.5*\",\"openai/gpt-5.5*\"],\"gpt-5.6\":[\"copilot/gpt-5.6*\",\"openai/gpt-5.6*\"],\"grok\":[\"copilot/*grok*\",\"openai/*grok*\"],\"haiku\":[\"copilot/*haiku*\",\"anthropic/*haiku*\"],\"image-generation\":[\"copilot/gpt-image*\",\"openai/gpt-image*\",\"openai/chatgpt-image*\",\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"google/imagen*\"],\"kimi\":[\"copilot/kimi*\",\"openai/kimi*\"],\"kiwi\":[\"copilot/kiwi*\",\"openai/kiwi*\"],\"large\":[\"sonnet\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"lyria\":[\"google/lyria*\",\"gemini/lyria*\",\"copilot/lyria*\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"mai-code-1-flash-picker\":[\"copilot/MAI-Code-1-Flash-picker*\",\"copilot/mai-code-1-flash-picker*\",\"openai/MAI-Code-1-Flash-picker*\"],\"mini\":[\"haiku\",\"gpt-5-mini\",\"gpt-5-nano\",\"gemini-flash-lite\"],\"nano-banana\":[\"copilot/nano-banana*\",\"google/nano-banana*\",\"gemini/nano-banana*\"],\"opus\":[\"copilot/*opus*\",\"anthropic/*opus*\"],\"opusplan\":[\"opus?effort=high\"],\"raptor-mini\":[\"copilot/raptor*\",\"openai/raptor*\"],\"reasoning\":[\"copilot/o1*\",\"copilot/o3*\",\"copilot/o4*\",\"openai/o1*\",\"openai/o3*\",\"openai/o4*\"],\"robotics\":[\"copilot/*robotics*\",\"google/*robotics*\",\"gemini/*robotics*\"],\"small\":[\"mini\"],\"small-agent\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash\"],\"sonnet\":[\"copilot/*sonnet*\",\"anthropic/*sonnet*\"],\"sonnet-6x\":[\"copilot/*sonnet-4.5*\",\"copilot/*sonnet-4.6*\",\"copilot/*sonnet-5*\",\"copilot/*sonnet-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\",\"anthropic/*sonnet-5*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"veo\":[\"google/veo*\",\"gemini/veo*\"],\"vision\":[\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.27.43,squid=sha256:26be5e0b8c8f4c41c8a59126b29bb5d80b07253597472ded2a16bdd75abcbf9d,agent=sha256:04e2d1987a565000a8f114b89d806ae7a3864dd4f944be65275b28c93d8690e6,api-proxy=sha256:d85f57975af5ea23af4996e41ed73fbc8f5b4a47402472bfe82e508f352cb0c1,cli-proxy=sha256:65c45ea2967984d0024f3df61bc71335658a77ede96c8d9665da7a5f33a795ab\"},\"logging\":{\"proxyLogsDir\":\"/tmp/gh-aw/sandbox/firewall/logs\",\"auditDir\":\"/tmp/gh-aw/sandbox/firewall/audit\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json" |
There was a problem hiding this comment.
This generated workflow change (fallback pricing + full model-routing policy) is unrelated to the described ESLint fix and is bundled without explanation.
💡 Details
The PR description is entirely about core-method-resolve.ts JSDoc recognition, yet this lock file diff adds defaultAiCreditsPricing and a large models routing table to the daily BYOK Ollama test's firewall/proxy config. This is almost certainly a stale/regenerated artifact from running make recompile against a newer source template rather than an intentional part of this fix. Bundling unrelated generated changes into a focused PR makes it harder to review, bisect, and roll back independently — if this config change is wrong or has unintended effects on credit limits/model routing, it will be attributed to the wrong PR. Recommend reverting this file's changes here and letting it land in its own separate PR alongside whatever change actually motivates it (or confirming intentionally that this drift is expected).
There was a problem hiding this comment.
This lock file change cannot be reverted without breaking check-workflow-drift. The .md source is unchanged in this PR, but make recompile now generates the extended content due to updates in the compilation tooling. Keeping the lock file in sync with compilation is required by the tooling gate.
|
@copilot run pr-finisher skill |
- Fix JSDOC_CORE_PARAM_RE to capture [$\w]+ (supports $ in param names) - Fix variable alias branch to check isJSDocCoreParamInScope (const c = coreArg) - Add destructuring test coverage for JSDoc-annotated DI params - Lock file stays compiled (daily-byok-ollama-test: recompile artifact, unchanged md source) Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
…hen test coverage - hasJSDocCoreParamAnnotation: also checks ExportNamedDeclaration/ExportDefaultDeclaration parent so JSDoc before `export async function f(coreArg)` is recognized - Add esmRuleTester to require-return-after-core-setfailed and no-core-setoutput-non-string - Add valid/invalid ESM test groups covering `export async function` with JSDoc-annotated params Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
All review feedback addressed (commits 9cfa1fa and 60e26fa):
Local validation: |
|
@copilot quick triage for this PR:
|
|
🎉 This pull request is included in a new release. Release: |
8 ESLint rules sharing
core-method-resolve.tswere blind to DI-style@actions/coreparameters with non-canonical names (e.g.,coreArg) becauseisCoreAliasIdentifieronly matched againstCORE_ALIASES = {"core", "coreObj"}. Any function likeasync function f(coreArg, ctx)was invisible to all affected rules regardless of its JSDoc type annotation.Changes
core-method-resolve.tsJSDOC_CORE_PARAM_RE— matches@param {typeof import('@actions/core')} <name>in block comments (single- and double-quote variants).hasJSDocCoreParamAnnotation(functionNode, paramName, sourceCode)— checks JSDoc before the function node and its parentVariableDeclaration(for function expressions).isJSDocCoreParamInScope(identifier, sourceCode)— resolves an identifier through scope and checks for the annotation.isCoreAliasIdentifier— Parameter branch now has two gates: CORE_ALIASES fast path, then JSDoc slow path. Existing exact-name semantics are fully preserved.isDestructuredCoreMethodIdentifier— accepts destructuring from JSDoc-annotated core parameters (e.g.,const { setFailed } = coreArg).Tests — new
it()groups inrequire-return-after-core-setfailed.test.tsandno-core-setoutput-non-string.test.tscovering:coreArg.setFailed(msg); throw …recognized as compliant (not a false positive).coreArg.setFailed(…)is flagged with suggestion.coreArgwithout JSDoc remains unrecognized (false-positive guard).Before / after
Parameters without the JSDoc type annotation continue to be ignored — broad prefix/regex matching is intentionally avoided.