feat: extract LGTM processor to external JS file with tests#6074
feat: extract LGTM processor to external JS file with tests#6074Skarlso merged 4 commits intoexternal-secrets:mainfrom
Conversation
Moves the inline JavaScript from the 'Process LGTM Command' step in .github/workflows/lgtm.yml into a separate module at .github/scripts/lgtm-processor.js. Behaviour is unchanged — this is a faithful extraction with no logic modifications. Also adds .github/scripts/lgtm-processor-test.js with unit tests for the pure helper logic (CODEOWNERS parsing, file-pattern matching, required-role resolution) using Node.js built-in assert. Run with: node --input-type=module < .github/scripts/lgtm-processor-test.js Closes external-secrets#5500 Signed-off-by: Mateen Anjum <mateenali66@gmail.com>
WalkthroughIntroduces an LGTM command processor that automates pull request approval workflows. A new external module parses CODEOWNERS mappings and manages reviewer role-based label approval. The workflow file refactors to use this module instead of inline logic. A test suite validates the parsing and pattern matching functionality. Changes
📝 Coding Plan
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment Tip CodeRabbit can generate a title for your PR based on the changes.Add |
There was a problem hiding this comment.
Actionable comments posted: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
.github/workflows/lgtm.yml (1)
24-25:⚠️ Potential issue | 🔴 CriticalThe workflow no longer checks out the module it imports at runtime.
Only
CODEOWNERS.mdis present in the sparse checkout, but line 51 imports${GITHUB_WORKSPACE}/.github/scripts/lgtm-processor.js. On the runner that file is missing, soProcess LGTM Commandfails before it can parse CODEOWNERS or add the label.Suggested fix
with: sparse-checkout: | CODEOWNERS.md + .github/scripts🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/workflows/lgtm.yml around lines 24 - 25, The sparse-checkout only includes CODEOWNERS.md but the workflow job "Process LGTM Command" requires the lgtm-processor.js script at runtime; update the sparse-checkout config in lgtm.yml to include the lgtm-processor.js file (or switch to a full checkout) so the runner can find and import lgtm-processor.js and the job no longer fails due to a missing file.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.github/scripts/lgtm-processor-test.js:
- Around line 14-16: The test file duplicates pure helpers (parseCodeowners,
fileMatchesPattern, getRequiredReviewerRoles) so regressions in the real
processor aren’t caught; extract those helper functions into a single shared
module (or export them from the existing processor module) and update both the
processor and .github/scripts/lgtm-processor-test.js to import the shared
helpers instead of reimplementing them, ensuring the exported symbol names
(parseCodeowners, fileMatchesPattern, getRequiredReviewerRoles) are used and
update any require/import statements accordingly.
- Around line 54-64: The forEach callbacks (codeownerMappings.forEach,
roles.forEach, wildcardRoles.forEach) implicitly return the value from
requiredReviewerRoles.add(...) which violates the lint rule; change each arrow
callback to use a block body with explicit statements (e.g., braces and a
semicolon) so they do not return a value — for example convert
roles.forEach(role => requiredReviewerRoles.add(role)) to roles.forEach(role =>
{ requiredReviewerRoles.add(role); }); and likewise use a block for the
codeownerMappings.forEach callback that calls fileMatchesPattern and the inner
roles.forEach, ensuring no value is returned from the outer callback.
In @.github/scripts/lgtm-processor.js:
- Line 14: The file currently uses ESM export syntax for the async function run
which will fail when imported by the workflow as CommonJS; fix this by
converting the export to CommonJS (replace the ESM export with module.exports =
async function run(...) or assign exports.run = run after declaration), or
alternatively make the module truly ESM by adding a package.json with "type":
"module" adjacent to the script or renaming the file to .mjs so Node parses it
as ESM; target the exported symbol run in .github/scripts/lgtm-processor.js when
applying the change.
- Around line 108-115: The forEach callbacks are implicitly returning values
(violating useIterableCallbackReturn); change the concise arrow body that calls
roles.forEach(role => requiredReviewerRoles.add(role)) to a block-bodied arrow
that performs the add without returning a value — e.g., inside the
codeownerMappings.forEach callback (mapping, pattern, file, hasSpecificOwner)
replace roles.forEach(role => requiredReviewerRoles.add(role)) with
roles.forEach(role => { requiredReviewerRoles.add(role); }); ensure no return
value is produced from the forEach callbacks and preserve the existing logic
that sets hasSpecificOwner when a pattern matches.
- Around line 96-99: The current call to github.rest.pulls.listFiles only
fetches one page, so changedFiles misses files when a PR has >30 files; replace
the single-page fetch with a paginated fetch (e.g. use github.paginate or an
explicit loop) to retrieve all files for the given owner, repo and prNumber,
then compute changedFiles by mapping filenames across the full paginated result;
update references around filesResponse/changedFiles to use the full list
returned by github.paginate(github.rest.pulls.listFiles, { owner, repo,
pull_number: prNumber }).
---
Outside diff comments:
In @.github/workflows/lgtm.yml:
- Around line 24-25: The sparse-checkout only includes CODEOWNERS.md but the
workflow job "Process LGTM Command" requires the lgtm-processor.js script at
runtime; update the sparse-checkout config in lgtm.yml to include the
lgtm-processor.js file (or switch to a full checkout) so the runner can find and
import lgtm-processor.js and the job no longer fails due to a missing file.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 50331ac0-d465-4c8a-b059-7a15fc6358d7
📒 Files selected for processing (3)
.github/scripts/lgtm-processor-test.js.github/scripts/lgtm-processor.js.github/workflows/lgtm.yml
| // Helpers duplicated from lgtm-processor.js for unit testing | ||
| // (kept in sync manually; tests will catch drift) | ||
| // --------------------------------------------------------------------------- |
There was a problem hiding this comment.
These tests are asserting copies of the helpers, not the helpers the workflow executes.
Because parseCodeowners, fileMatchesPattern, and getRequiredReviewerRoles are reimplemented here, a regression in .github/scripts/lgtm-processor.js can still leave this file green. Please move the pure helpers into a shared module, or export them from the processor and import them here instead.
Also applies to: 18-68
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.github/scripts/lgtm-processor-test.js around lines 14 - 16, The test file
duplicates pure helpers (parseCodeowners, fileMatchesPattern,
getRequiredReviewerRoles) so regressions in the real processor aren’t caught;
extract those helper functions into a single shared module (or export them from
the existing processor module) and update both the processor and
.github/scripts/lgtm-processor-test.js to import the shared helpers instead of
reimplementing them, ensuring the exported symbol names (parseCodeowners,
fileMatchesPattern, getRequiredReviewerRoles) are used and update any
require/import statements accordingly.
| codeownerMappings.forEach(({ pattern, roles }) => { | ||
| if (fileMatchesPattern(file, pattern)) { | ||
| roles.forEach(role => requiredReviewerRoles.add(role)); | ||
| hasSpecificOwner = true; | ||
| } | ||
| }); | ||
| if (!hasSpecificOwner) hasFilesWithoutSpecificOwners = true; | ||
| }); | ||
|
|
||
| if (hasFilesWithoutSpecificOwners) { | ||
| wildcardRoles.forEach(role => requiredReviewerRoles.add(role)); |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, check if the file exists and read lines 54-64
if [ -f ".github/scripts/lgtm-processor-test.js" ]; then
echo "=== File found. Reading lines 54-64 ==="
sed -n '54,64p' ".github/scripts/lgtm-processor-test.js"
else
echo "File not found at expected location. Searching for it..."
find . -name "lgtm-processor-test.js" -type f
fiRepository: external-secrets/external-secrets
Length of output: 511
🏁 Script executed:
# Also check the broader context around those lines
if [ -f ".github/scripts/lgtm-processor-test.js" ]; then
echo "=== Broader context (lines 45-75) ==="
sed -n '45,75p' ".github/scripts/lgtm-processor-test.js"
fiRepository: external-secrets/external-secrets
Length of output: 1067
🏁 Script executed:
# Check if this is a test file and look for the exact forEach patterns mentioned
if [ -f ".github/scripts/lgtm-processor-test.js" ]; then
echo "=== Checking for forEach patterns mentioned in review ==="
grep -n "roles.forEach\|wildcardRoles.forEach" ".github/scripts/lgtm-processor-test.js"
fiRepository: external-secrets/external-secrets
Length of output: 272
🌐 Web query:
Biome lint/suspicious/useIterableCallbackReturn rule
💡 Result:
lint/suspicious/useIterableCallbackReturn is a Biome linter rule that enforces consistent return behavior in callbacks passed to iterable/array methods. It’s recommended (enabled by default) and errors by default. (biomejs.dev)
What it checks
Biome expects callbacks to follow the method’s contract: (biomejs.dev)
Callbacks must return a value (you’ll get an error if some paths don’t return):
every,filter,find,findIndex,findLast,findLastIndex,flatMap,map,reduce,reduceRight,some,sort,toSorted(andArray.from’s mapping callback) (biomejs.dev)
Callbacks must not return a value:
forEach(biomejs.dev)
Notes:
asyncandfunction*(generator) callbacks are ignored by this rule. (biomejs.dev)
Typical “why am I seeing this?” examples
map(() => { doStuff(); })→ missingreturnin the callback (should always return).forEach(() => { return 1; })→ returning a value fromforEachis flagged (should not return a value). (biomejs.dev)
Configure / disable
Enable/disable via biome.json: (biomejs.dev)
{
"linter": {
"rules": {
"suspicious": {
"useIterableCallbackReturn": "off"
}
}
}
}Or suppress locally using the rule’s diagnostic category in an ignore comment. (biomejs.dev)
Citations:
- 1: https://biomejs.dev/linter/rules/use-iterable-callback-return/?utm_source=openai
- 2: https://biomejs.dev/linter/rules/use-iterable-callback-return/?utm_source=openai
- 3: https://biomejs.dev/linter/rules/use-iterable-callback-return/?utm_source=openai
- 4: https://biomejs.dev/linter/rules/use-iterable-callback-return/?utm_source=openai
- 5: https://biomejs.dev/linter/rules/use-iterable-callback-return/?utm_source=openai
- 6: https://biomejs.dev/linter/rules/use-iterable-callback-return/?utm_source=openai
- 7: https://biomejs.dev/linter/rules/use-iterable-callback-return/?utm_source=openai
- 8: https://biomejs.dev/analyzer/suppressions/?utm_source=openai
🏁 Script executed:
# Let me also check what the .add() method returns
# and verify the implicit return behavior is as described
python3 <<'EOF'
# In JavaScript/TypeScript, Set.prototype.add() returns the Set instance itself
# This means in an arrow function like: role => requiredReviewerRoles.add(role)
# The callback implicitly returns the Set
print("Set.add() behavior:")
print("- Returns: the Set instance (for chaining)")
print("- Used in forEach: callback's return value is ignored")
print("- Issue: implicit return is confusing and suggests a mistake")
print()
print("The suggested fix (using block statement) prevents implicit return:")
print("roles.forEach(role => {")
print(" requiredReviewerRoles.add(role);")
print("});")
print()
print("In block statement form, there's no implicit return unless explicitly stated.")
EOFRepository: external-secrets/external-secrets
Length of output: 465
Fix implicit returns in forEach callbacks that violate lint/suspicious/useIterableCallbackReturn.
Both callbacks implicitly return the Set from .add(), triggering the Biome lint rule. The forEach method contract requires callbacks to not return a value.
Suggested fix
- if (fileMatchesPattern(file, pattern)) {
- roles.forEach(role => requiredReviewerRoles.add(role));
+ if (fileMatchesPattern(file, pattern)) {
+ roles.forEach(role => {
+ requiredReviewerRoles.add(role);
+ });
hasSpecificOwner = true;
}
@@
- wildcardRoles.forEach(role => requiredReviewerRoles.add(role));
+ wildcardRoles.forEach(role => {
+ requiredReviewerRoles.add(role);
+ });📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| codeownerMappings.forEach(({ pattern, roles }) => { | |
| if (fileMatchesPattern(file, pattern)) { | |
| roles.forEach(role => requiredReviewerRoles.add(role)); | |
| hasSpecificOwner = true; | |
| } | |
| }); | |
| if (!hasSpecificOwner) hasFilesWithoutSpecificOwners = true; | |
| }); | |
| if (hasFilesWithoutSpecificOwners) { | |
| wildcardRoles.forEach(role => requiredReviewerRoles.add(role)); | |
| codeownerMappings.forEach(({ pattern, roles }) => { | |
| if (fileMatchesPattern(file, pattern)) { | |
| roles.forEach(role => { | |
| requiredReviewerRoles.add(role); | |
| }); | |
| hasSpecificOwner = true; | |
| } | |
| }); | |
| if (!hasSpecificOwner) hasFilesWithoutSpecificOwners = true; | |
| }); | |
| if (hasFilesWithoutSpecificOwners) { | |
| wildcardRoles.forEach(role => { | |
| requiredReviewerRoles.add(role); | |
| }); |
🧰 Tools
🪛 Biome (2.4.6)
[error] 56-56: This callback passed to forEach() iterable method should not return a value.
(lint/suspicious/useIterableCallbackReturn)
[error] 64-64: This callback passed to forEach() iterable method should not return a value.
(lint/suspicious/useIterableCallbackReturn)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.github/scripts/lgtm-processor-test.js around lines 54 - 64, The forEach
callbacks (codeownerMappings.forEach, roles.forEach, wildcardRoles.forEach)
implicitly return the value from requiredReviewerRoles.add(...) which violates
the lint rule; change each arrow callback to use a block body with explicit
statements (e.g., braces and a semicolon) so they do not return a value — for
example convert roles.forEach(role => requiredReviewerRoles.add(role)) to
roles.forEach(role => { requiredReviewerRoles.add(role); }); and likewise use a
block for the codeownerMappings.forEach callback that calls fileMatchesPattern
and the inner roles.forEach, ensuring no value is returned from the outer
callback.
| * @param {object} params.context - GitHub Actions context | ||
| * @param {object} params.fs - Node.js fs module | ||
| */ | ||
| export default async function run({ core, github, context, fs }) { |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
found=0
for p in .github/scripts/package.json .github/package.json package.json; do
if [ -f "$p" ]; then
found=1
if rg -q '"type"\s*:\s*"module"' "$p"; then
echo "$p -> type=module"
else
echo "$p -> type!=module"
fi
fi
done
if [ "$found" -eq 0 ]; then
echo "No package.json found in the .github/scripts ancestry"
fiRepository: external-secrets/external-secrets
Length of output: 130
🏁 Script executed:
# Check root package.json existence and ESM type field
if [ -f package.json ]; then
echo "=== Root package.json exists ==="
cat package.json | head -20
if rg -q '"type"\s*:\s*"module"' package.json; then
echo "Contains: \"type\": \"module\""
else
echo "Does NOT contain: \"type\": \"module\""
fi
else
echo "Root package.json does NOT exist"
fiRepository: external-secrets/external-secrets
Length of output: 109
🏁 Script executed:
# Find workflow files that reference lgtm-processor.js
fd -e yml -e yaml .github/workflows | xargs grep -l "lgtm-processor" 2>/dev/null || echo "No workflow files reference lgtm-processor"Repository: external-secrets/external-secrets
Length of output: 510
🏁 Script executed:
# Find test files that might import lgtm-processor
fd -t f \( -name "*lgtm*" -o -name "*test*" \) .github/scripts 2>/dev/null || echo "No test files in .github/scripts"Repository: external-secrets/external-secrets
Length of output: 109
🏁 Script executed:
# Verify lgtm-processor.js exists
ls -la .github/scripts/lgtm-processor.js 2>/dev/null || echo "lgtm-processor.js NOT found"Repository: external-secrets/external-secrets
Length of output: 159
🏁 Script executed:
# Correctly search for workflow files in .github/workflows
fd . '.github/workflows' -e yml -e yaml | head -20Repository: external-secrets/external-secrets
Length of output: 731
🏁 Script executed:
# Search all workflows for any reference to Node.js scripts execution or lgtm
fd . '.github/workflows' -e yml -e yaml -exec grep -l "node\|lgtm\|scripts" {} \;Repository: external-secrets/external-secrets
Length of output: 2261
🏁 Script executed:
# Check lgtm.yml
cat .github/workflows/lgtm.ymlRepository: external-secrets/external-secrets
Length of output: 2060
🏁 Script executed:
# Check lgtm-remove-on-update.yml
cat .github/workflows/lgtm-remove-on-update.ymlRepository: external-secrets/external-secrets
Length of output: 1486
🏁 Script executed:
head -20 .github/scripts/lgtm-processor.jsRepository: external-secrets/external-secrets
Length of output: 851
Module format mismatch will cause workflow failure.
Line 14 exports using ESM syntax (export default), but the workflow in lgtm.yml attempts to import it via await import() with no ESM configuration in place. There is no package.json with "type": "module" in .github/scripts/, .github/, or the repository root. Node.js will parse the .js file as CommonJS by default and reject the export default syntax before any LGTM logic executes.
Either add "type": "module" to a package.json in .github/scripts/ (or .github/), rename the file to .mjs, or rewrite using CommonJS (module.exports).
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.github/scripts/lgtm-processor.js at line 14, The file currently uses ESM
export syntax for the async function run which will fail when imported by the
workflow as CommonJS; fix this by converting the export to CommonJS (replace the
ESM export with module.exports = async function run(...) or assign exports.run =
run after declaration), or alternatively make the module truly ESM by adding a
package.json with "type": "module" adjacent to the script or renaming the file
to .mjs so Node parses it as ESM; target the exported symbol run in
.github/scripts/lgtm-processor.js when applying the change.
There was a problem hiding this comment.
@mateenali66 I'm not great at Javascript, do you know if this is an actual problem? :DDD
I don't even understand what the problem is. :D
There was a problem hiding this comment.
Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!
There was a problem hiding this comment.
@Skarlso Not an actual problem — CodeRabbit got confused here.
The file is pure CommonJS: 'use strict' at the top, const fs = require('fs'), and module.exports = lgtmProcessor at the bottom. The workflow imports it with require('./.github/scripts/lgtm-processor.js'). No ESM anywhere.
CodeRabbit invented an export default on line 14 that doesn't exist — that line is just the start of the parseCodeowners function definition. Nothing to fix here.
There was a problem hiding this comment.
Thanks, that's what I thought.
| const filesResponse = await github.rest.pulls.listFiles({ | ||
| owner, repo, pull_number: prNumber | ||
| }); | ||
| const changedFiles = filesResponse.data.map(f => f.filename); |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, let's examine the file and see the context around lines 96-99
fd -t f "lgtm-processor.js" && wc -l .github/scripts/lgtm-processor.jsRepository: external-secrets/external-secrets
Length of output: 114
🏁 Script executed:
# Read the relevant section with context
cat -n .github/scripts/lgtm-processor.js | sed -n '85,115p'Repository: external-secrets/external-secrets
Length of output: 1498
🏁 Script executed:
# Check the full file to understand the complete flow
cat -n .github/scripts/lgtm-processor.jsRepository: external-secrets/external-secrets
Length of output: 10221
🌐 Web query:
GitHub API REST pulls.listFiles pagination default page size
💡 Result:
For the REST endpoint “List pull request files” (GET /repos/{owner}/{repo}/pulls/{pull_number}/files, i.e. pulls.listFiles):
- Default page size (
per_page) is 30 files if you don’t specify it. [1], [2] - You can set
per_pageup to 100 (then paginate withpage=2,page=3, etc., following the responseLinkheader). [1]
Example: .../pulls/123/files?per_page=100&page=1 [1]
Sources: [1] (docs.github.com) [2] (octokit.github.io)
Citations:
- 1: https://docs.github.com/zh/enterprise-server%403.18/rest/pulls/pulls?utm_source=openai
- 2: https://octokit.github.io/rest.js/v20/?utm_source=openai
🌐 Web query:
Octokit github.paginate() usage pagination utility
💡 Result:
octokit.paginate() is Octokit’s REST pagination utility: it follows the response Link headers and returns one flattened array containing items from all pages. It also exposes octokit.paginate.iterator() for page-by-page streaming (more memory-efficient). [1][2]
Typical usage (Octokit.js)
1) Get all items as one array
import { Octokit } from "octokit";
const octokit = new Octokit({ auth: process.env.GITHUB_TOKEN });
const issues = await octokit.paginate("GET /repos/{owner}/{repo}/issues", {
owner: "octocat",
repo: "Spoon-Knife",
per_page: 100,
});[1]
You can also pass an endpoint method instead of a route string:
const issues = await octokit.paginate(octokit.rest.issues.listForRepo, {
owner: "octocat",
repo: "hello-world",
per_page: 100,
});[2]
2) Iterate page-by-page (async iterator)
const iterator = octokit.paginate.iterator(octokit.rest.issues.listForRepo, {
owner: "octocat",
repo: "hello-world",
per_page: 100,
});
for await (const { data: issues } of iterator) {
for (const issue of issues) console.log(issue.number, issue.title);
}[2]
3) Optional “map” callback (transform / early-stop)
GitHub’s docs note you can pass an optional map function to transform results and/or stop early (and paginate.iterator() if you don’t want to fetch everything at once). [1]
If you’re composing Octokit manually
Pagination comes from @octokit/plugin-paginate-rest (it adds .paginate() / .paginate.iterator()), e.g.:
import { Octokit } from "@octokit/core";
import { paginateRest } from "@octokit/plugin-paginate-rest";
const MyOctokit = Octokit.plugin(paginateRest);
const octokit = new MyOctokit({ auth: "secret123" });
const issues = await octokit.paginate("GET /repos/{owner}/{repo}/issues", {
owner: "octocat",
repo: "hello-world",
per_page: 100,
});[3]
Sources: GitHub REST pagination docs [1], Octokit.js README [2], @octokit/plugin-paginate-rest README [3].
Paginate the PR file list before computing reviewer roles.
Lines 96-99 only inspect the first page from pulls.listFiles. GitHub's REST API defaults to 30 items per page, so PRs with more than 30 changed files miss the remaining files. This causes the workflow to undercompute required roles and can authorize /lgtm from the wrong team.
Suggested fix
- const filesResponse = await github.rest.pulls.listFiles({
- owner, repo, pull_number: prNumber
- });
- const changedFiles = filesResponse.data.map(f => f.filename);
+ const files = await github.paginate(github.rest.pulls.listFiles, {
+ owner,
+ repo,
+ pull_number: prNumber,
+ per_page: 100
+ });
+ const changedFiles = files.map(file => file.filename);📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const filesResponse = await github.rest.pulls.listFiles({ | |
| owner, repo, pull_number: prNumber | |
| }); | |
| const changedFiles = filesResponse.data.map(f => f.filename); | |
| const files = await github.paginate(github.rest.pulls.listFiles, { | |
| owner, | |
| repo, | |
| pull_number: prNumber, | |
| per_page: 100 | |
| }); | |
| const changedFiles = files.map(file => file.filename); |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.github/scripts/lgtm-processor.js around lines 96 - 99, The current call to
github.rest.pulls.listFiles only fetches one page, so changedFiles misses files
when a PR has >30 files; replace the single-page fetch with a paginated fetch
(e.g. use github.paginate or an explicit loop) to retrieve all files for the
given owner, repo and prNumber, then compute changedFiles by mapping filenames
across the full paginated result; update references around
filesResponse/changedFiles to use the full list returned by
github.paginate(github.rest.pulls.listFiles, { owner, repo, pull_number:
prNumber }).
| codeownerMappings.forEach(mapping => { | ||
| const { pattern, roles } = mapping; | ||
| // Match pattern (handle both exact matches and directory patterns) | ||
| // This handles hierarchical matching where broader patterns can cover more specific paths | ||
| if (file === pattern || | ||
| file.startsWith(pattern.endsWith('/') ? pattern : pattern + '/')) { | ||
| roles.forEach(role => requiredReviewerRoles.add(role)); | ||
| hasSpecificOwner = true; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, let's check if the file exists and read the relevant lines
cat -n .github/scripts/lgtm-processor.js | sed -n '100,120p'Repository: external-secrets/external-secrets
Length of output: 1087
🏁 Script executed:
# Look for Biome configuration files
find . -name "biome.json" -o -name "biome.jsonc" -o -name ".biomeignore" | head -20Repository: external-secrets/external-secrets
Length of output: 89
🏁 Script executed:
# Check for Biome configuration and rules
rg "useIterableCallbackReturn" -t json -t jsRepository: external-secrets/external-secrets
Length of output: 59
🏁 Script executed:
cat ./biome.jsonRepository: external-secrets/external-secrets
Length of output: 1851
🏁 Script executed:
web_search
Biome useIterableCallbackReturn rule documentationRepository: external-secrets/external-secrets
Length of output: 171
🌐 Web query:
Biome useIterableCallbackReturn rule what does it check
💡 Result:
Biome’s lint/suspicious/useIterableCallbackReturn rule enforces consistent return behavior inside callbacks passed to common iterable/array methods: for methods whose callback result is used, the callback should always return a value (e.g. map, filter, find, reduce, some, every, sort, etc.). It also flags the opposite case for forEach: returning a value from a forEach callback is disallowed (because the return value is ignored). Async and generator callbacks are ignored. [1]
Optionally, since Biome v2.4.0, you can set checkForEach: false to skip checking forEach callbacks for returned values. [1] [2]
Line 114 violates Biome's useIterableCallbackReturn rule.
The arrow function callback implicitly returns the Set from .add(), but forEach callbacks should not return values. Convert to a block body:
Suggested fix
- roles.forEach(role => requiredReviewerRoles.add(role));
+ roles.forEach(role => {
+ requiredReviewerRoles.add(role);
+ });📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| codeownerMappings.forEach(mapping => { | |
| const { pattern, roles } = mapping; | |
| // Match pattern (handle both exact matches and directory patterns) | |
| // This handles hierarchical matching where broader patterns can cover more specific paths | |
| if (file === pattern || | |
| file.startsWith(pattern.endsWith('/') ? pattern : pattern + '/')) { | |
| roles.forEach(role => requiredReviewerRoles.add(role)); | |
| hasSpecificOwner = true; | |
| codeownerMappings.forEach(mapping => { | |
| const { pattern, roles } = mapping; | |
| // Match pattern (handle both exact matches and directory patterns) | |
| // This handles hierarchical matching where broader patterns can cover more specific paths | |
| if (file === pattern || | |
| file.startsWith(pattern.endsWith('/') ? pattern : pattern + '/')) { | |
| roles.forEach(role => { | |
| requiredReviewerRoles.add(role); | |
| }); | |
| hasSpecificOwner = true; |
🧰 Tools
🪛 Biome (2.4.6)
[error] 114-114: This callback passed to forEach() iterable method should not return a value.
(lint/suspicious/useIterableCallbackReturn)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.github/scripts/lgtm-processor.js around lines 108 - 115, The forEach
callbacks are implicitly returning values (violating useIterableCallbackReturn);
change the concise arrow body that calls roles.forEach(role =>
requiredReviewerRoles.add(role)) to a block-bodied arrow that performs the add
without returning a value — e.g., inside the codeownerMappings.forEach callback
(mapping, pattern, file, hasSpecificOwner) replace roles.forEach(role =>
requiredReviewerRoles.add(role)) with roles.forEach(role => {
requiredReviewerRoles.add(role); }); ensure no return value is produced from the
forEach callbacks and preserve the existing logic that sets hasSpecificOwner
when a pattern matches.
|
Thanks! 🙇 After this, we can improve the existing script. :) It will be much more visible! Thank you! :) |
|
|
@mateenali66 Now that this is merged, will you add the check that prevents it from doing something if the label doesn't exist? :) |
If the lgtm label is missing from the repo, core.setFailed() is called with a descriptive error before any other logic runs. Resolves the follow-up requested by @Skarlso after external-secrets#6074 was merged. Signed-off-by: Mateen Anjum <mateenali66@gmail.com>
…-secrets#6074) Co-authored-by: Gergely Bräutigam <gergely.brautigam@sap.com> Signed-off-by: AlexOQ <30403857+AlexOQ@users.noreply.github.com>
…2.2.0 (#4923) This PR contains the following updates: | Package | Update | Change | |---|---|---| | [external-secrets/external-secrets](https://github.com/external-secrets/external-secrets) | minor | `v2.1.0` → `v2.2.0` | --- >⚠️ **Warning** > > Some dependencies could not be looked up. Check the [Dependency Dashboard](issues/2) for more information. --- ### Release Notes <details> <summary>external-secrets/external-secrets (external-secrets/external-secrets)</summary> ### [`v2.2.0`](https://github.com/external-secrets/external-secrets/releases/tag/v2.2.0) [Compare Source](external-secrets/external-secrets@v2.1.0...v2.2.0) Image: `ghcr.io/external-secrets/external-secrets:v2.2.0` Image: `ghcr.io/external-secrets/external-secrets:v2.2.0-ubi` Image: `ghcr.io/external-secrets/external-secrets:v2.2.0-ubi-boringssl` <!-- Release notes generated using configuration in .github/release.yml at main --> #### What's Changed ##### General - chore: release charts v2.1.0 by [@​Skarlso](https://github.com/Skarlso) in [#​6030](external-secrets/external-secrets#6030) - chore: fix the stability doc by [@​Skarlso](https://github.com/Skarlso) in [#​6035](external-secrets/external-secrets#6035) - fix(security): Fix vulnerabilities by [@​othomann](https://github.com/othomann) in [#​6052](external-secrets/external-secrets#6052) - fix(aws): sync tags and resource policy even when secret value unchanged by [@​evs-secops](https://github.com/evs-secops) in [#​6025](external-secrets/external-secrets#6025) - fix: publish now uses docker build v4 which required some changes by [@​Skarlso](https://github.com/Skarlso) in [#​6062](external-secrets/external-secrets#6062) - feat(gcpsm): auto-detect projectID from GCP metadata server by [@​patjlm](https://github.com/patjlm) in [#​5922](external-secrets/external-secrets#5922) - chore(templating): Remove years in license and their checks by [@​evrardj-roche](https://github.com/evrardj-roche) in [#​5955](external-secrets/external-secrets#5955) - docs: Add Roche to official ADOPTERS by [@​evrardj-roche](https://github.com/evrardj-roche) in [#​6076](external-secrets/external-secrets#6076) - feat: Add Last Sync column to ExternalSecret and PushSecret printers by [@​jaruwat-panturat](https://github.com/jaruwat-panturat) in [#​6068](external-secrets/external-secrets#6068) - fix(onepassword): support native item IDs by [@​chadxz](https://github.com/chadxz) in [#​6073](external-secrets/external-secrets#6073) - feat: extract LGTM processor to external JS file with tests by [@​mateenali66](https://github.com/mateenali66) in [#​6074](external-secrets/external-secrets#6074) - feat: fail fast if LGTM label does not exist in repository by [@​mateenali66](https://github.com/mateenali66) in [#​6078](external-secrets/external-secrets#6078) - feat(passbolt): add support for Passbolt V5 API by [@​cedricherzog-passbolt](https://github.com/cedricherzog-passbolt) in [#​5919](external-secrets/external-secrets#5919) - fix(infisical): dataFrom.find.path should filter by secret path not name by [@​johnvox](https://github.com/johnvox) in [#​6086](external-secrets/external-secrets#6086) - fix: disable the priority queue which misbehaves at scale by [@​Skarlso](https://github.com/Skarlso) in [#​6083](external-secrets/external-secrets#6083) - chore: update go version to 1.26.1 by [@​Skarlso](https://github.com/Skarlso) in [#​6072](external-secrets/external-secrets#6072) - docs(aws): fix PushSecret metadata indentation in resource policy exa... by [@​Br1an67](https://github.com/Br1an67) in [#​6056](external-secrets/external-secrets#6056) - fix(aws): prevent EC2 IMDS fallback when explicit credentials are pro... by [@​Br1an67](https://github.com/Br1an67) in [#​6036](external-secrets/external-secrets#6036) - feat(templating): Add certSANs function to extract SANs from certificates by [@​mzdeb](https://github.com/mzdeb) in [#​6058](external-secrets/external-secrets#6058) - docs: document template.metadata labels/annotations behavior by [@​lucpas](https://github.com/lucpas) in [#​6102](external-secrets/external-secrets#6102) - fix: CODEOWNERS are seriously out of date by [@​Skarlso](https://github.com/Skarlso) in [#​6106](external-secrets/external-secrets#6106) - feat(helm): add readinessProbe support for external-secrets deployment by [@​AlexOQ](https://github.com/AlexOQ) in [#​5831](external-secrets/external-secrets#5831) - fix: update grpc for CVE-2026-33186 by [@​Skarlso](https://github.com/Skarlso) in [#​6108](external-secrets/external-secrets#6108) - feat(azurekv): add expiration time to azure kv secret by [@​muraliavarma](https://github.com/muraliavarma) in [#​5935](external-secrets/external-secrets#5935) - feat: add path to cloud.ru provider by [@​heavyandrew](https://github.com/heavyandrew) in [#​5952](external-secrets/external-secrets#5952) - fix(add-eso-version): fix separator line pattern in add\_eso\_version.sh script by [@​riccardomc](https://github.com/riccardomc) in [#​6113](external-secrets/external-secrets#6113) ##### Dependencies - chore(deps): bump zizmorcore/zizmor-action from 0.5.0 to 0.5.2 by [@​dependabot](https://github.com/dependabot)\[bot] in [#​6038](external-secrets/external-secrets#6038) - chore(deps): bump charset-normalizer from 3.4.4 to 3.4.5 in /hack/api-docs by [@​dependabot](https://github.com/dependabot)\[bot] in [#​6047](external-secrets/external-secrets#6047) - chore(deps): bump platformdirs from 4.9.2 to 4.9.4 in /hack/api-docs by [@​dependabot](https://github.com/dependabot)\[bot] in [#​6050](external-secrets/external-secrets#6050) - chore(deps): bump mkdocs-material from 9.7.3 to 9.7.4 in /hack/api-docs by [@​dependabot](https://github.com/dependabot)\[bot] in [#​6049](external-secrets/external-secrets#6049) - chore(deps): bump github/codeql-action from 4.32.4 to 4.32.6 by [@​dependabot](https://github.com/dependabot)\[bot] in [#​6039](external-secrets/external-secrets#6039) - chore(deps): bump step-security/harden-runner from 2.15.0 to 2.15.1 by [@​dependabot](https://github.com/dependabot)\[bot] in [#​6043](external-secrets/external-secrets#6043) - chore(deps): bump actions/dependency-review-action from 4.8.3 to 4.9.0 by [@​dependabot](https://github.com/dependabot)\[bot] in [#​6040](external-secrets/external-secrets#6040) - chore(deps): bump crazy-max/ghaction-import-gpg from 6.3.0 to 7.0.0 by [@​dependabot](https://github.com/dependabot)\[bot] in [#​6044](external-secrets/external-secrets#6044) - chore(deps): bump docker/login-action from 3.7.0 to 4.0.0 by [@​dependabot](https://github.com/dependabot)\[bot] in [#​6042](external-secrets/external-secrets#6042) - chore(deps): bump docker/setup-buildx-action from 3.12.0 to 4.0.0 by [@​dependabot](https://github.com/dependabot)\[bot] in [#​6041](external-secrets/external-secrets#6041) - chore(deps): bump docker/setup-qemu-action from 3.7.0 to 4.0.0 by [@​dependabot](https://github.com/dependabot)\[bot] in [#​6046](external-secrets/external-secrets#6046) - chore(deps): bump aquasecurity/trivy-action from 0.34.1 to 0.35.0 by [@​dependabot](https://github.com/dependabot)\[bot] in [#​6048](external-secrets/external-secrets#6048) - chore(deps): bump anchore/sbom-action from 0.23.0 to 0.23.1 by [@​dependabot](https://github.com/dependabot)\[bot] in [#​6093](external-secrets/external-secrets#6093) - chore(deps): bump distroless/static from `28efbe9` to `47b2d72` by [@​dependabot](https://github.com/dependabot)\[bot] in [#​6088](external-secrets/external-secrets#6088) - chore(deps): bump ubi9/ubi from `cecb1cd` to `6ed9f6f` by [@​dependabot](https://github.com/dependabot)\[bot] in [#​6087](external-secrets/external-secrets#6087) - chore(deps): bump mkdocs-material from 9.7.4 to 9.7.5 in /hack/api-docs by [@​dependabot](https://github.com/dependabot)\[bot] in [#​6096](external-secrets/external-secrets#6096) - chore(deps): bump tornado from 6.5.4 to 6.5.5 in /hack/api-docs by [@​dependabot](https://github.com/dependabot)\[bot] in [#​6094](external-secrets/external-secrets#6094) - chore(deps): bump charset-normalizer from 3.4.5 to 3.4.6 in /hack/api-docs by [@​dependabot](https://github.com/dependabot)\[bot] in [#​6095](external-secrets/external-secrets#6095) - chore(deps): bump step-security/harden-runner from 2.15.1 to 2.16.0 by [@​dependabot](https://github.com/dependabot)\[bot] in [#​6089](external-secrets/external-secrets#6089) - chore(deps): bump sigstore/cosign-installer from 4.0.0 to 4.1.0 by [@​dependabot](https://github.com/dependabot)\[bot] in [#​6092](external-secrets/external-secrets#6092) - chore(deps): bump softprops/action-gh-release from 2.5.0 to 2.6.1 by [@​dependabot](https://github.com/dependabot)\[bot] in [#​6090](external-secrets/external-secrets#6090) - chore(deps): bump actions/create-github-app-token from 2.2.1 to 3.0.0 by [@​dependabot](https://github.com/dependabot)\[bot] in [#​6091](external-secrets/external-secrets#6091) #### New Contributors - [@​othomann](https://github.com/othomann) made their first contribution in [#​6052](external-secrets/external-secrets#6052) - [@​evs-secops](https://github.com/evs-secops) made their first contribution in [#​6025](external-secrets/external-secrets#6025) - [@​patjlm](https://github.com/patjlm) made their first contribution in [#​5922](external-secrets/external-secrets#5922) - [@​jaruwat-panturat](https://github.com/jaruwat-panturat) made their first contribution in [#​6068](external-secrets/external-secrets#6068) - [@​chadxz](https://github.com/chadxz) made their first contribution in [#​6073](external-secrets/external-secrets#6073) - [@​mateenali66](https://github.com/mateenali66) made their first contribution in [#​6074](external-secrets/external-secrets#6074) - [@​cedricherzog-passbolt](https://github.com/cedricherzog-passbolt) made their first contribution in [#​5919](external-secrets/external-secrets#5919) - [@​johnvox](https://github.com/johnvox) made their first contribution in [#​6086](external-secrets/external-secrets#6086) - [@​Br1an67](https://github.com/Br1an67) made their first contribution in [#​6056](external-secrets/external-secrets#6056) - [@​mzdeb](https://github.com/mzdeb) made their first contribution in [#​6058](external-secrets/external-secrets#6058) - [@​lucpas](https://github.com/lucpas) made their first contribution in [#​6102](external-secrets/external-secrets#6102) - [@​AlexOQ](https://github.com/AlexOQ) made their first contribution in [#​5831](external-secrets/external-secrets#5831) - [@​muraliavarma](https://github.com/muraliavarma) made their first contribution in [#​5935](external-secrets/external-secrets#5935) - [@​heavyandrew](https://github.com/heavyandrew) made their first contribution in [#​5952](external-secrets/external-secrets#5952) **Full Changelog**: <external-secrets/external-secrets@v2.1.0...v2.2.0> </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My41OS4yIiwidXBkYXRlZEluVmVyIjoiNDMuNTkuMiIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiaW1hZ2UiXX0=--> Reviewed-on: https://gitea.alexlebens.dev/alexlebens/infrastructure/pulls/4923 Co-authored-by: Renovate Bot <renovate-bot@alexlebens.net> Co-committed-by: Renovate Bot <renovate-bot@alexlebens.net>
This PR contains the following updates: | Package | Update | Change | |---|---|---| | [external-secrets](https://github.com/external-secrets/external-secrets) | minor | `2.1.0` → `2.2.0` | --- >⚠️ **Warning** > > Some dependencies could not be looked up. Check the [Dependency Dashboard](issues/2) for more information. --- ### Release Notes <details> <summary>external-secrets/external-secrets (external-secrets)</summary> ### [`v2.2.0`](https://github.com/external-secrets/external-secrets/releases/tag/v2.2.0) [Compare Source](external-secrets/external-secrets@v2.1.0...v2.2.0) Image: `ghcr.io/external-secrets/external-secrets:v2.2.0` Image: `ghcr.io/external-secrets/external-secrets:v2.2.0-ubi` Image: `ghcr.io/external-secrets/external-secrets:v2.2.0-ubi-boringssl` <!-- Release notes generated using configuration in .github/release.yml at main --> ##### What's Changed ##### General - chore: release charts v2.1.0 by [@​Skarlso](https://github.com/Skarlso) in [#​6030](external-secrets/external-secrets#6030) - chore: fix the stability doc by [@​Skarlso](https://github.com/Skarlso) in [#​6035](external-secrets/external-secrets#6035) - fix(security): Fix vulnerabilities by [@​othomann](https://github.com/othomann) in [#​6052](external-secrets/external-secrets#6052) - fix(aws): sync tags and resource policy even when secret value unchanged by [@​evs-secops](https://github.com/evs-secops) in [#​6025](external-secrets/external-secrets#6025) - fix: publish now uses docker build v4 which required some changes by [@​Skarlso](https://github.com/Skarlso) in [#​6062](external-secrets/external-secrets#6062) - feat(gcpsm): auto-detect projectID from GCP metadata server by [@​patjlm](https://github.com/patjlm) in [#​5922](external-secrets/external-secrets#5922) - chore(templating): Remove years in license and their checks by [@​evrardj-roche](https://github.com/evrardj-roche) in [#​5955](external-secrets/external-secrets#5955) - docs: Add Roche to official ADOPTERS by [@​evrardj-roche](https://github.com/evrardj-roche) in [#​6076](external-secrets/external-secrets#6076) - feat: Add Last Sync column to ExternalSecret and PushSecret printers by [@​jaruwat-panturat](https://github.com/jaruwat-panturat) in [#​6068](external-secrets/external-secrets#6068) - fix(onepassword): support native item IDs by [@​chadxz](https://github.com/chadxz) in [#​6073](external-secrets/external-secrets#6073) - feat: extract LGTM processor to external JS file with tests by [@​mateenali66](https://github.com/mateenali66) in [#​6074](external-secrets/external-secrets#6074) - feat: fail fast if LGTM label does not exist in repository by [@​mateenali66](https://github.com/mateenali66) in [#​6078](external-secrets/external-secrets#6078) - feat(passbolt): add support for Passbolt V5 API by [@​cedricherzog-passbolt](https://github.com/cedricherzog-passbolt) in [#​5919](external-secrets/external-secrets#5919) - fix(infisical): dataFrom.find.path should filter by secret path not name by [@​johnvox](https://github.com/johnvox) in [#​6086](external-secrets/external-secrets#6086) - fix: disable the priority queue which misbehaves at scale by [@​Skarlso](https://github.com/Skarlso) in [#​6083](external-secrets/external-secrets#6083) - chore: update go version to 1.26.1 by [@​Skarlso](https://github.com/Skarlso) in [#​6072](external-secrets/external-secrets#6072) - docs(aws): fix PushSecret metadata indentation in resource policy exa... by [@​Br1an67](https://github.com/Br1an67) in [#​6056](external-secrets/external-secrets#6056) - fix(aws): prevent EC2 IMDS fallback when explicit credentials are pro... by [@​Br1an67](https://github.com/Br1an67) in [#​6036](external-secrets/external-secrets#6036) - feat(templating): Add certSANs function to extract SANs from certificates by [@​mzdeb](https://github.com/mzdeb) in [#​6058](external-secrets/external-secrets#6058) - docs: document template.metadata labels/annotations behavior by [@​lucpas](https://github.com/lucpas) in [#​6102](external-secrets/external-secrets#6102) - fix: CODEOWNERS are seriously out of date by [@​Skarlso](https://github.com/Skarlso) in [#​6106](external-secrets/external-secrets#6106) - feat(helm): add readinessProbe support for external-secrets deployment by [@​AlexOQ](https://github.com/AlexOQ) in [#​5831](external-secrets/external-secrets#5831) - fix: update grpc for CVE-2026-33186 by [@​Skarlso](https://github.com/Skarlso) in [#​6108](external-secrets/external-secrets#6108) - feat(azurekv): add expiration time to azure kv secret by [@​muraliavarma](https://github.com/muraliavarma) in [#​5935](external-secrets/external-secrets#5935) - feat: add path to cloud.ru provider by [@​heavyandrew](https://github.com/heavyandrew) in [#​5952](external-secrets/external-secrets#5952) - fix(add-eso-version): fix separator line pattern in add\_eso\_version.sh script by [@​riccardomc](https://github.com/riccardomc) in [#​6113](external-secrets/external-secrets#6113) ##### Dependencies - chore(deps): bump zizmorcore/zizmor-action from 0.5.0 to 0.5.2 by [@​dependabot](https://github.com/dependabot)\[bot] in [#​6038](external-secrets/external-secrets#6038) - chore(deps): bump charset-normalizer from 3.4.4 to 3.4.5 in /hack/api-docs by [@​dependabot](https://github.com/dependabot)\[bot] in [#​6047](external-secrets/external-secrets#6047) - chore(deps): bump platformdirs from 4.9.2 to 4.9.4 in /hack/api-docs by [@​dependabot](https://github.com/dependabot)\[bot] in [#​6050](external-secrets/external-secrets#6050) - chore(deps): bump mkdocs-material from 9.7.3 to 9.7.4 in /hack/api-docs by [@​dependabot](https://github.com/dependabot)\[bot] in [#​6049](external-secrets/external-secrets#6049) - chore(deps): bump github/codeql-action from 4.32.4 to 4.32.6 by [@​dependabot](https://github.com/dependabot)\[bot] in [#​6039](external-secrets/external-secrets#6039) - chore(deps): bump step-security/harden-runner from 2.15.0 to 2.15.1 by [@​dependabot](https://github.com/dependabot)\[bot] in [#​6043](external-secrets/external-secrets#6043) - chore(deps): bump actions/dependency-review-action from 4.8.3 to 4.9.0 by [@​dependabot](https://github.com/dependabot)\[bot] in [#​6040](external-secrets/external-secrets#6040) - chore(deps): bump crazy-max/ghaction-import-gpg from 6.3.0 to 7.0.0 by [@​dependabot](https://github.com/dependabot)\[bot] in [#​6044](external-secrets/external-secrets#6044) - chore(deps): bump docker/login-action from 3.7.0 to 4.0.0 by [@​dependabot](https://github.com/dependabot)\[bot] in [#​6042](external-secrets/external-secrets#6042) - chore(deps): bump docker/setup-buildx-action from 3.12.0 to 4.0.0 by [@​dependabot](https://github.com/dependabot)\[bot] in [#​6041](external-secrets/external-secrets#6041) - chore(deps): bump docker/setup-qemu-action from 3.7.0 to 4.0.0 by [@​dependabot](https://github.com/dependabot)\[bot] in [#​6046](external-secrets/external-secrets#6046) - chore(deps): bump aquasecurity/trivy-action from 0.34.1 to 0.35.0 by [@​dependabot](https://github.com/dependabot)\[bot] in [#​6048](external-secrets/external-secrets#6048) - chore(deps): bump anchore/sbom-action from 0.23.0 to 0.23.1 by [@​dependabot](https://github.com/dependabot)\[bot] in [#​6093](external-secrets/external-secrets#6093) - chore(deps): bump distroless/static from `28efbe9` to `47b2d72` by [@​dependabot](https://github.com/dependabot)\[bot] in [#​6088](external-secrets/external-secrets#6088) - chore(deps): bump ubi9/ubi from `cecb1cd` to `6ed9f6f` by [@​dependabot](https://github.com/dependabot)\[bot] in [#​6087](external-secrets/external-secrets#6087) - chore(deps): bump mkdocs-material from 9.7.4 to 9.7.5 in /hack/api-docs by [@​dependabot](https://github.com/dependabot)\[bot] in [#​6096](external-secrets/external-secrets#6096) - chore(deps): bump tornado from 6.5.4 to 6.5.5 in /hack/api-docs by [@​dependabot](https://github.com/dependabot)\[bot] in [#​6094](external-secrets/external-secrets#6094) - chore(deps): bump charset-normalizer from 3.4.5 to 3.4.6 in /hack/api-docs by [@​dependabot](https://github.com/dependabot)\[bot] in [#​6095](external-secrets/external-secrets#6095) - chore(deps): bump step-security/harden-runner from 2.15.1 to 2.16.0 by [@​dependabot](https://github.com/dependabot)\[bot] in [#​6089](external-secrets/external-secrets#6089) - chore(deps): bump sigstore/cosign-installer from 4.0.0 to 4.1.0 by [@​dependabot](https://github.com/dependabot)\[bot] in [#​6092](external-secrets/external-secrets#6092) - chore(deps): bump softprops/action-gh-release from 2.5.0 to 2.6.1 by [@​dependabot](https://github.com/dependabot)\[bot] in [#​6090](external-secrets/external-secrets#6090) - chore(deps): bump actions/create-github-app-token from 2.2.1 to 3.0.0 by [@​dependabot](https://github.com/dependabot)\[bot] in [#​6091](external-secrets/external-secrets#6091) ##### New Contributors - [@​othomann](https://github.com/othomann) made their first contribution in [#​6052](external-secrets/external-secrets#6052) - [@​evs-secops](https://github.com/evs-secops) made their first contribution in [#​6025](external-secrets/external-secrets#6025) - [@​patjlm](https://github.com/patjlm) made their first contribution in [#​5922](external-secrets/external-secrets#5922) - [@​jaruwat-panturat](https://github.com/jaruwat-panturat) made their first contribution in [#​6068](external-secrets/external-secrets#6068) - [@​chadxz](https://github.com/chadxz) made their first contribution in [#​6073](external-secrets/external-secrets#6073) - [@​mateenali66](https://github.com/mateenali66) made their first contribution in [#​6074](external-secrets/external-secrets#6074) - [@​cedricherzog-passbolt](https://github.com/cedricherzog-passbolt) made their first contribution in [#​5919](external-secrets/external-secrets#5919) - [@​johnvox](https://github.com/johnvox) made their first contribution in [#​6086](external-secrets/external-secrets#6086) - [@​Br1an67](https://github.com/Br1an67) made their first contribution in [#​6056](external-secrets/external-secrets#6056) - [@​mzdeb](https://github.com/mzdeb) made their first contribution in [#​6058](external-secrets/external-secrets#6058) - [@​lucpas](https://github.com/lucpas) made their first contribution in [#​6102](external-secrets/external-secrets#6102) - [@​AlexOQ](https://github.com/AlexOQ) made their first contribution in [#​5831](external-secrets/external-secrets#5831) - [@​muraliavarma](https://github.com/muraliavarma) made their first contribution in [#​5935](external-secrets/external-secrets#5935) - [@​heavyandrew](https://github.com/heavyandrew) made their first contribution in [#​5952](external-secrets/external-secrets#5952) **Full Changelog**: <external-secrets/external-secrets@v2.1.0...v2.2.0> </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My41OS4yIiwidXBkYXRlZEluVmVyIjoiNDMuNTkuMiIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiY2hhcnQiXX0=--> Reviewed-on: https://gitea.alexlebens.dev/alexlebens/infrastructure/pulls/4927 Co-authored-by: Renovate Bot <renovate-bot@alexlebens.net> Co-committed-by: Renovate Bot <renovate-bot@alexlebens.net>
…-secrets#6074) Co-authored-by: Gergely Bräutigam <gergely.brautigam@sap.com>



Summary
Addresses #5500.
Moves the inline JavaScript from the
Process LGTM Commandstep in.github/workflows/lgtm.ymlinto a separate module at.github/scripts/lgtm-processor.js.Behaviour is unchanged — this is a faithful, line-for-line extraction. No logic modifications, no new features.
Changes:
.github/scripts/lgtm-processor.js— the existing inline script, wrapped in an exported async function. Accepts{ core, github, context, fs }as parameters..github/scripts/lgtm-processor-test.js— unit tests for the pure helper logic (CODEOWNERS parsing, file-pattern matching, required-role resolution) using Node.js built-inassert. Run with:node --input-type=module < .github/scripts/lgtm-processor-test.js.github/workflows/lgtm.yml—script:block replaced with a two-line import:Summary
This PR extracts the inline LGTM command processor logic from
.github/workflows/lgtm.ymlinto an external, testable module.Changes:
.github/scripts/lgtm-processor.js– Extracted LGTM processor as a default-exported async function accepting{ core, github, context, fs }. Handles maintainer verification, required role computation based on CODEOWNERS patterns, and approval/blocking logic with detailed confirmation messages..github/scripts/lgtm-processor-test.js– Unit tests for pure helper logic: CODEOWNERS parsing, file-pattern matching, and required-role resolution. Runnable via Node.js..github/workflows/lgtm.yml– Replaces 231-line inline script with 2-line dynamic import and invocation of the external processor.Behavior: Unchanged; faithful extraction with no logic modifications. Closes #5500.