Skip to content
Open
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
41 changes: 41 additions & 0 deletions .github/workflows/crewai-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: CrewAI CI

on:
pull_request:
branches: [main]
paths:
- ".github/workflows/crewai-ci.yml"
- "crewai/**"
push:
branches: [main]
paths:
- ".github/workflows/crewai-ci.yml"
- "crewai/**"

permissions:
contents: read

jobs:
test:
runs-on: ubuntu-latest

defaults:
run:
working-directory: crewai

steps:
- uses: actions/checkout@v6

- uses: actions/setup-python@v6
with:
python-version: "3.12"

- run: python -m pip install --upgrade pip

- run: python -m pip install -e . -r requirements-dev.txt

- run: make lint

- run: make test

- run: python -m build
106 changes: 106 additions & 0 deletions .github/workflows/crewai-publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
name: CrewAI CD - Publish to PyPI

on:
push:
branches: [main]
paths:
- ".github/workflows/crewai-publish.yml"
- "crewai/**"

jobs:
build:
name: Build distribution
runs-on: ubuntu-latest
permissions:
contents: read
outputs:
Comment on lines +1 to +16

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Add a minimal top-level permissions block.

No permissions block is declared at the workflow level, so jobs inherit the default (often broad) GITHUB_TOKEN scopes. Restrict to least privilege at the top and let jobs widen only as needed.

🔒 Proposed fix
 on:
   push:
     branches: [main]
     paths:
       - ".github/workflows/crewai-publish.yml"
       - "crewai/**"
 
+permissions:
+  contents: read
+
 jobs:
📝 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.

Suggested change
name: CrewAI CD - Publish to PyPI
on:
push:
branches: [main]
paths:
- ".github/workflows/crewai-publish.yml"
- "crewai/**"
jobs:
build:
name: Build distribution
runs-on: ubuntu-latest
permissions:
contents: read
outputs:
name: CrewAI CD - Publish to PyPI
on:
push:
branches: [main]
paths:
- ".github/workflows/crewai-publish.yml"
- "crewai/**"
permissions:
contents: read
jobs:
build:
name: Build distribution
runs-on: ubuntu-latest
permissions:
contents: read
outputs:
🧰 Tools
🪛 zizmor (1.26.1)

[warning] 1-107: overly broad permissions (excessive-permissions): default permissions used due to no permissions: block

(excessive-permissions)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/crewai-publish.yml around lines 1 - 16, Add a top-level
permissions block to the CrewAI CD - Publish to PyPI workflow so the default
GITHUB_TOKEN scope is minimized; keep the existing job-level permissions in
build and only widen permissions in specific jobs if needed. Update the workflow
near the on/job declarations, using the workflow name and build job as anchors
when editing.

Source: Linters/SAST tools

version-exists: ${{ steps.version.outputs.exists }}
package-version: ${{ steps.version.outputs.version }}
steps:
- name: Checkout repository
uses: actions/checkout@v6

- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.12"

- name: Install uv
uses: astral-sh/setup-uv@v8.1.0

- name: Check PyPI version availability
id: version
working-directory: ./crewai
run: |
PACKAGE=$(python -c "import tomllib; f=open('pyproject.toml','rb'); d=tomllib.load(f); print(d['project']['name'])")
VERSION=$(python -c "import tomllib; f=open('pyproject.toml','rb'); d=tomllib.load(f); print(d['project']['version'])")
echo "package=${PACKAGE}" >> "$GITHUB_OUTPUT"
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
RESULT=$(python - "$PACKAGE" "$VERSION" <<'PY'
import sys
import urllib.error
import urllib.parse
import urllib.request

package = sys.argv[1]
version = sys.argv[2]
url = f"https://pypi.org/pypi/{urllib.parse.quote(package)}/{version}/json"
try:
with urllib.request.urlopen(url, timeout=10):
pass
except urllib.error.HTTPError as exc:
if exc.code == 404:
print("missing")
sys.exit(0)
print(f"PyPI returned HTTP {exc.code} while checking {url}", file=sys.stderr)
sys.exit(2)
except Exception as exc:
print(f"Failed to check PyPI for {url}: {exc}", file=sys.stderr)
sys.exit(2)
print("exists")
PY
)
case "$RESULT" in
exists)
echo "exists=true" >> "$GITHUB_OUTPUT"
echo "${PACKAGE} ${VERSION} already exists on PyPI; skipping publish."
;;
missing)
echo "exists=false" >> "$GITHUB_OUTPUT"
echo "${PACKAGE} ${VERSION} is available on PyPI; building distribution."
;;
*)
echo "Unexpected PyPI availability result: $RESULT"
exit 1
;;
esac

- name: Build package
if: steps.version.outputs.exists == 'false'
working-directory: ./crewai
run: uv build

- name: Upload distribution artifact
if: steps.version.outputs.exists == 'false'
uses: actions/upload-artifact@v7
with:
name: python-package-distributions
path: crewai/dist/

publish-pypi:
name: Publish to PyPI
needs: build
if: needs.build.outputs.version-exists == 'false'
runs-on: ubuntu-latest
steps:
- name: Download distributions
uses: actions/download-artifact@v8
with:
name: python-package-distributions
path: dist/

- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
packages-dir: dist/
password: ${{ secrets.PYPI_API_TOKEN }}
5 changes: 5 additions & 0 deletions crewai/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# TinyFish API key — create one at https://agent.tinyfish.ai/api-keys
TINYFISH_API_KEY=your_api_key_here

# An LLM key for CrewAI agents (any provider CrewAI supports). Example:
# OPENAI_API_KEY=sk-...
26 changes: 26 additions & 0 deletions crewai/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Python
__pycache__/
*.py[cod]
*.egg-info/
build/
dist/
.eggs/

# Virtual environments
.venv/
venv/
env/

# Tooling caches
.pytest_cache/
.ruff_cache/
.mypy_cache/

# Secrets / local config
.env
.env.local

# Editor / OS
.DS_Store
.idea/
.vscode/
21 changes: 21 additions & 0 deletions crewai/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2026 TinyFish

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
16 changes: 16 additions & 0 deletions crewai/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
.PHONY: format lint test clean

format:
ruff format src tests
ruff check --fix src tests

lint:
ruff check src tests
ruff format --check src tests

test:
pytest tests -v

clean:
rm -rf build dist *.egg-info .pytest_cache .ruff_cache
find . -type d -name __pycache__ -exec rm -rf {} +
Loading