Create CODE_OF_CONDUCT.md #230
This file contains hidden or 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
| name: Jotai Benchmark Tests | |
| on: | |
| push: | |
| branches: | |
| - main | |
| - '*' | |
| - '*/*' | |
| - '*/*/*' | |
| - '*/*/*/*' | |
| pull_request: | |
| branches: | |
| - main | |
| - '*' | |
| - '*/*' | |
| - '*/*/*' | |
| - '*/*/*/*' | |
| workflow_dispatch: | |
| inputs: | |
| limit: | |
| description: "Number of benchmarks to test (20-30)" | |
| required: false | |
| default: "25" | |
| level: | |
| description: "Obfuscation level (1-5)" | |
| required: false | |
| default: "3" | |
| concurrency: | |
| group: jotai-tests-${{ github.ref }}-${{ github.event.pull_request.number || '' }} | |
| cancel-in-progress: true | |
| jobs: | |
| test-jotai: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| permissions: | |
| contents: read | |
| actions: read | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| lfs: false | |
| - name: Authenticate to Google Cloud | |
| uses: google-github-actions/auth@v2 | |
| with: | |
| credentials_json: ${{ secrets.GCP_SERVICE_ACCOUNT_KEY }} | |
| - name: Set up Cloud SDK | |
| uses: google-github-actions/setup-gcloud@v2 | |
| - name: Download LLVM binaries from GCP Cloud Storage | |
| id: download-binaries | |
| env: | |
| GCP_BUCKET: llvmbins | |
| run: | | |
| echo "==========================================" | |
| echo "Downloading LLVM binaries from GCP Cloud Storage" | |
| echo "==========================================" | |
| # Create target directory | |
| mkdir -p cmd/llvm-obfuscator/plugins/linux-x86_64 | |
| # Download all individual files from GCP bucket | |
| echo "Downloading individual binaries from gs://${GCP_BUCKET}/linux-x86_64/..." | |
| gsutil -m cp -r "gs://${GCP_BUCKET}/linux-x86_64/*" cmd/llvm-obfuscator/plugins/linux-x86_64/ || { | |
| echo "❌ ERROR: Failed to download binaries from GCP Cloud Storage" | |
| echo "" | |
| echo "Bucket: ${GCP_BUCKET}" | |
| echo "Path: linux-x86_64/" | |
| echo "" | |
| echo "To fix:" | |
| echo " 1. Ensure individual binaries are uploaded to gs://${GCP_BUCKET}/linux-x86_64/" | |
| echo " 2. Required files: clang, opt, LLVMObfuscationPlugin.so, libLLVM.so.22.0git, mlir-opt, mlir-translate, clangir, MLIRObfuscation.so" | |
| echo " 3. Also ensure lib/clang/22/include/ directory is uploaded" | |
| echo "" | |
| exit 1 | |
| } | |
| # Make binaries executable | |
| chmod +x cmd/llvm-obfuscator/plugins/linux-x86_64/clang || true | |
| chmod +x cmd/llvm-obfuscator/plugins/linux-x86_64/opt || true | |
| chmod +x cmd/llvm-obfuscator/plugins/linux-x86_64/mlir-opt || true | |
| chmod +x cmd/llvm-obfuscator/plugins/linux-x86_64/mlir-translate || true | |
| chmod +x cmd/llvm-obfuscator/plugins/linux-x86_64/clangir || true | |
| chmod +x cmd/llvm-obfuscator/plugins/linux-x86_64/lld || true | |
| # Create ld.lld symlink (clang looks for ld.lld when using -fuse-ld=lld) | |
| if [ -f "cmd/llvm-obfuscator/plugins/linux-x86_64/lld" ]; then | |
| ln -sf lld cmd/llvm-obfuscator/plugins/linux-x86_64/ld.lld | |
| echo "✅ Created ld.lld symlink" | |
| fi | |
| # Fix incomplete bundled headers by copying missing files from system clang | |
| # These headers are required for LTO compilation to work correctly | |
| INCLUDE_DIR="cmd/llvm-obfuscator/plugins/linux-x86_64/lib/clang/22/include" | |
| if [ -d "$INCLUDE_DIR" ]; then | |
| cp /usr/lib/llvm-*/lib/clang/*/include/__stddef_header_macro.h "$INCLUDE_DIR/" 2>/dev/null || true | |
| cp /usr/lib/llvm-*/lib/clang/*/include/__float_header_macro.h "$INCLUDE_DIR/" 2>/dev/null || true | |
| echo "✅ Copied missing header files from system clang" | |
| fi | |
| echo "✅ Binaries downloaded successfully" | |
| ls -lh cmd/llvm-obfuscator/plugins/linux-x86_64/ | |
| - name: Verify binaries are present (REQUIRED) | |
| run: | | |
| echo "==========================================" | |
| echo "Verifying custom LLVM binaries (REQUIRED)" | |
| echo "==========================================" | |
| echo "" | |
| MISSING_BINARIES=0 | |
| # Check if binaries exist and are actual files | |
| if [ ! -f "cmd/llvm-obfuscator/plugins/linux-x86_64/clang" ] || \ | |
| ! file cmd/llvm-obfuscator/plugins/linux-x86_64/clang | grep -q "ELF"; then | |
| echo "❌ ERROR: clang binary missing or invalid" | |
| echo " Run the 'Store LLVM Binaries as Artifacts' workflow first" | |
| MISSING_BINARIES=1 | |
| else | |
| echo "✅ Custom clang binary verified" | |
| fi | |
| if [ ! -f "cmd/llvm-obfuscator/plugins/linux-x86_64/opt" ] || \ | |
| ! file cmd/llvm-obfuscator/plugins/linux-x86_64/opt | grep -q "ELF"; then | |
| echo "❌ ERROR: opt binary missing or invalid" | |
| echo " Run the 'Store LLVM Binaries as Artifacts' workflow first" | |
| MISSING_BINARIES=1 | |
| else | |
| echo "✅ Custom opt binary verified" | |
| fi | |
| # Check mlir-opt (required for MLIR obfuscation passes) | |
| if [ ! -f "cmd/llvm-obfuscator/plugins/linux-x86_64/mlir-opt" ] || \ | |
| ! file cmd/llvm-obfuscator/plugins/linux-x86_64/mlir-opt | grep -q "ELF"; then | |
| echo "❌ ERROR: mlir-opt binary missing or invalid" | |
| echo " Run the 'Store LLVM Binaries as Artifacts' workflow first" | |
| MISSING_BINARIES=1 | |
| else | |
| echo "✅ Custom mlir-opt binary verified" | |
| fi | |
| # Check mlir-translate (required for MLIR lowering) | |
| if [ ! -f "cmd/llvm-obfuscator/plugins/linux-x86_64/mlir-translate" ] || \ | |
| ! file cmd/llvm-obfuscator/plugins/linux-x86_64/mlir-translate | grep -q "ELF"; then | |
| echo "❌ ERROR: mlir-translate binary missing or invalid" | |
| echo " Run the 'Store LLVM Binaries as Artifacts' workflow first" | |
| MISSING_BINARIES=1 | |
| else | |
| echo "✅ Custom mlir-translate binary verified" | |
| fi | |
| if [ $MISSING_BINARIES -eq 1 ]; then | |
| echo "" | |
| echo "❌ ERROR: Required custom LLVM binaries are missing" | |
| echo "" | |
| echo "To fix:" | |
| echo " 1. Go to Actions → 'Store LLVM Binaries in GCP Cloud Storage'" | |
| echo " 2. Run the workflow manually with a version (e.g., v1.0.0)" | |
| echo " 3. This will upload binaries to GCP Cloud Storage" | |
| exit 1 | |
| fi | |
| echo "✅ All required binaries verified" | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.10" | |
| - name: Install system dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y clang git | |
| - name: Install Python dependencies | |
| working-directory: cmd/llvm-obfuscator | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -r requirements.txt | |
| - name: Set up LLVM toolchain environment | |
| run: | | |
| echo "==========================================" | |
| echo "Setting up LLVM toolchain environment" | |
| echo "==========================================" | |
| BIN_DIR="$PWD/cmd/llvm-obfuscator/plugins/linux-x86_64" | |
| # Verify binaries are accessible | |
| echo "Verifying toolchain binaries..." | |
| ls -lh "$BIN_DIR" | grep -E "(clang|opt|mlir-opt|mlir-translate)" || true | |
| # Add binaries to PATH (this will be available in subsequent steps) | |
| echo "$BIN_DIR" >> $GITHUB_PATH | |
| # Set LD_LIBRARY_PATH for shared libraries (if libLLVM.so exists in the same directory) | |
| if [ -f "$BIN_DIR/libLLVM.so.22.0git" ] || [ -f "$BIN_DIR/libLLVM.so" ]; then | |
| echo "LD_LIBRARY_PATH=$BIN_DIR" >> $GITHUB_ENV | |
| echo "✅ LD_LIBRARY_PATH set to $BIN_DIR" | |
| fi | |
| # Verify mlir-opt is accessible (using full path since PATH update happens in next step) | |
| echo "" | |
| echo "Verifying mlir-opt binary..." | |
| if [ -x "$BIN_DIR/mlir-opt" ]; then | |
| echo "✅ mlir-opt binary is executable" | |
| "$BIN_DIR/mlir-opt" --version | head -1 || echo "⚠️ mlir-opt version check failed" | |
| else | |
| echo "❌ ERROR: mlir-opt not found or not executable at $BIN_DIR/mlir-opt" | |
| exit 1 | |
| fi | |
| echo "✅ LLVM toolchain environment configured" | |
| - name: Run Jotai CI Tests | |
| working-directory: cmd/llvm-obfuscator | |
| env: | |
| INPUT_LIMIT: ${{ github.event.inputs.limit }} | |
| LEVEL: ${{ github.event.inputs.level || '3' }} | |
| RANDOM_SEED: ${{ github.run_number }} | |
| run: | | |
| echo "==========================================" | |
| echo "Computing test parameters..." | |
| echo "==========================================" | |
| # If user gave a limit (workflow_dispatch), use it. | |
| # Otherwise generate limit = (run_number % 11) + 20 | |
| if [ -z "$INPUT_LIMIT" ]; then | |
| RANDOM_LIMIT=$(( (RANDOM_SEED % 11) + 20 )) | |
| else | |
| RANDOM_LIMIT="$INPUT_LIMIT" | |
| fi | |
| echo "Benchmark limit: $RANDOM_LIMIT" | |
| echo "Obfuscation level: $LEVEL" | |
| echo "Random seed: $RANDOM_SEED" | |
| echo "" | |
| echo "==========================================" | |
| echo "Executing Jotai Benchmark Test Workflow:" | |
| echo " 1. Get C source files from Jotai" | |
| echo " 2. Compile baseline binaries" | |
| echo " 3. Apply LLVM obfuscation" | |
| echo " 4. Run baseline vs obfuscated" | |
| echo " 5. Validate functional equivalence" | |
| echo " 6. Hello world" | |
| echo "==========================================" | |
| echo "" | |
| python3 tests/test_jotai_ci.py \ | |
| --limit "$RANDOM_LIMIT" \ | |
| --level "$LEVEL" \ | |
| --min-success-rate 0.6 \ | |
| --random-seed "$RANDOM_SEED" \ | |
| --output ./jotai_ci_results \ | |
| --json-report ./jotai_ci_summary.json | |
| - name: Upload test results | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: jotai-test-results | |
| path: | | |
| cmd/llvm-obfuscator/jotai_ci_results/** | |
| cmd/llvm-obfuscator/jotai_ci_summary.json | |
| retention-days: 7 | |
| - name: Display summary | |
| if: always() | |
| working-directory: cmd/llvm-obfuscator | |
| run: | | |
| if [ -f jotai_ci_summary.json ]; then | |
| echo "## Jotai Test Summary" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| python3 << 'PYEOF' >> $GITHUB_STEP_SUMMARY | |
| import json | |
| with open("jotai_ci_summary.json") as f: | |
| data = json.load(f) | |
| s = data["summary"] | |
| print(f"- **Total benchmarks:** {s['total_benchmarks']}") | |
| print(f"- **Tested:** {s['tested']}") | |
| print(f"- **Skipped:** {s['skipped']}") | |
| print(f"- **Success rate:** {s['success_rate']*100:.1f}%") | |
| print(f"- **Functional tests passed:** {s['functional_success']}/{s['tested']}") | |
| PYEOF | |
| fi |