Skip to content

Commit 825436a

Browse files
committed
Bring .github in line with main
Signed-off-by: Simon Dudley <simon.dudley@consensys.net>
1 parent 0775def commit 825436a

16 files changed

Lines changed: 1153 additions & 64 deletions

.github/ISSUE_TEMPLATE/bug-report.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ assignees: ''
1212
<!-- comply with it, including treating everyone with respect: -->
1313
<!-- https://github.com/besu-eth/besu/blob/main/CODE_OF_CONDUCT.md -->
1414
<!-- * Reproduced the issue in the latest version of the software -->
15-
<!-- * Read the debugging docs: https://besu.hyperledger.org/private-networks/how-to -->
15+
<!-- * Read the docs: https://docs.besu-eth.org/ -->
1616
<!-- * Duplicate Issue check: https://github.com/search?q=+is%3Aissue+repo%3Abesu-eth/besu -->
1717

1818
### Steps to Reproduce

.github/pull_request_template.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
### Thanks for sending a pull request! Have you done the following?
1010

1111
- [ ] Checked out our [contribution guidelines](https://github.com/besu-eth/besu/blob/main/CONTRIBUTING.md)?
12-
- [ ] Considered documentation and added the `doc-change-required` label to this PR [if updates are required](https://wiki.hyperledger.org/display/BESU/Documentation).
13-
- [ ] Considered the changelog and included an [update if required](https://wiki.hyperledger.org/display/BESU/Changelog).
12+
- [ ] Considered documentation and added the `doc-change-required` label to this PR if updates are required in the [Besu documentation](https://github.com/besu-eth/besu-docs).
13+
- [ ] Considered the changelog and [included an update if required](https://github.com/besu-eth/besu/blob/main/CONTRIBUTING.md#changelog).
1414
- [ ] For database changes (e.g. KeyValueSegmentIdentifier) considered compatibility and performed forwards and backwards compatibility tests
1515

1616
### Locally, you can run these tests to catch failures early:
@@ -20,6 +20,6 @@
2020
- [ ] acceptance tests: `./gradlew acceptanceTest`
2121
- [ ] integration tests: `./gradlew integrationTest`
2222
- [ ] reference tests: `./gradlew ethereum:referenceTests:referenceTests`
23-
- [ ] hive tests: [Engine or other RPCs modified?](https://lf-hyperledger.atlassian.net/wiki/spaces/BESU/pages/22156302/Using+Hive+Test+Suite)
23+
- [ ] hive tests: [Engine or other RPCs modified?](https://github.com/besu-eth/besu/wiki/Working-through-Hive-tests)
2424

2525

.github/scripts/splitList.sh

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#!/usr/bin/env bash
2+
##
3+
## Copyright contributors to Besu.
4+
##
5+
## Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
6+
## the License. You may obtain a copy of the License at
7+
##
8+
## http://www.apache.org/licenses/LICENSE-2.0
9+
##
10+
## Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
11+
## an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
12+
## specific language governing permissions and limitations under the License.
13+
##
14+
## SPDX-License-Identifier: Apache-2.0
15+
##
16+
17+
N=$2 # Number of groups
18+
i=0 # Initialize counter
19+
cat $1 | while read line; do
20+
echo "$line" >> "group_$((i % N + 1)).txt"
21+
let i++
22+
done
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
#!/bin/bash
2+
##
3+
## Copyright contributors to Besu.
4+
##
5+
## Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
6+
## the License. You may obtain a copy of the License at
7+
##
8+
## http://www.apache.org/licenses/LICENSE-2.0
9+
##
10+
## Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
11+
## an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
12+
## specific language governing permissions and limitations under the License.
13+
##
14+
## SPDX-License-Identifier: Apache-2.0
15+
##
16+
17+
REPORTS_DIR="$1"
18+
REPORT_STRIP_PREFIX="$2"
19+
REPORT_STRIP_SUFFIX="$3"
20+
SPLIT_COUNT=$4
21+
SPLIT_INDEX=$5
22+
23+
# extract tests time from Junit XML reports
24+
find "$REPORTS_DIR" -type f -name TEST-*.xml | xargs -I{} bash -c "xmlstarlet sel -t -v 'concat(sum(//testcase/@time), \" \", //testsuite/testcase[1]/@classname)' '{}'; echo '{}' | sed \"s#${REPORT_STRIP_PREFIX}/\(.*\)/${REPORT_STRIP_SUFFIX}.*# \1#\"" > tmp/timing.tsv
25+
26+
# Sort times in descending order
27+
IFS=$'\n' sorted=($(sort -nr tmp/timing.tsv))
28+
unset IFS
29+
30+
sums=()
31+
tests=()
32+
33+
# Initialize sums
34+
for ((i=0; i<SPLIT_COUNT; i++))
35+
do
36+
sums[$i]=0
37+
done
38+
39+
echo -n '' > tmp/processedTests.list
40+
41+
# add tests to groups trying to balance the sum of execution time of each group
42+
for line in "${sorted[@]}"; do
43+
line_parts=( $line )
44+
test_time=$( echo "${line_parts[0]} * 1000 / 1" | bc ) # convert to millis without decimals
45+
test_name=${line_parts[1]}
46+
module_dir=${line_parts[2]}
47+
test_with_module="$test_name $module_dir"
48+
49+
# deduplication check to avoid executing a test multiple time
50+
if grep -F -q --line-regexp "$test_with_module" tmp/processedTests.list
51+
then
52+
continue
53+
fi
54+
55+
# Does the test still exists?
56+
if grep -F -q --line-regexp "$test_with_module" tmp/currentTests.list
57+
then
58+
# Find index of min sum
59+
idx_min_sum=0
60+
min_sum=${sums[0]}
61+
for ((i=0; i<SPLIT_COUNT; i++))
62+
do
63+
if [[ ${sums[$i]} -lt $min_sum ]]
64+
then
65+
idx_min_sum=$i
66+
min_sum=${sums[$i]}
67+
fi
68+
done
69+
70+
# Add the test to the min sum list
71+
min_sum_tests=${tests[$idx_min_sum]}
72+
tests[$idx_min_sum]="${min_sum_tests}${test_with_module},"
73+
74+
# Update the sums
75+
((sums[idx_min_sum]+=test_time))
76+
77+
echo "$test_with_module" >> tmp/processedTests.list
78+
fi
79+
done
80+
81+
# Any new test?
82+
grep -F --line-regexp -v -f tmp/processedTests.list tmp/currentTests.list > tmp/newTests.list
83+
idx_new_test=0
84+
while read -r new_test_with_module
85+
do
86+
idx_group=$(( idx_new_test % SPLIT_COUNT ))
87+
group=${tests[$idx_group]}
88+
tests[$idx_group]="${group}${new_test_with_module},"
89+
idx_new_test=$(( idx_new_test + 1 ))
90+
done < tmp/newTests.list
91+
92+
# remove last comma
93+
for ((i=0; i<SPLIT_COUNT; i++))
94+
do
95+
test_list=${tests[$i]%,}
96+
tests[$i]="$test_list"
97+
done
98+
99+
100+
# group tests by module
101+
module_list=( $( echo "${tests[$SPLIT_INDEX]}" | tr "," "\n" | awk '{print $2}' | sort -u ) )
102+
103+
declare -A group_by_module
104+
for module_dir in "${module_list[@]}"
105+
do
106+
group_by_module[$module_dir]=""
107+
done
108+
109+
IFS="," test_list=( ${tests[$SPLIT_INDEX]} )
110+
unset IFS
111+
112+
for line in "${test_list[@]}"
113+
do
114+
line_parts=( $line )
115+
test_name=${line_parts[0]}
116+
module_dir=${line_parts[1]}
117+
118+
module_group=${group_by_module[$module_dir]}
119+
group_by_module[$module_dir]="$module_group$test_name "
120+
done
121+
122+
# return the requests index, without quotes to drop the last trailing space
123+
for module_dir in "${module_list[@]}"
124+
do
125+
module_test_task=":${module_dir//\//:}:test"
126+
module_tests=$( echo "${group_by_module[$module_dir]% }" | sed -e 's/^\| / --tests /g' )
127+
echo "$module_test_task $module_tests"
128+
done

.github/scripts/verifyArtifacts.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import requests
2+
import argparse
3+
4+
5+
def create_artifact_paths(version):
6+
artifacts_base_path = "https://hyperledger.jfrog.io/hyperledger/besu-maven/org/hyperledger/besu"
7+
# add to this list here to update the list of artifacts to check
8+
artifacts = [
9+
# besu-evm
10+
f"{artifacts_base_path}/besu-evm/{version}/besu-evm-{version}.module",
11+
f"{artifacts_base_path}/besu-evm/{version}/besu-evm-{version}.pom",
12+
f"{artifacts_base_path}/besu-evm/{version}/besu-evm-{version}.jar",
13+
# besu-plugin-api
14+
f"{artifacts_base_path}/besu-plugin-api/{version}/besu-plugin-api-{version}.module",
15+
f"{artifacts_base_path}/besu-plugin-api/{version}/besu-plugin-api-{version}.pom",
16+
f"{artifacts_base_path}/besu-plugin-api/{version}/besu-plugin-api-{version}.jar",
17+
# besu-metrics-core
18+
f"{artifacts_base_path}/internal/besu-metrics-core/{version}/besu-metrics-core-{version}.module",
19+
f"{artifacts_base_path}/internal/besu-metrics-core/{version}/besu-metrics-core-{version}.pom",
20+
f"{artifacts_base_path}/internal/besu-metrics-core/{version}/besu-metrics-core-{version}.jar",
21+
# internal/besu-ethereum-core
22+
f"{artifacts_base_path}/internal/besu-ethereum-core/{version}/besu-ethereum-core-{version}.module",
23+
f"{artifacts_base_path}/internal/besu-ethereum-core/{version}/besu-ethereum-core-{version}.pom",
24+
f"{artifacts_base_path}/internal/besu-ethereum-core/{version}/besu-ethereum-core-{version}.jar",
25+
# internal/besu-config
26+
f"{artifacts_base_path}/internal/besu-config/{version}/besu-config-{version}.module",
27+
f"{artifacts_base_path}/internal/besu-config/{version}/besu-config-{version}.pom",
28+
f"{artifacts_base_path}/internal/besu-config/{version}/besu-config-{version}.jar",
29+
# bom
30+
f"{artifacts_base_path}/bom/{version}/bom-{version}.module",
31+
f"{artifacts_base_path}/bom/{version}/bom-{version}.pom",
32+
]
33+
return artifacts
34+
35+
36+
37+
def check_url(url):
38+
print(f"Checking artifact at: {url}")
39+
r = requests.head(url)
40+
if (r.status_code != 200):
41+
raise Exception(f"Sorry, No artifact found at '{url}' !!!")
42+
43+
def main():
44+
parser = argparse.ArgumentParser(description='Check besu artifacts')
45+
parser.add_argument('--besu_version', action="store", dest='besu_version', default="")
46+
args = parser.parse_args()
47+
print(args.besu_version)
48+
49+
artifacts = create_artifact_paths(args.besu_version)
50+
print(artifacts)
51+
for url in artifacts:
52+
check_url(url)
53+
54+
if __name__ == "__main__":
55+
main()
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
name: acceptance-tests-timing-reports-update
2+
3+
# Runs on every merge to main. Grabs the per-runner acceptance test XML results from the just-merged
4+
# PR's latest successful CI run and consolidates them into a single 'acceptance-tests-timing-reports'
5+
# artifact on main.
6+
# That artifact is the timing baseline that acceptance-tests.yml downloads on every PR to split
7+
# tests across parallel runners by historical duration. The data is always one merge behind — a PR's
8+
# own results only feed the *next* PR's split.
9+
10+
on:
11+
push:
12+
branches:
13+
- main
14+
15+
jobs:
16+
syncTestReports:
17+
if: github.repository == 'besu-eth/besu'
18+
runs-on: ubuntu-latest
19+
steps:
20+
- name: Get latest merge PR number
21+
id: latest_merged_pr_number
22+
run: echo "PULL_REQUEST_NUMBER=$(gh pr list --repo besu-eth/besu --base main --state merged --json "number,mergedAt" --search "sort:updated-desc" --jq 'max_by(.mergedAt)|.number')" >> "$GITHUB_OUTPUT"
23+
env:
24+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
25+
- name: Get acceptance test reports from latest merged PR
26+
uses: dawidd6/action-download-artifact@e7466d1a7587ed14867642c2ca74b5bcc1e19a2d
27+
with:
28+
workflow: ci.yml
29+
workflow_conclusion: success
30+
pr: ${{ env.LATEST_MERGED_PR_NUMBER }}
31+
name_is_regexp: true
32+
name: 'acceptance-node-\d+-test-results'
33+
path: acceptance-tests-timing-reports
34+
if_no_artifact_found: fail
35+
env:
36+
LATEST_MERGED_PR_NUMBER: ${{ steps.latest_merged_pr_number.outputs.PULL_REQUEST_NUMBER }}
37+
- name: Upload acceptance test results
38+
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
39+
with:
40+
name: acceptance-tests-timing-reports
41+
path: 'acceptance-tests-timing-reports/**/TEST-*.xml'

.github/workflows/acceptance-tests.yml

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,19 @@
11
name: acceptance-tests
2-
on:
3-
workflow_dispatch:
4-
merge_group:
5-
pull_request:
6-
branches:
7-
- main
8-
- release-*
9-
- verkle
10-
- performance
11-
- '*-devnet-*'
122

13-
concurrency:
14-
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
15-
cancel-in-progress: true
3+
on:
4+
workflow_call:
165

176
env:
187
GRADLE_OPTS: "-Xmx1g"
198
total-runners: 14
209

2110
jobs:
22-
acceptanceTestEthereum:
11+
acceptanceTests:
2312
runs-on: ubuntu-latest
13+
timeout-minutes: 30
2414
name: "Acceptance Runner"
2515
permissions:
16+
contents: read
2617
statuses: write
2718
checks: write
2819
strategy:
@@ -39,6 +30,10 @@ jobs:
3930
with:
4031
distribution: temurin
4132
java-version: 25
33+
- name: Setup Gradle
34+
uses: gradle/actions/setup-gradle@39e147cb9de83bb9910b8ef8bd7fff0ee20fcd6f # v6.0.1
35+
with:
36+
cache-disabled: true
4237
- name: Install required packages
4338
run: sudo apt-get install -y xmlstarlet
4439
- name: setup gradle
@@ -49,17 +44,20 @@ jobs:
4944
run: ./gradlew acceptanceTest --test-dry-run -Dorg.gradle.parallel=true -Dorg.gradle.caching=true
5045
- name: Extract current test list
5146
run: mkdir tmp; find . -type f -name TEST-*.xml | xargs -I{} bash -c "xmlstarlet sel -t -v '/testsuite/testcase[1]/@classname' '{}'; echo ' acceptanceTest'" | tee tmp/currentTests.list
47+
# Downloads the timing baseline produced by update-acceptance-tests-timing-reports.yml on the last merge to main.
48+
# `splitTestsByTime.sh` uses the per-test durations in these XMLs to distribute tests across parallel runners by historical wall-clock time rather than a naive split.
49+
# If the artifact is missing # (e.g. first run), splitting falls back to round-robin for all tests.
5250
- name: Get acceptance test reports
5351
uses: dawidd6/action-download-artifact@e7466d1a7587ed14867642c2ca74b5bcc1e19a2d
5452
continue-on-error: true
5553
with:
5654
branch: main
57-
workflow: update-test-reports.yml
58-
name: acceptance-test-results
55+
workflow: acceptance-tests-timing-reports-update.yml
56+
name: acceptance-tests-timing-reports
5957
path: tmp/junit-xml-reports-downloaded
6058
if_no_artifact_found: ignore
6159
- name: Split tests
62-
run: .github/workflows/splitTestsByTime.sh tmp/junit-xml-reports-downloaded "tmp/junit-xml-reports-downloaded/acceptance-node-.*-test-results" "TEST-" ${{env.total-runners}} ${{ matrix.runner_index }} > testList.txt
60+
run: .github/scripts/splitTestsByTime.sh tmp/junit-xml-reports-downloaded "tmp/junit-xml-reports-downloaded/acceptance-node-.*-test-results" "TEST-" ${{env.total-runners}} ${{ matrix.runner_index }} > testList.txt
6361
- name: format gradle args
6462
# we do not need the module task here
6563
run: cat testList.txt | cut -f 2- -d ' ' | tee gradleArgs.txt
@@ -95,10 +93,11 @@ jobs:
9593
with:
9694
name: acceptance-node-${{matrix.runner_index}}-test-html-reports
9795
path: 'acceptance-tests/tests/build/reports/tests/**'
98-
accepttests-passed:
99-
name: "accepttests-passed"
96+
97+
acceptanceTestsPassed:
98+
name: acceptanceTestsPassed
10099
runs-on: ubuntu-latest
101-
needs: [ acceptanceTestEthereum ]
100+
needs: [ acceptanceTests ]
102101
permissions:
103102
checks: write
104103
statuses: write

.github/workflows/bft-soak-test.yml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ on:
1212
- qbft
1313
- ibft2
1414
soak-time-mins:
15-
description: 'Duration of soak test in minutes (minimum 60)'
15+
description: 'Duration of soak test in minutes (minimum 70)'
1616
required: false
17-
default: '60'
17+
default: '70'
1818
type: string
1919
besu_ref:
2020
required: true
@@ -37,6 +37,7 @@ jobs:
3737
runs-on: ubuntu-latest
3838
timeout-minutes: 180
3939
permissions:
40+
contents: read
4041
statuses: write
4142
checks: write
4243
steps:
@@ -50,7 +51,7 @@ jobs:
5051
with:
5152
distribution: temurin
5253
java-version: 25
53-
- name: setup gradle
54+
- name: Setup Gradle
5455
uses: gradle/actions/setup-gradle@39e147cb9de83bb9910b8ef8bd7fff0ee20fcd6f # v6.0.1
5556
with:
5657
cache-disabled: true

0 commit comments

Comments
 (0)