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
43 changes: 22 additions & 21 deletions .github/workflows/benchmark.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ permissions:
jobs:
benchmark:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v6
with:
Expand All @@ -29,10 +29,11 @@ jobs:
with:
python-version: "3.11"

- name: Install uv
uses: astral-sh/setup-uv@v7

- name: Install dependencies
run: |
pip install poetry
poetry install --with dev
run: uv sync --group dev

- name: Install system dependencies
run: |
Expand All @@ -42,7 +43,7 @@ jobs:
# Generate benchmark comparison report using our branch-based script
- name: Generate benchmark comparison report
run: |
poetry run python bbot/scripts/benchmark_report.py \
uv run python bbot/scripts/benchmark_report.py \
--base ${{ github.base_ref }} \
--current ${{ github.head_ref }} \
--output benchmark_report.md \
Expand All @@ -66,55 +67,55 @@ jobs:
with:
script: |
const fs = require('fs');

try {
const report = fs.readFileSync('benchmark_report.md', 'utf8');

// Find existing benchmark comment (with pagination)
const comments = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
per_page: 100, // Get more comments per page
});

// Debug: log all comments to see what we're working with
console.log(`Found ${comments.data.length} comments on this PR`);
comments.data.forEach((comment, index) => {
console.log(`Comment ${index}: user=${comment.user.login}, body preview="${comment.body.substring(0, 100)}..."`);
});
const existingComments = comments.data.filter(comment =>

const existingComments = comments.data.filter(comment =>
comment.body.toLowerCase().includes('performance benchmark') &&
comment.user.login === 'github-actions[bot]'
);

console.log(`Found ${existingComments.length} existing benchmark comments`);

if (existingComments.length > 0) {
// Sort comments by creation date to find the most recent
const sortedComments = existingComments.sort((a, b) =>
const sortedComments = existingComments.sort((a, b) =>
new Date(b.created_at) - new Date(a.created_at)
);

const mostRecentComment = sortedComments[0];
console.log(`Updating most recent benchmark comment: ${mostRecentComment.id} (created: ${mostRecentComment.created_at})`);

await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: mostRecentComment.id,
body: report
});
console.log('Updated existing benchmark comment');

// Delete any older duplicate comments
if (existingComments.length > 1) {
console.log(`Deleting ${existingComments.length - 1} older duplicate comments`);
for (let i = 1; i < sortedComments.length; i++) {
const commentToDelete = sortedComments[i];
console.log(`Attempting to delete comment ${commentToDelete.id} (created: ${commentToDelete.created_at})`);

try {
await github.rest.issues.deleteComment({
owner: context.repo.owner,
Expand All @@ -140,7 +141,7 @@ jobs:
}
} catch (error) {
console.error('Failed to post benchmark results:', error);

// Post a fallback comment
const fallbackMessage = [
'## Performance Benchmark Report',
Expand All @@ -149,18 +150,18 @@ jobs:
'> ',
'> The benchmark comparison failed to run. This might be because:',
'> - Benchmark tests don\'t exist on the base branch yet',
'> - Dependencies are missing',
'> - Dependencies are missing',
'> - Test execution failed',
'> ',
'> Please check the [workflow logs](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}) for details.',
'> ',
'> 馃搧 Benchmark artifacts may be available for download from the workflow run.'
].join('\\n');

await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: fallbackMessage
});
}
}
10 changes: 5 additions & 5 deletions .github/workflows/distro_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
os: ["ubuntu:22.04", "ubuntu:24.04", "debian", "archlinux", "fedora", "kalilinux/kali-rolling", "parrotsec/security"]
steps:
- uses: actions/checkout@v6
- name: Install Python and Poetry
- name: Install Python and uv
run: |
if [ -f /etc/os-release ]; then
. /etc/os-release
Expand Down Expand Up @@ -51,7 +51,7 @@ jobs:
pyenv rehash
python3.11 -m pip install --user pipx
python3.11 -m pipx ensurepath
pipx install poetry
pipx install uv
"
- name: Set OS Environment Variable
run: echo "OS_NAME=${{ matrix.os }}" | sed 's|[:/]|_|g' >> $GITHUB_ENV
Expand All @@ -61,9 +61,9 @@ jobs:
export PATH="$HOME/.pyenv/bin:$PATH"
export PATH="$HOME/.pyenv/shims:$PATH"
export BBOT_DISTRO_TESTS=true
poetry env use python3.11
poetry install
poetry run pytest --reruns 2 --exitfirst -o timeout_func_only=true --timeout 1200 --disable-warnings --log-cli-level=INFO .
uv python pin 3.11
uv sync --group dev
uv run pytest --reruns 2 --exitfirst -o timeout_func_only=true --timeout 1200 --disable-warnings --log-cli-level=INFO .
- name: Upload Debug Logs
if: always()
uses: actions/upload-artifact@v6
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/docs_updater.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ jobs:
uses: actions/setup-python@v6
with:
python-version: "3.x"
- name: Install uv
uses: astral-sh/setup-uv@v7
- name: Install dependencies
run: |
pip install poetry
poetry install
run: uv sync --group dev
- name: Generate docs
run: |
poetry run bbot/scripts/docs.py
uv run bbot/scripts/docs.py
- name: Create or Update Pull Request
uses: peter-evans/create-pull-request@v8
with:
Expand Down
97 changes: 57 additions & 40 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,17 @@ jobs:
python-version: ${{ matrix.python-version }}
- name: Set Python Version Environment Variable
run: echo "PYTHON_VERSION=${{ matrix.python-version }}" | sed 's|[:/]|_|g' >> $GITHUB_ENV
- name: Install uv
uses: astral-sh/setup-uv@v7
- name: Install dependencies
run: |
pip install poetry
poetry install
run: uv sync --group dev
- name: Lint
run: |
poetry run ruff check
poetry run ruff format --check
uv run ruff check
uv run ruff format --check
- name: Run tests
run: |
poetry run pytest -vv --reruns 2 -o timeout_func_only=true --timeout 1200 --disable-warnings --log-cli-level=INFO --cov-config=bbot/test/coverage.cfg --cov-report xml:cov.xml --cov=bbot .
uv run pytest -vv --reruns 2 -o timeout_func_only=true --timeout 1200 --disable-warnings --log-cli-level=INFO --cov-config=bbot/test/coverage.cfg --cov-report xml:cov.xml --cov=bbot .
- name: Upload Debug Logs
if: always()
uses: actions/upload-artifact@v6
Expand Down Expand Up @@ -69,14 +69,32 @@ jobs:
uses: actions/setup-python@v6
with:
python-version: "3.x"
- name: Install dependencies
- name: Install uv
uses: astral-sh/setup-uv@v7
- name: Calculate version
id: calc_version
run: |
python -m pip install --upgrade pip
pip install poetry build
poetry self add "poetry-dynamic-versioning[plugin]"
# Get base version from latest stable tag (exclude rc tags, strip 'v' prefix)
LATEST_STABLE_TAG=$(git describe --tags --abbrev=0 --exclude="*rc*")
BASE_VERSION=$(echo "$LATEST_STABLE_TAG" | sed 's/^v//')

if [[ "${{ github.ref }}" == "refs/heads/stable" ]]; then
# Stable: clean version from tag
VERSION="$BASE_VERSION"
elif [[ "${{ github.ref }}" == "refs/heads/dev" ]]; then
# Dev: version.distancerc (e.g., 3.0.0.123rc)
DISTANCE=$(git rev-list ${LATEST_STABLE_TAG}..HEAD --count)
VERSION="${BASE_VERSION}.${DISTANCE}rc"
fi

echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
echo "Calculated version: $VERSION"

# Write version to file for hatchling to pick up
echo "__version__ = \"$VERSION\"" > bbot/_version.py
- name: Build Pypi package
if: github.ref == 'refs/heads/stable' || github.ref == 'refs/heads/dev'
run: python -m build
run: uv build
- name: Publish Pypi package
if: github.ref == 'refs/heads/stable' || github.ref == 'refs/heads/dev'
uses: pypa/gh-action-pypi-publish@release/v1.13
Expand All @@ -85,7 +103,7 @@ jobs:
- name: Get BBOT version
id: version
run: |
FULL_VERSION=$(poetry version | cut -d' ' -f2)
FULL_VERSION="${{ steps.calc_version.outputs.VERSION }}"
echo "BBOT_VERSION=$FULL_VERSION" >> $GITHUB_OUTPUT
# Extract major.minor (e.g., 2.7 from 2.7.1)
MAJOR_MINOR=$(echo "$FULL_VERSION" | cut -d'.' -f1-2)
Expand Down Expand Up @@ -177,6 +195,28 @@ jobs:
done
outputs:
BBOT_VERSION: ${{ steps.version.outputs.BBOT_VERSION }}
tag_commit:
needs: publish_code
runs-on: ubuntu-latest
if: github.event_name == 'push' && (github.ref == 'refs/heads/stable' || github.ref == 'refs/heads/dev')
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Configure git
run: |
git config --local user.email "info@blacklanternsecurity.com"
git config --local user.name "GitHub Actions"
- name: Tag commit
run: |
VERSION="v${{ needs.publish_code.outputs.BBOT_VERSION }}"
if [[ "${{ github.ref }}" == "refs/heads/stable" ]]; then
git tag -a "$VERSION" -m "Stable Release $VERSION"
else
git tag -a "$VERSION" -m "Dev Release $VERSION"
fi
git push origin "$VERSION"

publish_docs:
runs-on: ubuntu-latest
if: github.event_name == 'push' && (github.ref == 'refs/heads/stable' || github.ref == 'refs/heads/dev')
Expand All @@ -194,10 +234,10 @@ jobs:
path: .cache
restore-keys: |
mkdocs-material-
- name: Install uv
uses: astral-sh/setup-uv@v7
- name: Install dependencies
run: |
pip install poetry
poetry install --only=docs
run: uv sync --only-group docs
- name: Configure Git
run: |
git config user.name github-actions
Expand All @@ -211,35 +251,12 @@ jobs:
- name: Generate docs (stable branch)
if: github.ref == 'refs/heads/stable'
run: |
poetry run mike deploy Stable
uv run mike deploy Stable
- name: Generate docs (dev branch)
if: github.ref == 'refs/heads/dev'
run: |
poetry run mike deploy Dev
uv run mike deploy Dev
- name: Publish docs
run: |
git switch gh-pages
git push
# tag_commit:
# needs: publish_code
# runs-on: ubuntu-latest
# if: github.event_name == 'push' && github.ref == 'refs/heads/stable'
# steps:
# - uses: actions/checkout@v6
# with:
# ref: ${{ github.head_ref }}
# fetch-depth: 0 # Fetch all history for all tags and branches
# - name: Configure git
# run: |
# git config --local user.email "info@blacklanternsecurity.com"
# git config --local user.name "GitHub Actions"
# - name: Tag commit
# run: |
# VERSION="${{ needs.publish_code.outputs.BBOT_VERSION }}"
# if [[ "${{ github.ref }}" == "refs/heads/dev" ]]; then
# TAG_MESSAGE="Dev Release $VERSION"
# elif [[ "${{ github.ref }}" == "refs/heads/stable" ]]; then
# TAG_MESSAGE="Stable Release $VERSION"
# fi
# git tag -a $VERSION -m "$TAG_MESSAGE"
# git push origin --tags
6 changes: 4 additions & 2 deletions bbot/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
# version placeholder (replaced by poetry-dynamic-versioning)
__version__ = "v0.0.0"
try:
from bbot._version import __version__
except ImportError:
__version__ = "0.0.0"
1 change: 1 addition & 0 deletions bbot/_version.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__version__ = "0.0.0"
18 changes: 18 additions & 0 deletions bbot/core/helpers/depsinstaller/installer.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,24 @@ async def pip_install(self, packages, constraints=None):
packages_str = ",".join(packages)
log.info(f"Installing the following pip packages: {packages_str}")

# Ensure pip is available in the environment
try:
check_pip_command = [sys.executable, "-m", "pip", "--version"]
await self.parent_helper.run(check_pip_command, check=True)
except CalledProcessError:
# pip is not available, try to install it with ensurepip
log.info("pip not found in virtual environment, attempting to install with ensurepip")
try:
ensurepip_command = [sys.executable, "-m", "ensurepip", "--upgrade"]
await self.parent_helper.run(ensurepip_command, check=True)
log.info("Successfully installed pip with ensurepip")
except CalledProcessError as err:
log.warning(
f"Failed to install pip with ensurepip (return code {err.returncode}): {err.stderr}. "
f"If using uv, create the virtual environment with 'uv venv --seed' or set UV_VENV_SEED=1"
)
return False

command = [sys.executable, "-m", "pip", "install", "--upgrade"] + packages

# if no custom constraints are provided, use the constraints of the currently installed version of bbot
Expand Down
Loading
Loading