Skip to content

🐛 Remove the eyes reaction when analysis finishes - #609

Merged
AndreiIurko merged 3 commits into
mainfrom
fix/pr-eyes-reaction-not-removed
Jul 31, 2026
Merged

🐛 Remove the eyes reaction when analysis finishes#609
AndreiIurko merged 3 commits into
mainfrom
fix/pr-eyes-reaction-not-removed

Conversation

@ivan-orekhov

Copy link
Copy Markdown
Collaborator

Problem

The action adds an 👀 (eyes) reaction to the PR when analysis starts and a 👍 (+1) reaction when it finishes. The finish step was supposed to remove the 👀, but it didn't — PRs ended up with both 👀 and 👍.

Root cause

putReaction in scan/src/utils.ts removed the old reaction with an unpaginated listForIssue + find(), so:

  • only the first match (≤ first 30 reactions) was ever deleted, and
  • matching was by content only — it could target another user's 👀, get a 403, and never remove the action's own reaction.

Deleting by reaction_id alone is also unsafe: GitHub's delete endpoint documents no own-reaction-only restriction, so a naive "delete every match" would strip other users' reactions too.

Fix

putReaction now:

  1. Creates the new reaction first and reads its author (user.login) from the response — works for both the default GITHUB_TOKEN (github-actions[bot]) and a custom PAT/App token.
  2. Paginates all reactions and deletes only those whose content matches and whose author is that same identity — other users' reactions are left untouched.
  3. Tolerates per-item delete errors so one failure can't block the rest; skips removal entirely if the author can't be determined.

Tests

Adds putReaction unit tests: own-vs-other-user removal (a human's 👀 survives), empty oldReaction, missing author, and the non-PR early return.

scan/dist/index.js regenerated via the pre-commit hook / npm run package.

🤖 Generated with Claude Code

The action added an eyes (👀) reaction on start and a thumbs-up (+1) on
finish, but the removal step failed to strip the eyes, leaving both on the PR.

The old removal used an unpaginated listForIssue and find(), deleting at most
one match — and matched by content only, so it could target another user's
reaction (403) and never remove the action's own.

putReaction now creates the new reaction first to learn its author from the
response (works for the default GITHUB_TOKEN and custom PAT/App tokens alike),
then paginates all reactions and deletes only those with the matching content
AND authored by that same identity. Other users' reactions are left untouched.
Per-item delete errors are tolerated so one failure can't block the rest.

Adds unit tests for putReaction covering own-vs-other-user removal, empty
oldReaction, missing author, and the non-PR early return.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jul 17, 2026

Copy link
Copy Markdown

Qodana for JVM

It seems all right 👌

No new problems were found according to the checks applied

💡 Qodana analysis was run in the pull request mode: only the changed files were checked
☁️ View the detailed Qodana report

Detected 190 dependencies

Third-party software list

This page lists the third-party software dependencies used in qodana

Dependency Version Licenses
@actions/artifact 2.3.2 MIT
@actions/cache 4.1.0 MIT
@actions/core 1.11.1 MIT
@actions/exec 1.1.1 MIT
@actions/github 5.1.1 MIT
@actions/github 6.0.1 MIT
@actions/glob 0.1.2 MIT
@actions/http-client 2.2.1 MIT
@actions/io 1.1.3 MIT
@actions/tool-cache 2.0.2 MIT
@azure/abort-controller 1.1.0 MIT
@azure/abort-controller 2.1.2 MIT
@azure/core-auth 1.7.2 MIT
@azure/core-util 1.9.0 MIT
@azure/ms-rest-js 2.7.0 MIT
@azure/storage-blob 12.17.0 MIT
@fastify/busboy 2.1.1 MIT
@gitbeaker/core 43.8.0 MIT
@gitbeaker/requester-utils 43.8.0 MIT
@gitbeaker/rest 43.8.0 MIT
@isaacs/fs-minipass 4.0.1 ISC
@octokit/auth-token 2.5.0 MIT
@octokit/core 3.6.0 MIT
@octokit/core 5.2.0 MIT
@octokit/core 7.0.6 MIT
@octokit/endpoint 6.0.12 MIT
@octokit/endpoint 9.0.6 MIT
@octokit/graphql 4.8.0 MIT
@octokit/openapi-types 12.11.0 MIT
@octokit/openapi-types 20.0.0 MIT
@octokit/openapi-types 27.0.0 MIT
@octokit/openapi-webhooks-types 12.1.0 MIT
@octokit/plugin-paginate-rest 14.0.0 MIT
@octokit/plugin-paginate-rest 2.21.3 MIT
@octokit/plugin-paginate-rest 9.2.2 MIT
@octokit/plugin-request-log 1.0.4 MIT
@octokit/plugin-request-log 6.0.0 MIT
@octokit/plugin-rest-endpoint-methods 10.4.1 MIT
@octokit/plugin-rest-endpoint-methods 17.0.0 MIT
@octokit/plugin-rest-endpoint-methods 5.16.2 MIT
@octokit/plugin-retry 3.0.9 MIT
@octokit/request-error 2.1.0 MIT
@octokit/request-error 5.1.1 MIT
@octokit/request-error 7.0.0 MIT
@octokit/request 5.6.3 MIT
@octokit/request 8.4.1 MIT
@octokit/rest 22.0.1 MIT
@octokit/types 12.6.0 MIT
@octokit/types 13.10.0 MIT
@octokit/types 14.1.0 MIT
@octokit/types 16.0.0 MIT
@octokit/types 6.41.0 MIT
@octokit/webhooks-methods 6.0.0 MIT
@octokit/webhooks 14.2.0 MIT
@protobuf-ts/plugin-framework 2.9.4 Apache-2.0
BSD-3-Clause
@protobuf-ts/plugin 2.9.4 Apache-2.0
@protobuf-ts/protoc 2.9.4 Apache-2.0
@protobuf-ts/runtime-rpc 2.11.1 Apache-2.0
@protobuf-ts/runtime 2.11.1 Apache-2.0
BSD-3-Clause
@qodana/action 1.0.0 Apache-2.0
@qodana/ci-common 1.0.0 Apache-2.0
@qodana/gitlab 1.0.0 Apache-2.0
@qodana/vsts 1.0.0 Apache-2.0
@types/adm-zip 0.5.7 MIT
@types/node 16.18.126 MIT
@types/node 25.5.2 MIT
@types/sarif 2.1.7 MIT
@types/semver 5.5.0 MIT
@types/uuid 3.4.13 MIT
abort-controller 3.0.0 MIT
adm-zip 0.5.17 MIT
annotations 13.0 Apache-2.0
archiver-utils 5.0.2 MIT
archiver 7.0.1 MIT
argparse 1.0.10 MIT
async 3.2.5 MIT
asynckit 0.4.0 MIT
axios 1.15.2 MIT
azure-devops-node-api 15.1.2 MIT
azure-pipelines-task-lib 5.2.8 MIT
azure-pipelines-tasks-utility-common 3.272.0 MIT
azure-pipelines-tool-lib 2.0.12 MIT
b4a 1.6.6 Apache-2.0
balanced-match 1.0.2 MIT
bare-events 2.2.2 Apache-2.0
before-after-hook 2.2.3 Apache-2.0
binary 0.3.0 MIT
bottleneck 2.19.5 MIT
brace-expansion 2.0.2 MIT
buffer-crc32 1.0.0 MIT
buffers 0.1.1 MIT
call-bind-apply-helpers 1.0.2 MIT
chainsaw 0.1.0 MIT
chownr 3.0.0 BlueOak-1.0.0
combined-stream 1.0.8 MIT
compress-commons 6.0.2 MIT
core-util-is 1.0.3 MIT
crc-32 1.2.2 Apache-2.0
crc32-stream 6.0.0 MIT
delayed-stream 1.0.0 MIT
deprecation 2.3.1 ISC
des.js 1.1.0 MIT
dunder-proto 1.0.1 MIT
es-define-property 1.0.1 MIT
es-errors 1.3.0 MIT
es-object-atoms 1.1.1 MIT
es-set-tostringtag 2.1.0 MIT
esprima 4.0.1 BSD-2-Clause
event-target-shim 5.0.1 MIT
fast-fifo 1.3.2 MIT
follow-redirects 1.15.11 MIT
form-data 2.5.1 MIT
form-data 4.0.5 MIT
function-bind 1.1.2 MIT
get-intrinsic 1.3.0 MIT
get-proto 1.0.1 MIT
gopd 1.2.0 MIT
has-symbols 1.1.0 MIT
has-tostringtag 1.0.2 MIT
hasown 2.0.2 MIT
immediate 3.0.6 MIT
inherits 2.0.4 ISC
is-plain-object 5.0.0 MIT
is-stream 2.0.1 MIT
isarray 1.0.0 MIT
js-md4 0.3.2 MIT
js-yaml 3.14.2 MIT
jszip 3.10.1 GPL-3.0-or-later
MIT
jwt-decode 3.1.2 MIT
kotlin-reflect 1.9.20 Apache-2.0
kotlin-stdlib 1.9.20 Apache-2.0
lie 3.3.0 MIT
math-intrinsics 1.1.0 MIT
mime-db 1.52.0 MIT
mime-types 2.1.35 MIT
minimatch 3.1.5 ISC
minimatch 5.1.6 ISC
minimist 1.2.8 MIT
minipass 7.1.2 ISC
minizlib 3.1.0 MIT
mkdirp 0.5.6 MIT
node-fetch 2.7.0 MIT
normalize-path 3.0.0 MIT
once 1.4.0 ISC
pako 1.0.11 MIT
Zlib
picomatch-browser 2.2.6 MIT
process-nextick-args 2.0.1 MIT
proxy-from-env 2.1.0 MIT
qs 6.15.0 BSD-3-Clause
queue-tick 1.0.1 MIT
rate-limiter-flexible 8.3.0 ISC
readable-stream 2.3.8 MIT
readable-stream 4.5.2 MIT
readdir-glob 1.1.3 Apache-2.0
safe-buffer 5.1.2 MIT
sax 1.3.0 ISC
semver-compare 1.0.0 MIT
semver 5.7.2 ISC
semver 6.3.1 ISC
setimmediate 1.0.5 MIT
shell-quote 1.8.3 MIT
sprintf-js 1.0.3 BSD-3-Clause
streamx 2.16.1 MIT
string_decoder 1.1.1 MIT
tar-stream 3.1.7 MIT
tar 7.5.13 BlueOak-1.0.0
tr46 0.0.3 MIT
traverse 0.3.9 MIT
tslib 1.14.1 0BSD
tslib 2.8.1 0BSD
tunnel 0.0.6 MIT
typed-rest-client 1.8.11 MIT
typed-rest-client 2.1.0 MIT
typed-rest-client 2.2.0 MIT
typescript 3.9.10 Apache-2.0
underscore 1.13.6 MIT
undici-types 7.18.2 MIT
undici 5.29.0 MIT
universal-user-agent 6.0.1 ISC
unzip-stream 0.3.4 MIT
util-deprecate 1.0.2 MIT
uuid 3.4.0 MIT
uuid 8.3.2 MIT
webidl-conversions 3.0.1 BSD-2-Clause
whatwg-url 5.0.0 MIT
xcase 2.0.1 MIT
xml2js 0.5.0 MIT
xmlbuilder 11.0.1 MIT
yallist 5.0.0 BlueOak-1.0.0
zip-stream 6.0.1 MIT
Contact Qodana team

Contact us at qodana-support@jetbrains.com

Test files (*.test.ts) are excluded from every tsconfig include and from the
composite build, so editors opened them in an inferred project with default
compiler options and failed to resolve types (jest globals, imports).

This test-only project (noEmit, composite: false) includes src + __tests__ so
IDEs type-check the tests properly. It is not part of `tsc -b`, ESLint, or the
dist bundle, so build/lint/CI are unaffected.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Comment thread scan/tsconfig.spec.json Outdated
Comment thread scan/src/utils.ts
Comment thread scan/__tests__/utils.test.ts Outdated
Comment thread scan/__tests__/utils.test.ts Outdated
Comment thread scan/__tests__/utils.test.ts Outdated
@AndreiIurko
AndreiIurko merged commit 7ce8bde into main Jul 31, 2026
78 checks passed
@AndreiIurko
AndreiIurko deleted the fix/pr-eyes-reaction-not-removed branch July 31, 2026 07:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants