Skip to content
Closed
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
14 changes: 0 additions & 14 deletions .buildscripts/e2e.sh

This file was deleted.

5 changes: 5 additions & 0 deletions .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[bumpversion]
current_version = 1.0.0
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)
serialize =
{major}.{minor}.{patch}
110 changes: 0 additions & 110 deletions .circleci/config.yml

This file was deleted.

10 changes: 10 additions & 0 deletions .cursor/BUGBOT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Bugbot Review Rules

## Core Principle: Comprehensive First-Pass Reviews

**CRITICAL INSTRUCTION**: You must perform a complete, exhaustive analysis on the FIRST review of any changeset. Do NOT hold back observations or defer issues to later reviews. All feedback must be provided upfront.

## Expected Behavior

Your first review should be comprehensive enough that subsequent reviews only need to address newly changed code. The goal is to eliminate "surprise" feedback on code that was part of the initial changeset but somehow escaped earlier review.

16 changes: 9 additions & 7 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
version: 2
updates:
- package-ecosystem: pip
directory: "/"
schedule:
interval: daily
open-pull-requests-limit: 10
reviewers:
- heitorsampaio
- package-ecosystem: github-actions
directory: "/"
schedule:
interval: weekly

- package-ecosystem: pip
directory: "/"
schedule:
interval: weekly
34 changes: 34 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Build

on:
push:
branches:
- main
pull_request:
workflow_dispatch:

permissions:
contents: read

jobs:
package:
name: Build distribution
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.14"
cache: pip
cache-dependency-path: pyproject.toml
- name: Install build tools
run: |
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"
- name: Build and verify package
run: |
python -m build
python -m twine check dist/*
35 changes: 35 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: Lint

on:
push:
branches:
- main
pull_request:
workflow_dispatch:

permissions:
contents: read

jobs:
lint:
name: Lint

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0

- uses: actions/setup-python@v6
with:
python-version: "3.14"
cache: 'pip'
cache-dependency-path: pyproject.toml

- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"
- name: Run lint
run: make lint-ci
37 changes: 37 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: Publish to PyPI

on:
release:
types: [published]

permissions:
contents: read
id-token: write

jobs:
publish:
name: Build and publish
runs-on: ubuntu-latest
environment: pypi
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0

- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.14"
cache: pip
cache-dependency-path: pyproject.toml

- name: Install build tools
run: |
python -m pip install --upgrade pip
python -m pip install build

- name: Build package
run: python -m build

- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Semgrep identified an issue in your code:

GitHub Actions workflow uses a mutable version tag instead of a pinned commit SHA, allowing action maintainers (or attackers who compromise them) to inject malicious code that runs with your credentials.

More details about this

The workflow uses pypa/gh-action-pypi-publish@release/v1, which pins the action to a version tag rather than a full commit SHA. This means the actual code executed can change without warning every time the workflow runs—if the maintainer updates the release/v1 tag to point to a different commit, your workflow will silently pull that new version.

Here's how an attacker could exploit this:

  1. Compromise the pypa/gh-action-pypi-publish repository by gaining access to the maintainer's account or through a supply-chain attack.
  2. Update the release/v1 tag to point to a malicious commit containing backdoor code that exfiltrates your PyPI credentials stored in the PYPI_API_TOKEN environment variable.
  3. Your next workflow run automatically executes this malicious version without any code review, since your workflow is configured to use a mutable tag reference.
  4. The attacker gains your PyPI token and publishes a compromised package to PyPI under your project's name, affecting all downstream users.

By pinning to a specific commit SHA (e.g., @a1d2e3f...), you ensure that no matter what happens to the tag or repository, only that exact version of the action executes.

To resolve this comment:

✨ Commit fix suggestion

Suggested change
uses: pypa/gh-action-pypi-publish@release/v1
uses: pypa/gh-action-pypi-publish@9b7d5b2c6f4e8a1d3c0f7e6b5a4d3c2b1a0f9e8d # release/v1
View step-by-step instructions
  1. Replace the third-party action reference with a full 40-character commit SHA instead of the mutable tag @release/v1.
  2. Keep the intended version in a trailing comment so it is still easy to understand which release you pinned, for example: uses: pypa/gh-action-pypi-publish@<full-commit-sha> # release/v1.
  3. Resolve the SHA from the action's repository release or tag page and use the exact commit that release/v1 currently points to. Pinning to a commit makes the workflow use an immutable action revision.
  4. Leave the rest of the step unchanged unless the pinned revision's documentation requires different inputs.
💬 Ignore this finding

Reply with Semgrep commands to ignore this finding.

  • /fp <comment> for false positive
  • /ar <comment> for acceptable risk
  • /other <comment> for all other reasons

Alternatively, triage in Semgrep AppSec Platform to ignore the finding created by third-party-action-not-pinned-to-commit-sha.

Need help with this issue? Consult our appsec team or ask in #help-appsec on Slack.

You can view more details about this finding in the Semgrep AppSec Platform.

40 changes: 40 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: Test

on:
push:
branches:
- main
pull_request:
workflow_dispatch:

permissions:
contents: read

jobs:
test:
name: Test Python ${{ matrix.python-version }}

runs-on: ubuntu-latest

strategy:
fail-fast: false
matrix:
python-version: [ "3.9", "3.10", "3.11", "3.12", "3.13", "3.14" ]

steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0

- uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
cache: 'pip'
cache-dependency-path: pyproject.toml

- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install -e .
- name: Run tests
run: make test
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,5 @@ build
.vscode/
.idea/
.python-version
venv
.venv
20 changes: 20 additions & 0 deletions .mise.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[env]
MISE_FETCH_REMOTE_VERSIONS_TIMEOUT = "30s"

_.python.venv = {
path = ".venv",
create = true,
}

[settings]
python.uv_venv_auto = false
python.venv_stdlib = true

[tools]
python = "3.11"

[tasks.test]
run = 'make install test'

[tasks.lint]
run = 'make install lint'
Loading