ci: Add workflow that compares the compiled output between the PR and master (#3626)

Fixes #3063
This commit is contained in:
Tyler Wilding
2024-08-03 02:42:34 -04:00
committed by GitHub
parent 2e9b099d58
commit a13b0dce45
14 changed files with 170 additions and 38 deletions
@@ -0,0 +1,96 @@
name: Compilation Check
on:
pull_request:
branches:
- master
jobs:
build:
name: Compare
runs-on: ubuntu-20.04
timeout-minutes: 60
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
ref: master
- name: Install Package Dependencies
run: |
sudo apt update
sudo apt install build-essential cmake \
clang gcc g++ lcov make nasm libxrandr-dev \
libxinerama-dev libxcursor-dev libpulse-dev \
libxi-dev zip ninja-build libgl1-mesa-dev libssl-dev
- name: Setup sccache
uses: hendrikmuhs/ccache-action@v1.2.13
with:
variant: sccache
key: linux-ubuntu-20.04--Release-linux-clang-asan-${{ github.sha }}
restore-keys: linux-ubuntu-20.04--Release-linux-clang-asan
max-size: 1000M
- name: CMake Generation (master)
env:
CC: clang
CXX: clang++
run: |
cmake -B build --preset=Release-linux-clang-asan \
-DCMAKE_C_COMPILER_LAUNCHER=sccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=sccache
- name: Build goalc (master)
run: cmake --build build --parallel $((`nproc`)) --target goalc
- name: Compile and preserve (master)
run: |
./build/goalc/goalc --game jak1 --cmd "(make-group \"all-code\")"
./build/goalc/goalc --game jak2 --cmd "(make-group \"all-code\")"
./build/goalc/goalc --game jak3 --cmd "(make-group \"all-code\")"
mv ./out/jak1/obj ./out/jak1/obj.master
mv ./out/jak2/obj ./out/jak2/obj.master
mv ./out/jak3/obj ./out/jak3/obj.master
- name: Checkout PR
uses: actions/checkout@v4
with:
clean: "false"
- name: CMake Generation (PR)
env:
CC: clang
CXX: clang++
run: |
cmake -B build --preset=Release-linux-clang-asan \
-DCMAKE_C_COMPILER_LAUNCHER=sccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=sccache
- name: Build goalc (PR)
run: cmake --build build --parallel $((`nproc`)) --target goalc
- name: Compile and preserve (PR)
run: |
./build/goalc/goalc --game jak1 --cmd "(make-group \"all-code\")"
./build/goalc/goalc --game jak2 --cmd "(make-group \"all-code\")"
./build/goalc/goalc --game jak3 --cmd "(make-group \"all-code\")"
mv ./out/jak1/obj ./out/jak1/obj.pr
mv ./out/jak2/obj ./out/jak2/obj.pr
mv ./out/jak3/obj ./out/jak3/obj.pr
- name: Compare Results and Produce Report
run: |
ls -l ./out/jak1
ls -l ./out/jak2
ls -l ./out/jak3
set +e
python ./scripts/gsrc/compare-compilation-outputs.py --base "./out/jak1/obj.master,./out/jak2/obj.master,./out/jak3/obj.master" --compare "./out/jak1/obj.pr,./out/jak2/obj.pr,./out/jak3/obj.pr" --markdown
SCRIPT_EXIT_CODE=$?
cat ./comp-diff-report.md >> $GITHUB_STEP_SUMMARY
if [ "$SCRIPT_EXIT_CODE" -ne 0 ]; then
exit 1
fi
+2 -1
View File
@@ -32,6 +32,7 @@ linux-default/
*.bin
*.log
*.p2s
out/
savestate-out/
savestate_out/
failures/
@@ -39,6 +40,7 @@ ee-results*.json
search-results.json
.env
/search-results.json
comp-diff-report.md
# graphics debug
debug_out/
@@ -67,7 +69,6 @@ custom_assets/jak3/merc_replacements/*
svnrev.h
common/versions/revision.h
ci-artifacts/
out/build/
__pycache__/
# sqlite stuff
+15 -4
View File
@@ -8,6 +8,8 @@
#include "BinaryWriter.h"
#include "FileUtil.h"
#include "common/log/log.h"
void build_dgo(const DgoDescription& description, const std::string& output_prefix) {
BinaryWriter writer;
// dgo header
@@ -15,8 +17,14 @@ void build_dgo(const DgoDescription& description, const std::string& output_pref
writer.add_cstr_len(description.dgo_name.c_str(), 60);
for (auto& obj : description.entries) {
auto obj_data = file_util::read_binary_file(file_util::get_jak_project_dir() / "out" /
output_prefix / "obj" / obj.file_name);
// Ensure the directory exists
const auto file_path =
file_util::get_jak_project_dir() / "out" / output_prefix / "obj" / obj.file_name;
if (!file_util::file_exists(file_path.string())) {
lg::warn("tried to build a DGO with a file that doesn't exist: {}", file_path.string());
continue;
}
auto obj_data = file_util::read_binary_file(file_path);
// size
writer.add<uint32_t>(obj_data.size());
// name
@@ -29,6 +37,9 @@ void build_dgo(const DgoDescription& description, const std::string& output_pref
}
}
writer.write_to_file(file_util::get_jak_project_dir() / "out" / output_prefix / "iso" /
description.dgo_name);
// Ensure the output directory exists
const auto dgo_path =
file_util::get_jak_project_dir() / "out" / output_prefix / "iso" / description.dgo_name;
file_util::create_dir_if_needed_for_file(dgo_path);
writer.write_to_file(dgo_path);
}
-3
View File
@@ -1,3 +0,0 @@
*
!.gitignore
!hash.md5
-3
View File
@@ -1,3 +0,0 @@
*
!.gitignore
!hash.md5
-3
View File
@@ -1,3 +0,0 @@
*
!.gitignore
!hash.md5
-3
View File
@@ -1,3 +0,0 @@
*
!.gitignore
!hash.md5
-3
View File
@@ -1,3 +0,0 @@
*
!.gitignore
!hash.md5
-3
View File
@@ -1,3 +0,0 @@
*
!.gitignore
!hash.md5
-3
View File
@@ -1,3 +0,0 @@
*
!.gitignore
!hash.md5
-3
View File
@@ -1,3 +0,0 @@
*
!.gitignore
!hash.md5
-3
View File
@@ -1,3 +0,0 @@
*
!.gitignore
!hash.md5
+57 -5
View File
@@ -4,6 +4,19 @@
import os
import hashlib
import argparse
parser = argparse.ArgumentParser("compare-compilation-outputs")
parser.add_argument("--base", help="The base branch directories", type=str)
parser.add_argument("--compare", help="The potentially modified directories to compare", type=str)
parser.add_argument("--markdown", help="The format to output results as a markdown file './comp-diff-report.md'", action="store_true")
args = parser.parse_args()
to_markdown_file = False
if args.markdown:
to_markdown_file = True
markdown_lines = []
def hash_file(filepath):
"""Returns the MD5 hash of the file."""
@@ -19,8 +32,13 @@ def compare_directories(base_dir, compare_dir):
missing_files = []
# Iterate through files in the base directory
total_files = 0
for root, _, files in os.walk(base_dir):
for file in files:
if file == ".gitignore":
continue
total_files = total_files + 1
base_file_path = os.path.join(root, file)
relative_path = os.path.relpath(base_file_path, base_dir)
compare_file_path = os.path.join(compare_dir, relative_path)
@@ -34,20 +52,54 @@ def compare_directories(base_dir, compare_dir):
missing_files.append(relative_path)
# Report results
print(f'Comparing {base_dir} with {compare_dir}')
markdown_lines.append(f'### Comparing `{base_dir}` with `{compare_dir}`\n\n')
if not mismatched_files and not missing_files:
print("All files matched successfully.")
markdown_lines.append(f'All `{total_files}` files matched successfully ✅\n\n')
return 0
else:
markdown_lines.append(f'Found potential problems ❌\n')
markdown_lines.append(f'- {len(mismatched_files)} different file(s)\n')
markdown_lines.append(f'- {len(missing_files)} missing file(s)\n\n')
markdown_lines.append("| file | result |\n")
markdown_lines.append("|------|--------|\n")
if mismatched_files:
print("Mismatched files:")
markdown_printed_already = 0
for file in mismatched_files:
print(f" - {file}")
if markdown_printed_already < 25:
markdown_lines.append(f"| `{file}` | different |\n")
markdown_printed_already = markdown_printed_already + 1
if len(mismatched_files) > 25:
markdown_lines.append(f"| ...and {len(mismatched_files) - 25} other files | different |\n")
if missing_files:
print("Missing files:")
markdown_printed_already = 0
for file in missing_files:
print(f" - {file}")
if markdown_printed_already < 25:
markdown_lines.append(f"| `{file}` | missing |\n")
markdown_printed_already = markdown_printed_already + 1
if len(missing_files) > 25:
markdown_lines.append(f"| ...and {len(missing_files) - 25} other files | missing |\n")
markdown_lines.append("\n")
return 1
# Usage example
base_directory = './out/jak1/obj'
compare_directory = './out/jak1/obj_master'
print(f'Comparing {base_directory} with {compare_directory}')
compare_directories(base_directory, compare_directory)
print(f"base: {args.base}")
print(f"compare: {args.compare}")
base_directory_list = args.base.split(",")
compare_directory_list = args.compare.split(",")
result = 0
for base_dir, comp_dir in zip(base_directory_list, compare_directory_list):
latest_result = compare_directories(base_dir, comp_dir)
if latest_result != 0:
result = latest_result
if to_markdown_file:
with open('./comp-diff-report.md', 'w', encoding='utf-8') as md_file:
md_file.writelines(markdown_lines)
print("Wrote results to ./comp-diff-report.md")
exit(result)
-1
View File
@@ -276,4 +276,3 @@ for adjust in adjustments:
function_string += f" ((fequal-epsilon? aspect-ratio {aspect_ratio} 0.01) {value:.1f})\n"
function_string += f" (else\n (+ {coefficients[0]}\n (* {coefficients[1]} aspect-ratio)\n (* {coefficients[2]} aspect-ratio aspect-ratio)\n (* {coefficients[3]} aspect-ratio aspect-ratio aspect-ratio)))))\n"
print(function_string)