Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,13 @@ updates:
# package it installs. Those move together - a semgrep release raises the
# floor of what it needs - and one pull request per package would leave
# each of them red against the others' old pins.
#
# Grouping alone was not enough. Dependabot raised every line of the list on
# its own, past what semgrep allows, and pip refused the set (#184: boltons
# 26.2.0 against semgrep's boltons~=21.0). Since 2026-10-15 the list is
# compiled from requirements-semgrep.in by pip-compile, and an .in file in
# the directory makes Dependabot run pip-compile itself, so what it proposes
# is a set pip resolved. How to compile it by hand is written in the .in file.
- package-ecosystem: pip
directory: "/.github"
schedule:
Expand Down
46 changes: 46 additions & 0 deletions .github/requirements-semgrep.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# The scanner CI runs, pinned, in a file a bot can edit.
#
# It lived as `pip install semgrep==X` inside a workflow step until 2026-09-02,
# and that is a place nothing watches. Dependabot reads go.mod for Go modules
# and `uses:` for actions, and it does not read shell commands - measured on
# this repository, thirty pull requests, none of them about a pinned tool. The
# cost of that was paid on 2026-09-01: staticcheck sat on a version that could
# not read Go 1.27 at all, and nobody had missed a warning, because there was
# never going to be one.
#
# A requirements file is an ecosystem Dependabot does read, so a new semgrep
# release now arrives as a pull request against THIS file. It can, because this
# file is not a workflow: a token cannot push changes under .github/workflows,
# which is why the three Go tools next door still cannot be handled this way.
# Written up as O170.
#
# Pinned rather than floating for the reason the workflow gives: an unpinned
# analyser turns somebody else's release into a red build on a commit that
# changed nothing.
#
# Licence read from the pinned version rather than recalled, on 2026-08-27:
# LGPL-2.1-or-later, stated by the wheel metadata as a License-Expression and
# carried in full beside it. Read again for 1.180.0 on 2026-10-14, the same.
# It analyses the tree and is never linked into either binary.
#
# This is the one line a person writes. requirements-semgrep.txt next to it is
# every package that line installs, pinned, and it is compiled from this file
# by pip-compile rather than written by hand. With the one line alone the
# vulnerability scanner has to guess what pip would pick, and it guessed wrong:
# measured 2026-10-14, a scan of "semgrep==1.180.0" reported eleven advisories
# against versions pip on Python 3.14 never installs.
#
# Compiled rather than frozen since 2026-10-15. The list was `pip freeze` of a
# clean install, and Dependabot raised each of its lines on its own - pull
# request #184 moved 21 of them, boltons to 26.2.0 among them, while semgrep
# 1.180.0 asks for boltons~=21.0, and pip refused the whole set. When an .in
# file is present Dependabot runs pip-compile itself, so what it proposes is a
# set pip can install. Compiled that day, the list came out the same 66
# versions the freeze had, which is also why #184 had nothing to give: every
# one of its 21 versions is outside what semgrep allows.
#
# To compile it by hand, from the root of the repository, with the Python the
# job uses and the pip-tools Dependabot runs:
#
# docker run --rm -v "$PWD/.github:/w" -w /w python:3.14-slim sh -c "pip install -q pip==26.1.1 pip-tools==7.5.3 && pip-compile --strip-extras --no-emit-index-url --output-file=requirements-semgrep.txt requirements-semgrep.in"
semgrep==1.180.0
189 changes: 150 additions & 39 deletions .github/requirements-semgrep.txt
Original file line number Diff line number Diff line change
@@ -1,101 +1,212 @@
# The scanner CI runs, pinned, in a file a bot can edit.
#
# It lived as `pip install semgrep==X` inside a workflow step until 2026-09-02,
# and that is a place nothing watches. Dependabot reads go.mod for Go modules
# and `uses:` for actions, and it does not read shell commands - measured on
# this repository, thirty pull requests, none of them about a pinned tool. The
# cost of that was paid on 2026-09-01: staticcheck sat on a version that could
# not read Go 1.27 at all, and nobody had missed a warning, because there was
# never going to be one.
# This file is autogenerated by pip-compile with Python 3.14
# by the following command:
#
# A requirements file is an ecosystem Dependabot does read, so a new semgrep
# release now arrives as a pull request against THIS file. It can, because this
# file is not a workflow: a token cannot push changes under .github/workflows,
# which is why the three Go tools next door still cannot be handled this way.
# Written up as O170.
# pip-compile --no-emit-index-url --no-index --output-file=requirements-semgrep.txt --strip-extras requirements-semgrep.in
#
# Pinned rather than floating for the reason the workflow gives: an unpinned
# analyser turns somebody else's release into a red build on a commit that
# changed nothing.
#
# Licence read from the pinned version rather than recalled, on 2026-08-27:
# LGPL-2.1-or-later, stated by the wheel metadata as a License-Expression and
# carried in full beside it. Read again for 1.180.0 on 2026-10-14, the same.
# It analyses the tree and is never linked into either binary.
#
# Every package it installs is pinned below, not only semgrep, since
# 2026-10-14. With the one line alone the vulnerability scanner has to guess
# what pip would pick, and it guessed wrong: measured that day, a scan of
# "semgrep==1.180.0" reported eleven advisories against python-multipart
# 0.0.9, anyio 4.9.0 and idna 3.9.0, while pip on Python 3.14 installed
# 0.0.32, 4.15.1 and 3.20, and a scan of what it really installed found
# nothing. The list is `pip freeze` of a clean install on Linux with the
# Python the job uses, which is the only place it is installed. Dependabot
# reads every line, and carries them in one pull request - see the group in
# dependabot.yml.
annotated-types==0.8.0
# via pydantic
anyio==4.15.1
# via
# httpx
# mcp
# sse-starlette
# starlette
attrs==26.1.0
# via
# glom
# jsonschema
# referencing
# semgrep
boltons==21.0.0
# via
# face
# glom
# semgrep
bracex==3.1
# via wcmatch
certifi==2026.7.22
# via
# httpcore
# httpx
# requests
cffi==2.1.1
# via cryptography
charset-normalizer==3.5.2
# via requests
click==8.4.2
# via
# click-option-group
# semgrep
# uvicorn
click-option-group==0.5.9
# via semgrep
colorama==0.4.6
# via semgrep
cryptography==50.0.2
# via pyjwt
exceptiongroup==1.2.2
# via semgrep
face==26.0.1
# via glom
glom==25.12.0
# via semgrep
googleapis-common-protos==1.75.5
# via opentelemetry-exporter-otlp-proto-http
h11==0.16.0
# via
# httpcore
# uvicorn
httpcore==1.0.9
# via httpx
httpx==0.28.1
# via mcp
httpx-sse==0.4.3
# via mcp
idna==3.20
importlib_metadata==8.7.1
# via
# anyio
# httpx
# requests
importlib-metadata==8.7.1
# via opentelemetry-api
jsonschema==4.25.1
# via
# mcp
# semgrep
jsonschema-specifications==2025.9.1
# via jsonschema
markdown-it-py==4.2.0
# via rich
mcp==1.29.0
# via semgrep
mdurl==0.1.2
# via markdown-it-py
opentelemetry-api==1.37.0
# via
# opentelemetry-exporter-otlp-proto-http
# opentelemetry-instrumentation
# opentelemetry-instrumentation-requests
# opentelemetry-instrumentation-threading
# opentelemetry-sdk
# opentelemetry-semantic-conventions
# semgrep
opentelemetry-exporter-otlp-proto-common==1.37.0
# via opentelemetry-exporter-otlp-proto-http
opentelemetry-exporter-otlp-proto-http==1.37.0
# via semgrep
opentelemetry-instrumentation==0.58b0
# via
# opentelemetry-instrumentation-requests
# opentelemetry-instrumentation-threading
opentelemetry-instrumentation-requests==0.58b0
# via semgrep
opentelemetry-instrumentation-threading==0.58b0
# via semgrep
opentelemetry-proto==1.37.0
# via
# opentelemetry-exporter-otlp-proto-common
# opentelemetry-exporter-otlp-proto-http
opentelemetry-sdk==1.37.0
# via
# opentelemetry-exporter-otlp-proto-http
# semgrep
opentelemetry-semantic-conventions==0.58b0
# via
# opentelemetry-instrumentation
# opentelemetry-instrumentation-requests
# opentelemetry-sdk
opentelemetry-util-http==0.58b0
# via opentelemetry-instrumentation-requests
packaging==26.3
# via
# opentelemetry-instrumentation
# semgrep
peewee==3.19.0
# via semgrep
protobuf==6.33.6
# via
# googleapis-common-protos
# opentelemetry-proto
pycparser==3.11
# via cffi
pydantic==2.14.1
# via
# mcp
# pydantic-settings
pydantic-core==2.50.1
# via pydantic
pydantic-settings==2.16.0
pydantic_core==2.50.1
Pygments==2.21.0
PyJWT==2.15.1
# via mcp
pygments==2.21.0
# via rich
pyjwt==2.15.1
# via
# mcp
# semgrep
python-dotenv==1.2.4
# via pydantic-settings
python-multipart==0.0.32
# via mcp
referencing==0.37.0
# via
# jsonschema
# jsonschema-specifications
requests==2.34.2
# via
# opentelemetry-exporter-otlp-proto-http
# semgrep
rich==15.0.0
# via semgrep
rpds-py==2026.9.1
ruamel.yaml==0.19.1
ruamel.yaml.clib==0.2.15
# via
# jsonschema
# referencing
ruamel-yaml==0.19.1
# via semgrep
ruamel-yaml-clib==0.2.15
# via semgrep
semantic-version==2.10.0
# via semgrep
semgrep==1.180.0
# via -r requirements-semgrep.in
sse-starlette==3.5.0
# via mcp
starlette==1.8.0
# via
# mcp
# sse-starlette
tomli==2.4.1
# via semgrep
typing-extensions==4.16.0
# via
# anyio
# mcp
# opentelemetry-api
# opentelemetry-exporter-otlp-proto-http
# opentelemetry-sdk
# opentelemetry-semantic-conventions
# pydantic
# pydantic-core
# pydantic-settings
# semgrep
# typing-inspection
typing-inspection==0.4.4
typing_extensions==4.16.0
# via
# mcp
# pydantic
# pydantic-settings
urllib3==2.8.0
# via
# requests
# semgrep
uvicorn==0.54.0
# via mcp
wcmatch==8.5.2
# via semgrep
wrapt==1.17.3
# via
# opentelemetry-instrumentation
# opentelemetry-instrumentation-threading
zipp==4.1.1
# via importlib-metadata
Loading