Skip to content

fix: resolve SonarCloud code scanning alerts for pip install security - #479

Merged
shenxianpeng merged 1 commit into
mainfrom
fix/code-scanning-alerts-sonarcloud
Jul 25, 2026
Merged

fix: resolve SonarCloud code scanning alerts for pip install security#479
shenxianpeng merged 1 commit into
mainfrom
fix/code-scanning-alerts-sonarcloud

Conversation

@shenxianpeng

@shenxianpeng shenxianpeng commented Jul 24, 2026

Copy link
Copy Markdown
Member

Summary

Fix all 8 open SonarCloud code scanning alerts (S8541 + S8544) by securing pip install commands in CI workflows.

Changes

pyproject.toml

  • Pin nox to exact version 2026.7.11 in dev optional deps
  • Add new ci optional deps group with pinned twine==6.2.0

.github/workflows/main.yml

  • Add --only-binary :all: to all pip install commands (fixes S8541)
  • Change standalone pip install nox to pip install .[dev] (versions managed by pyproject.toml)

.github/workflows/publish-package.yml

  • Split pip install --upgrade pip twine into two steps
  • Install twine via .[ci] extras (fixes S8544)

Alerts fixed

# File Rule Description
53 main.yml S8544 Locked versions via .[dev]
54 main.yml S8544 Locked versions via .[dev]
55 main.yml S8541 Added --only-binary :all:
56 main.yml S8544 Locked versions via .[dev]
58 main.yml S8544 Locked versions via .[dev]
59 main.yml S8544 Locked versions via .[dev]
60 main.yml S8544 Locked versions via .[dev]
63 publish-package.yml S8544 Locked versions via .[ci]

Why this approach

Version pins are centralized in pyproject.toml instead of hardcoded in workflow YAML. Dependabot (already configured for pip ecosystem) will automatically open PRs to update nox and twine versions.

Summary by CodeRabbit

  • Chores
    • Improved build, testing, documentation, and package publishing workflows by consistently using pre-built dependency packages.
    • Standardized development environment setup across automated checks and documentation builds.
    • Pinned the development automation tool to a specific version for more predictable results.
    • Updated package-building checks to use the same reliable dependency installation approach.

@shenxianpeng
shenxianpeng requested a review from a team as a code owner July 24, 2026 02:38
@netlify

netlify Bot commented Jul 24, 2026

Copy link
Copy Markdown

Deploy Preview for commit-check ready!

Name Link
🔨 Latest commit e646d8a
🔍 Latest deploy log https://app.netlify.com/projects/commit-check/deploys/6a6457af00d3210008781e3c
😎 Deploy Preview https://deploy-preview-479--commit-check.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@github-actions github-actions Bot added the bug Something isn't working label Jul 24, 2026
@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@shenxianpeng, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 36 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 0f029aa1-d5b1-4906-a1f8-77e34bdfe837

📥 Commits

Reviewing files that changed from the base of the PR and between 7d915f7 and e646d8a.

📒 Files selected for processing (3)
  • .github/workflows/main.yml
  • .github/workflows/publish-package.yml
  • pyproject.toml
📝 Walkthrough

Walkthrough

Changes

Dependency installation

Layer / File(s) Summary
Dependency extras contract
.github/workflows/publish-package.yml, pyproject.toml
The development extra pins nox, while package publishing installs the ci extra using binary distributions only.
CI dependency setup
.github/workflows/main.yml
The build, install, and docs jobs upgrade pip and install development dependencies using wheel-only commands.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: hardening CI pip installs to address SonarCloud security alerts.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/code-scanning-alerts-sonarcloud

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Jul 24, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.28%. Comparing base (ae0362e) to head (e646d8a).

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #479   +/-   ##
=======================================
  Coverage   97.28%   97.28%           
=======================================
  Files          12       12           
  Lines        1179     1179           
=======================================
  Hits         1147     1147           
  Misses         32       32           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@codspeed-hq

codspeed-hq Bot commented Jul 24, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 380 untouched benchmarks
⏩ 114 skipped benchmarks1


Comparing fix/code-scanning-alerts-sonarcloud (e646d8a) with main (bd890f1)2

Open in CodSpeed

Footnotes

  1. 114 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

  2. No successful run was found on main (ae0362e) during the generation of this report, so bd890f1 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

- Add --only-binary :all: to all pip install commands in workflows
- Pin nox and twine versions in pyproject.toml as optional deps
- Add new ci optional-dependency group for twine
- Install CI tools via .[dev] and .[ci] extras to centralize version mgmt
- Dependabot will automatically manage version updates in pyproject.toml
@shenxianpeng
shenxianpeng force-pushed the fix/code-scanning-alerts-sonarcloud branch from 7d915f7 to e646d8a Compare July 25, 2026 06:28
@sonarqubecloud

Copy link
Copy Markdown

@shenxianpeng
shenxianpeng merged commit dca495f into main Jul 25, 2026
33 checks passed
@shenxianpeng
shenxianpeng deleted the fix/code-scanning-alerts-sonarcloud branch July 25, 2026 07:10
shenxianpeng added a commit that referenced this pull request Aug 9, 2026
SonarCloud's unpinned-install rule failed the quality gate on a bare
'pip install .'. main.yml and publish-package.yml both carry
--only-binary :all: for exactly this, added in #479; this step was the
one that did not. Verified it still installs a local path: the resulting
version reads 2.13.4.post1.dev4, which is the checkout rather than the
release.
shenxianpeng added a commit that referenced this pull request Aug 9, 2026
I added --only-binary :all: because main.yml and publish-package.yml
carry it and #479 mentions SonarCloud. It does not satisfy this rule --
the alert stayed -- and --upgrade pip added a second flagged line, so
the change took the count from one to two.

Back to one plain line. The remaining alert needs a decision rather than
another flag: main.yml has the identical install and passes only because
it is not new code, so locking would mean a hash-pinned requirements
file or reviving the stale uv.lock.
shenxianpeng added a commit that referenced this pull request Aug 9, 2026
* ci: check this pull request with the commit-check in it

The workflow ran commit-check-action, which installs a released
commit-check -- so every pull request was checked by the version before
it. #540 had its own title rejected by the bug it was fixing, and the
same thing happened tonight in the .github repository. A self-test that
cannot see the change under test is not a self-test, and the action's
version does not track the engine's, so a fix needed two releases and a
bump before it could be reproduced here.

Install from the checkout instead. The cost is job-summary and
pr-comments, which are the action's rendering rather than the engine's
behaviour and are covered by the action's own repository.

Enumerating the commits is not optional. On a pull_request checkout HEAD
is the synthetic merge commit, which the engine skips, so a bare
'commit-check --message' reports a pass having read nothing. Verified on
a scratch repository holding one plainly bad commit: the bare form exits
0, this workflow exits 1. HEAD^1..HEAD^2 gives the real commits, and a
guard fails loudly if HEAD is not a merge so the failure can never be
silence.

The pull request title reaches the CLI through the environment. Titles
are attacker-controlled, and interpolating one into a run: block is a
script injection.

* ci: install with the flags the other workflows already use

SonarCloud's unpinned-install rule failed the quality gate on a bare
'pip install .'. main.yml and publish-package.yml both carry
--only-binary :all: for exactly this, added in #479; this step was the
one that did not. Verified it still installs a local path: the resulting
version reads 2.13.4.post1.dev4, which is the checkout rather than the
release.

* ci: close stdin so the branch and author checks cannot hang

With stdin left open, commit-check waits to read a message even when
only --branch and --author-name were asked for. Reproduced locally: the
process runs until killed, which in CI is a step that hangs rather than
fails.

Closing stdin also decides what the author checks look at, so the
comment says which: the author of HEAD, matching what the action
reports today.

* ci: revert the install flags that did not do what I thought

I added --only-binary :all: because main.yml and publish-package.yml
carry it and #479 mentions SonarCloud. It does not satisfy this rule --
the alert stayed -- and --upgrade pip added a second flagged line, so
the change took the count from one to two.

Back to one plain line. The remaining alert needs a decision rather than
another flag: main.yml has the identical install and passes only because
it is not new code, so locking would mean a hash-pinned requirements
file or reviving the stale uv.lock.

* refactor: move the checks into the nox session that already existed

The session was already there and already wrong: it ran a bare
'commit-check --message', which on a pull_request checkout inspects the
merge commit, which the engine skips. Leaving it that way while putting
a correct copy in YAML would have left two implementations, with the
broken one being the one a contributor reaches for locally.

So the logic lives in noxfile.py and the workflow is one line. The same
command now reproduces a CI failure on a laptop, which was half the
reason for moving off the action.

The session adapts rather than assuming CI: HEAD^1..HEAD^2 when the
checkout is a merge commit, HEAD otherwise, and the title only when
PR_TITLE is set. It still refuses to pass silently -- missing HEAD^2
during a pull_request event is an error, not a fallback.

Verified locally: enumerates 2 of 2 commits on a merge ref and 0 on a
plain one, exits 1 on a bad title having still run the branch and author
checks, exits 0 on a good one, and no longer hangs on stdin.

* refactor: keep the nox session simple, and CI logic in the workflow

Reverts b95acfd, which moved the pull request checks into the nox
session. The session is a developer command -- run commit-check on your
working copy -- and folding CI's shape into it made the simple thing
complicated for no gain.

The justification was wrong too. I claimed the same command would
reproduce a CI failure locally, then had to branch on whether HEAD^2
exists, because locally there is no merge commit and no PR title. A
command that behaves differently in the two places does not reproduce
one from the other.

It also introduced a bug the shell never had: filtering on .strip()
dropped empty messages, which this repository rejects via
allow_empty_commits = false, so such a commit would have been reported
as 'HEAD is not a merge commit' instead of as the thing it is. The shell
keeps them: printf 'a\0\0b\0' through 'read -r -d' yields a, empty, b.

noxfile.py is now byte-identical to main.

* ci: check the title, and stop checking messages that get discarded

main is linear and every subject ends in (#N): this repository squashes,
so the commits on a branch never reach it. The title becomes the subject.
Checking each commit was protecting history that does not exist, and cost
thirty lines of shell to do it.

What is left is two commands. The bare 'commit-check --message' still
cannot be one of them -- it reads HEAD, the synthetic merge commit, which
the engine skips and would pass having read nothing -- so the title goes
in through stdin instead, which sidesteps HEAD entirely and needs no
enumeration.

Contributors lose CI feedback on intermediate commit messages. The
pre-commit hook is where that belongs anyway: it arrives while the
message is being written rather than a round trip later.

Verified on a merge ref: bad title 1, good title 0, good title with a
bad branch name 1.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant