-
Notifications
You must be signed in to change notification settings - Fork 37
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
15 changed files
with
591 additions
and
100 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
name: Build | ||
|
||
on: # yamllint disable-line rule:truthy | ||
workflow_call: | ||
inputs: | ||
build_type: | ||
required: true | ||
type: string | ||
sanitize: | ||
required: true | ||
type: string | ||
|
||
jobs: | ||
run: | ||
runs-on: ubuntu-22.04 | ||
steps: | ||
- uses: actions/checkout@v3 | ||
with: | ||
submodules: recursive | ||
|
||
- name: Prepare environment | ||
run: bash .github/workflows/prepare-env.sh 14 | ||
|
||
- name: Generate Makefile | ||
run: | | ||
export CC=`which clang` CXX=`which clang++` | ||
SANITIZE_OPTION=$(python3 .github/workflows/translate_sanitize_to_ck_build_option.py ${{ inputs.sanitize }}) | ||
if [ "$SANITIZE_OPTION" != "none" ]; then | ||
cmake -G Ninja -B ./build -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DSANITIZE=$SANITIZE_OPTION | ||
else | ||
cmake -G Ninja -B ./build -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} | ||
fi | ||
- name: Build | ||
working-directory: ${{ github.workspace }}/build | ||
run: ninja -j 10 | ||
|
||
- name: Upload RaftKeeper binary | ||
uses: actions/upload-artifact@v4 | ||
with: | ||
name: raftkeeper-binary-${{ inputs.sanitize}} | ||
path: build/programs/raftkeeper | ||
|
||
- name: Upload unit test binary | ||
uses: actions/upload-artifact@v4 | ||
with: | ||
name: unit-test-binary-${{ inputs.sanitize}} | ||
path: build/src/rk_unit_tests |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
name: Check Style | ||
|
||
on: # yamllint disable-line rule:truthy | ||
workflow_call: | ||
|
||
env: | ||
REPORT_DIR: /tmp/reports | ||
|
||
jobs: | ||
run: | ||
runs-on: ubuntu-22.04 | ||
steps: | ||
- uses: actions/checkout@v3 | ||
|
||
- name: Install tools | ||
run: sudo apt-get update && sudo apt install -y shellcheck libxml2-utils git python3-pip pylint yamllint && pip3 install codespell | ||
|
||
- name: Check style | ||
working-directory: ${{ github.workspace }}/tests/ci | ||
run: python3 code_style_check.py | tee style-report.log |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
import xml.etree.ElementTree as ET | ||
|
||
import os | ||
|
||
|
||
def generate_report(report_dir, report_title): | ||
print("report_dir:", report_dir) | ||
test_cases = {} | ||
|
||
# Iterate over all files in the directory | ||
for report_file in os.listdir(report_dir): | ||
print("report_file:", report_file) | ||
if report_file.endswith(('-none.xml', '-tsan.xml', '-msan.xml', '-asan.xml', '-ubsan.xml')): | ||
sanitize_type = report_file.split('-')[-1].split('.')[0] | ||
with open(os.path.join(report_dir, report_file), 'r') as file: | ||
xml_data = file.read() | ||
print("xml_data:", xml_data) | ||
root = ET.fromstring(xml_data) | ||
|
||
for testsuite in root.findall('testsuite'): | ||
for testcase in testsuite.findall('testcase'): | ||
# integration test classname is like test_auto.test, we only need the first part | ||
classname = testcase.get('classname').split('.')[0] | ||
name = testcase.get('name') | ||
failure = testcase.find('failure') | ||
status = '❌' if failure is not None else '✅' | ||
error_message = failure.get('message').replace('\n', '<br>') if failure is not None else '' | ||
|
||
print(f"test case: {classname} {name} {failure} {error_message} {status}") | ||
if (classname, name) not in test_cases: | ||
test_cases[(classname, name)] = [] | ||
|
||
test_cases[(classname, name)].append((sanitize_type, status, error_message)) | ||
|
||
header = "| Classname | Name | Sanitize Type | Status | Error Message |\n" | ||
header += "|---------------|----------------------------------------|---------------|--------|---------------|\n" | ||
|
||
successful_tests = [] | ||
failed_tests = [] | ||
|
||
for (classname, name), results in test_cases.items(): | ||
# If all of test case are passed or not passed, squash them into one row and set sanitize_type to '-' | ||
statuses = {status for _, status, _ in results} | ||
if len(statuses) == 1: | ||
status = statuses.pop() | ||
# If there's an error message, use it; otherwise, set it to an empty string | ||
error_message = next((error for _, _, error in results if error), '') | ||
row = f"| {classname} | {name} | | {status} | {error_message} |" | ||
if error_message != '': | ||
failed_tests.append(row) | ||
else: | ||
successful_tests.append(row) | ||
else: | ||
# Process normally if not squashed | ||
for sanitize_type, status, error_message in results: | ||
row = f"| {classname} | {name} | {sanitize_type} | {status} | {error_message} |" | ||
if error_message != '': | ||
failed_tests.append(row) | ||
else: | ||
successful_tests.append(row) | ||
|
||
failed_table = header + "\n".join(failed_tests) if failed_tests else "All test cases passed!" | ||
successful_table = header + "\n".join(successful_tests) if successful_tests else "" | ||
|
||
collapsible_successful_table = ( | ||
"<details>\n" | ||
"<summary>Successful Test Cases</summary>\n\n" | ||
+ successful_table + | ||
"\n</details>" | ||
) | ||
|
||
commit_id = os.environ['GITHUB_SHA'] | ||
print("commit_id:", commit_id) | ||
|
||
report = f"{report_title} for commit {commit_id}.\n\n{failed_table}\n\n{collapsible_successful_table}" | ||
return report |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
from github_utils import get_artifact_url | ||
import sys | ||
|
||
|
||
if __name__ == "__main__": | ||
get_artifact_url(sys.argv[1]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
import os | ||
import sys | ||
import json | ||
|
||
from github.Auth import AppAuth | ||
from github import Github | ||
|
||
|
||
app_id = "995720" | ||
installation_id = 54780428 | ||
|
||
private_key_part_1 = """-----BEGIN RSA PRIVATE KEY----- | ||
MIIEowIBAAKCAQEAyN+CJniZ5AXyAdcHmfwq0ltaaSLBahjsndlJxJY4zxS3ywxC | ||
""" | ||
|
||
private_key_part_2 = """ornAzDEKp4VtBf9EWIraMsCk1Ak9Wp0yICNngJ+Ch13173xk2nkRNBRYAnq+Ln+x | ||
3VetS7hNMkHrSRHZezapzMCki9C0E7a9ks2F3sMwj8rKKhCvspMWGDBTMan5pKkc | ||
YLlOhA27MF66SOIdDAqbi9m0pKeoNvaFaD5hRykYE+bDjnfTXSRWzPragEk5pbKl | ||
sROzSDHqNYDH1d3QK4D1Uk7uT5ZQnkQuWFfliLbSaqPk4NhRwQx4jCqbkQZ4HvPm | ||
8q8I5fql1gDwOxPr1eTLOU00C5x3wcwnFT+MXwIDAQABAoIBAC38FNRvyXMM9WD8 | ||
c+4Jb1gmt6TX4wVB3XEpXBzX8vtdF9Iw5VRRR9S26WR+Q/4aeO/4IYl61oD/+H60 | ||
+9Olpz0nxv7sQK/pf0EQdCLDAX7X0I/ehb5RIwfxkiKOOqnIn0v4sJiCBWlIhuD4 | ||
dZ+U0y+y6XwRhYRpu38a8vToozL7+WX/Wu656FK0H0huH53EazrxxD6JLpoIFErK | ||
ojU5vzPJUgTdWnMZAdlEOjcO0Qg/XwDlzmQFga5duIzkt9CcmlOwRoWsVBph6YP8 | ||
Qzz2sjHslzoLo0Nmc+HVZLE+uyKjeI5UFfPRu5c+rZgbwR27fDJY/O/JsFbV8wZm | ||
5u504TkCgYEA849asWpIiWWg4U00txtM1etNe450x9bo6LgQ2QtcJTk5OPGuxUt3 | ||
sX51upYHat8VbEuEiEe70QEUySwqOiK6ofLn8zr8tPmg0smy0zt1DJy/tPHQ4ubX | ||
A9DKMqYxHJPS4iRi5R7sOIjNFBfA2iUPEesQRPXAIMkIyevv6LBfg9UCgYEA0yIB | ||
bftBTJc1WDbaOU339GYm8rLjiDHyK9DAOC548m85Bm1b45EtMoB5e+0VY/C10eLy | ||
A2A7t7CpA9kLZRVlx4voQ21bTjEnO470GN6SfmhcLZ65WzvbZvLHj+zGjkV8+Lot | ||
Av02h6hnwfwQhvN9XsZPyNk4IdcXK7045DnGzWMCgYAcF5HHWtHo/w7STbxhzkVL | ||
eythr+mqTxBoHyraTeQf6vy9o6qb2PuCPmrHzZwnaHmpFwC/Uz7HeY9zMKPiNrU+ | ||
Dq1QMaKKISy6g0cb9ASpIr892JJWSXfNWdyogOCzQh2VtcquUKXAU48L3T2CK7oU | ||
P/+NZKb3YRihaZQvS4CIzQKBgQC6UsxILu/Vk6u0CdRTtgcYW/4LOOurichZ+oNo | ||
ETsTWCxPC7uH/NqSMucDAptZ81fBvjIt4INS/Ehr6OMxdcy4aTO0LZHiU2Z4HRQ1 | ||
zlYh0B9o8yZI6W4aUC7lSOOBMrmzFzoZ5TR2S5wliTlcnw0I0qIecfQjiRods4O9 | ||
hW94WQKBgHMxir/eMLR8z9hj1jpJh+eN3Uo6UM+5dzgqNUn4CJC2Tt6tIZPoxdhX | ||
MimMH9yrRcCe068VlvqN+AsTTpkpceJT52dV5iXuEm1DoYgvhvD19MMlW/QmOY8w | ||
5GHXzNf9wt2HkMZZcpCasMTfWW3LvtEomcA3USQbZt5NgX7QjAVo | ||
-----END RSA PRIVATE KEY-----""" | ||
|
||
private_key = private_key_part_1 + private_key_part_2 | ||
|
||
def comment_on_pr(content, title): | ||
print("content:", content) | ||
if content is None: | ||
raise Exception("Content is required") | ||
|
||
app_auth = AppAuth(app_id, private_key) | ||
g = Github(auth=app_auth.get_installation_auth(installation_id)) | ||
|
||
# Get the pull request number and repository details | ||
repo_name = os.environ['GITHUB_REPOSITORY'] | ||
print("repo_name:", repo_name) | ||
|
||
# Read the event payload | ||
with open(os.environ['GITHUB_EVENT_PATH'], 'r') as f: | ||
event_payload = json.load(f) | ||
|
||
# Extract the pull request number | ||
pull_request_number = event_payload['pull_request']['number'] | ||
print("pull_request_number:", pull_request_number) | ||
|
||
repo = g.get_repo(repo_name) | ||
pull_request = repo.get_pull(int(pull_request_number)) | ||
|
||
# Get all comments on the pull request | ||
comments = pull_request.get_issue_comments() | ||
|
||
# Check if a comment by raftkeepeer-robot[bot] exists | ||
comment_found = False | ||
for comment in comments: | ||
print("find comment:", comment) | ||
if comment.user.login == "raftkeepeer-robot[bot]" and title in comment.body: | ||
# Update the existing comment | ||
comment.edit(content) | ||
comment_found = True | ||
break | ||
|
||
# If not, create a new comment | ||
if not comment_found: | ||
pull_request.create_issue_comment(content) | ||
|
||
|
||
def get_artifact_url(artifact_name): | ||
# Authenticate with GitHub | ||
app_auth = AppAuth(app_id, private_key) | ||
g = Github(auth=app_auth.get_installation_auth(installation_id)) | ||
|
||
# Get the repository | ||
repo_name = os.environ['GITHUB_REPOSITORY'] | ||
repo = g.get_repo(repo_name) | ||
|
||
# Get the specific workflow run | ||
run_id = os.environ['GITHUB_RUN_ID'] | ||
print("run_id:", run_id) | ||
workflow_run = repo.get_workflow_run(int(run_id)) | ||
|
||
# List artifacts for the workflow run | ||
artifacts = workflow_run.get_artifacts() | ||
|
||
# Assuming you want the first artifact, get its download URL | ||
for artifact in artifacts: | ||
if artifact.name == artifact_name: | ||
return artifact.archive_download_url | ||
|
||
return None |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
name: Test | ||
|
||
on: # yamllint disable-line rule:truthy | ||
workflow_call: | ||
inputs: | ||
sanitize: | ||
required: true | ||
type: string | ||
|
||
jobs: | ||
run: | ||
runs-on: ubuntu-22.04 | ||
steps: | ||
- name: Checkout code | ||
uses: actions/checkout@v3 | ||
|
||
- name: Download binary | ||
uses: actions/download-artifact@v4 | ||
with: | ||
name: raftkeeper-binary-${{ inputs.sanitize }} | ||
path: build/programs/ | ||
|
||
- name: Add executable privileges | ||
run: sudo chmod 755 build/programs/raftkeeper | ||
|
||
- name: Run integration Tests | ||
run: bash .github/workflows/run-integration-test.sh tests/integration --junitxml=integration-test-report-${{ inputs.sanitize }}.xml | ||
|
||
- name: Upload test report | ||
if: always() | ||
uses: actions/upload-artifact@v4 | ||
with: | ||
name: integration-test-report-${{ inputs.sanitize }}.xml | ||
path: tests/integration/integration-test-report-${{ inputs.sanitize }}.xml |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
name: Build and Test macOS | ||
|
||
on: # yamllint disable-line rule:truthy | ||
workflow_call: | ||
|
||
jobs: | ||
run: | ||
runs-on: macos-13 | ||
steps: | ||
- uses: actions/checkout@v3 | ||
with: | ||
submodules: recursive | ||
|
||
- name: Install tools | ||
run: brew install ninja ccache cmake llvm@17 | ||
|
||
- name: Generate Makefile | ||
run: export CC=$(brew --prefix llvm@17)/bin/clang CXX=$(brew --prefix llvm@17)/bin/clang++ && cmake -G Ninja -B ./build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} | ||
|
||
- name: Build | ||
working-directory: ${{github.workspace}}/build | ||
run: ninja -j 10 | ||
|
||
- name: Run unit tests | ||
working-directory: ${{github.workspace}}/build | ||
run: ./src/rk_unit_tests --gtest_color=yes |
Oops, something went wrong.