Skip to content

Commit 233c86c

Browse files
Merge pull request #2007 from blacklanternsecurity/3.0
BBOT 3.0 - blazed_elijah
2 parents 1b5cdc2 + d8f056e commit 233c86c

364 files changed

Lines changed: 16476 additions & 9984 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/benchmark.yml

Lines changed: 64 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ permissions:
1818
jobs:
1919
benchmark:
2020
runs-on: ubuntu-latest
21-
21+
2222
steps:
2323
- uses: actions/checkout@v6
2424
with:
@@ -29,10 +29,11 @@ jobs:
2929
with:
3030
python-version: "3.11"
3131

32+
- name: Install uv
33+
uses: astral-sh/setup-uv@v7
34+
3235
- name: Install dependencies
33-
run: |
34-
pip install poetry
35-
poetry install --with dev
36+
run: uv sync --group dev
3637

3738
- name: Install system dependencies
3839
run: |
@@ -42,7 +43,7 @@ jobs:
4243
# Generate benchmark comparison report using our branch-based script
4344
- name: Generate benchmark comparison report
4445
run: |
45-
poetry run python bbot/scripts/benchmark_report.py \
46+
uv run python bbot/scripts/benchmark_report.py \
4647
--base ${{ github.base_ref }} \
4748
--current ${{ github.head_ref }} \
4849
--output benchmark_report.md \
@@ -51,7 +52,7 @@ jobs:
5152

5253
# Upload benchmark results as artifacts
5354
- name: Upload benchmark results
54-
uses: actions/upload-artifact@v6
55+
uses: actions/upload-artifact@v7
5556
with:
5657
name: benchmark-results
5758
path: |
@@ -66,101 +67,85 @@ jobs:
6667
with:
6768
script: |
6869
const fs = require('fs');
69-
70-
try {
71-
const report = fs.readFileSync('benchmark_report.md', 'utf8');
72-
73-
// Find existing benchmark comment (with pagination)
70+
71+
// Helper: find existing benchmark comments on this PR
72+
async function findBenchmarkComments() {
7473
const comments = await github.rest.issues.listComments({
7574
owner: context.repo.owner,
7675
repo: context.repo.repo,
7776
issue_number: context.issue.number,
78-
per_page: 100, // Get more comments per page
77+
per_page: 100,
7978
});
80-
81-
// Debug: log all comments to see what we're working with
79+
8280
console.log(`Found ${comments.data.length} comments on this PR`);
83-
comments.data.forEach((comment, index) => {
84-
console.log(`Comment ${index}: user=${comment.user.login}, body preview="${comment.body.substring(0, 100)}..."`);
85-
});
86-
87-
const existingComments = comments.data.filter(comment =>
81+
82+
const benchmarkComments = comments.data.filter(comment =>
8883
comment.body.toLowerCase().includes('performance benchmark') &&
8984
comment.user.login === 'github-actions[bot]'
9085
);
91-
92-
console.log(`Found ${existingComments.length} existing benchmark comments`);
93-
94-
if (existingComments.length > 0) {
95-
// Sort comments by creation date to find the most recent
96-
const sortedComments = existingComments.sort((a, b) =>
86+
87+
console.log(`Found ${benchmarkComments.length} existing benchmark comments`);
88+
return benchmarkComments;
89+
}
90+
91+
// Helper: post or update the benchmark comment
92+
async function upsertComment(body) {
93+
const existing = await findBenchmarkComments();
94+
95+
if (existing.length > 0) {
96+
const sorted = existing.sort((a, b) =>
9797
new Date(b.created_at) - new Date(a.created_at)
9898
);
99-
100-
const mostRecentComment = sortedComments[0];
101-
console.log(`Updating most recent benchmark comment: ${mostRecentComment.id} (created: ${mostRecentComment.created_at})`);
102-
99+
103100
await github.rest.issues.updateComment({
104101
owner: context.repo.owner,
105102
repo: context.repo.repo,
106-
comment_id: mostRecentComment.id,
107-
body: report
103+
comment_id: sorted[0].id,
104+
body: body
108105
});
109-
console.log('Updated existing benchmark comment');
110-
111-
// Delete any older duplicate comments
112-
if (existingComments.length > 1) {
113-
console.log(`Deleting ${existingComments.length - 1} older duplicate comments`);
114-
for (let i = 1; i < sortedComments.length; i++) {
115-
const commentToDelete = sortedComments[i];
116-
console.log(`Attempting to delete comment ${commentToDelete.id} (created: ${commentToDelete.created_at})`);
117-
118-
try {
119-
await github.rest.issues.deleteComment({
120-
owner: context.repo.owner,
121-
repo: context.repo.repo,
122-
comment_id: commentToDelete.id
123-
});
124-
console.log(`Successfully deleted duplicate comment: ${commentToDelete.id}`);
125-
} catch (error) {
126-
console.error(`Failed to delete comment ${commentToDelete.id}: ${error.message}`);
127-
console.error(`Error details:`, error);
128-
}
106+
console.log(`Updated benchmark comment: ${sorted[0].id}`);
107+
108+
// Clean up older duplicates
109+
for (let i = 1; i < sorted.length; i++) {
110+
try {
111+
await github.rest.issues.deleteComment({
112+
owner: context.repo.owner,
113+
repo: context.repo.repo,
114+
comment_id: sorted[i].id
115+
});
116+
console.log(`Deleted duplicate comment: ${sorted[i].id}`);
117+
} catch (e) {
118+
console.error(`Failed to delete comment ${sorted[i].id}: ${e.message}`);
129119
}
130120
}
131121
} else {
132-
// Create new comment
133122
await github.rest.issues.createComment({
134123
owner: context.repo.owner,
135124
repo: context.repo.repo,
136125
issue_number: context.issue.number,
137-
body: report
126+
body: body
138127
});
139128
console.log('Created new benchmark comment');
140129
}
141-
} catch (error) {
142-
console.error('Failed to post benchmark results:', error);
143-
144-
// Post a fallback comment
145-
const fallbackMessage = [
146-
'## Performance Benchmark Report',
147-
'',
148-
'> ⚠️ **Failed to generate detailed benchmark comparison**',
149-
'> ',
150-
'> The benchmark comparison failed to run. This might be because:',
151-
'> - Benchmark tests don\'t exist on the base branch yet',
152-
'> - Dependencies are missing',
153-
'> - Test execution failed',
154-
'> ',
155-
'> Please check the [workflow logs](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}) for details.',
156-
'> ',
157-
'> 📁 Benchmark artifacts may be available for download from the workflow run.'
158-
].join('\\n');
159-
160-
await github.rest.issues.createComment({
161-
owner: context.repo.owner,
162-
repo: context.repo.repo,
163-
issue_number: context.issue.number,
164-
body: fallbackMessage
165-
});
166-
}
130+
}
131+
132+
let report;
133+
try {
134+
report = fs.readFileSync('benchmark_report.md', 'utf8');
135+
} catch (e) {
136+
console.error('Failed to read benchmark report:', e.message);
137+
report = `## Performance Benchmark Report
138+
139+
> **Failed to generate detailed benchmark comparison**
140+
>
141+
> The benchmark comparison failed to run. This might be because:
142+
> - Benchmark tests don't exist on the base branch yet
143+
> - Dependencies are missing
144+
> - Test execution failed
145+
>
146+
> Please check the [workflow logs](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}) for details.
147+
>
148+
> Benchmark artifacts may be available for download from the workflow run.`;
149+
}
150+
151+
await upsertComment(report);

.github/workflows/distro_tests.yml

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,20 @@ jobs:
1717
os: ["ubuntu:22.04", "ubuntu:24.04", "debian", "archlinux", "fedora", "kalilinux/kali-rolling", "parrotsec/security"]
1818
steps:
1919
- uses: actions/checkout@v6
20-
- name: Install Python and Poetry
20+
- name: Install Python and uv
2121
run: |
2222
if [ -f /etc/os-release ]; then
2323
. /etc/os-release
2424
if [ "$ID" = "ubuntu" ] || [ "$ID" = "debian" ] || [ "$ID" = "kali" ] || [ "$ID" = "parrotsec" ]; then
2525
export DEBIAN_FRONTEND=noninteractive
26+
# Pin Parrot to MIT mirror to avoid stale third-party mirrors (e.g. mirror.clarkson.edu)
27+
# Note: parrotsec/security image reports ID=debian, so we detect via parrot.list
28+
if [ -f /etc/apt/sources.list.d/parrot.list ]; then
29+
rm -f /etc/apt/sources.list /etc/apt/sources.list.old /etc/apt/sources.list.d/*.list /etc/apt/sources.list.d/*.sources
30+
echo "deb https://mirrors.mit.edu/parrot/ echo main contrib non-free non-free-firmware" > /etc/apt/sources.list.d/parrot.list
31+
echo "deb https://mirrors.mit.edu/parrot/ echo-security main contrib non-free non-free-firmware" >> /etc/apt/sources.list.d/parrot.list
32+
echo "deb https://mirrors.mit.edu/parrot/ echo-backports main contrib non-free non-free-firmware" >> /etc/apt/sources.list.d/parrot.list
33+
fi
2634
apt-get update
2735
apt-get -y install curl git bash build-essential docker.io libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget llvm libncurses5-dev libncursesw5-dev xz-utils tk-dev libffi-dev liblzma-dev
2836
elif [ "$ID" = "alpine" ]; then
@@ -51,22 +59,25 @@ jobs:
5159
pyenv rehash
5260
python3.11 -m pip install --user pipx
5361
python3.11 -m pipx ensurepath
54-
pipx install poetry
62+
pipx install uv
5563
"
5664
- name: Set OS Environment Variable
5765
run: echo "OS_NAME=${{ matrix.os }}" | sed 's|[:/]|_|g' >> $GITHUB_ENV
5866
- name: Run tests
5967
run: |
60-
export PATH="$HOME/.local/bin:$PATH"
61-
export PATH="$HOME/.pyenv/bin:$PATH"
62-
export PATH="$HOME/.pyenv/shims:$PATH"
68+
# Preserve pyenv/pipx paths installed under the GitHub-set HOME
69+
export PATH="/github/home/.local/bin:$PATH"
70+
export PATH="/github/home/.pyenv/bin:$PATH"
71+
export PATH="/github/home/.pyenv/shims:$PATH"
72+
# Fix HOME to match euid (root) so rustup/cargo don't refuse to build
73+
export HOME="$(getent passwd $(whoami) | cut -d: -f6)"
6374
export BBOT_DISTRO_TESTS=true
64-
poetry env use python3.11
65-
poetry install
66-
poetry run pytest --reruns 2 --exitfirst -o timeout_func_only=true --timeout 1200 --disable-warnings --log-cli-level=INFO .
75+
uv python pin 3.11
76+
uv sync --group dev
77+
uv run pytest --reruns 2 --exitfirst -o timeout_func_only=true --timeout 1200 --disable-warnings --log-cli-level=INFO .
6778
- name: Upload Debug Logs
6879
if: always()
69-
uses: actions/upload-artifact@v6
80+
uses: actions/upload-artifact@v7
7081
with:
7182
name: pytest-debug-logs-${{ env.OS_NAME }}
7283
path: pytest_debug.log

.github/workflows/docs_updater.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@ jobs:
1717
uses: actions/setup-python@v6
1818
with:
1919
python-version: "3.x"
20+
- name: Install uv
21+
uses: astral-sh/setup-uv@v7
2022
- name: Install dependencies
21-
run: |
22-
pip install poetry
23-
poetry install
23+
run: uv sync --group dev
2424
- name: Generate docs
2525
run: |
26-
poetry run bbot/scripts/docs.py
26+
uv run bbot/scripts/docs.py
2727
- name: Create or Update Pull Request
2828
uses: peter-evans/create-pull-request@v8
2929
with:

0 commit comments

Comments
 (0)