Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions .github/actions/validate-pr/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: Validate PR
description: Ensure only authorized users can modify workflow files in PRs
inputs:
base_sha:
description: Base commit SHA of the pull request
required: true
head_sha:
description: Head commit SHA of the pull request
required: true
author:
description: Login of the PR author
required: true
pr_state:
description: State of the pull request (open/closed)
required: true
runs:
using: composite
steps:
- name: Check workflow file changes
shell: bash
run: |
if git diff --name-only "${{ inputs.base_sha }}" "${{ inputs.head_sha }}" | grep -q "^.github/workflows/"; then
echo "Workflow changes detected."
AUTHOR="${{ inputs.author }}"
if [[ "$AUTHOR" == "misrasaurabh1" || "$AUTHOR" == "KRRT7" ]]; then
echo "Authorized user ($AUTHOR). Proceeding."
elif [[ "${{ inputs.pr_state }}" == "open" ]]; then
echo "PR is open. Protection rules in place. Proceeding."
else
echo "Unauthorized user ($AUTHOR). Exiting."
exit 1
fi
else
echo "No workflow file changes. Proceeding."
fi
141 changes: 63 additions & 78 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -61,26 +61,39 @@ jobs:
fi
}

# Unit tests: code + test infra + java + packages + build config
# Unit tests: code + test infra + packages + build config
check_paths unit_tests \
'codeflash/' 'codeflash-benchmark/' 'codeflash-java-runtime/' \
'codeflash/' 'codeflash-benchmark/' \
'tests/' 'packages/' 'pyproject.toml' 'uv.lock'

# Type checking: code + build config + mypy config
check_paths type_check \
'codeflash/' 'pyproject.toml' 'uv.lock' 'mypy_allowlist.txt'

# E2E tests: code + tests + build config
# E2E tests: Python pipeline + tests + build config (excludes java/ and javascript/)
check_paths e2e \
'codeflash/' 'tests/' 'pyproject.toml' 'uv.lock'

# JS E2E tests: JS packages changed
'codeflash/*.py' \
'codeflash/api/' 'codeflash/benchmarking/' 'codeflash/cli_cmds/' \
'codeflash/code_utils/' 'codeflash/discovery/' 'codeflash/github/' \
'codeflash/languages/python/' 'codeflash/languages/*.py' \
'codeflash/lsp/' 'codeflash/models/' 'codeflash/optimization/' \
'codeflash/picklepatch/' 'codeflash/result/' 'codeflash/setup/' \
'codeflash/telemetry/' 'codeflash/tracing/' 'codeflash/verification/' \
'tests/' 'pyproject.toml' 'uv.lock'

# JS E2E tests: JS language support + shared pipeline + packages
check_paths e2e_js \
'packages/'
'codeflash/languages/javascript/' 'codeflash/languages/base.py' \
'codeflash/languages/registry.py' 'codeflash/optimization/' \
'codeflash/verification/' 'packages/' \
'tests/scripts/end_to_end_test_js*'

# Java E2E tests: java runtime or java test fixtures changed
# Java E2E tests: Java language support + shared pipeline + runtime
check_paths e2e_java \
'codeflash-java-runtime/' 'code_to_optimize/java/'
'codeflash/languages/java/' 'codeflash/languages/base.py' \
'codeflash/languages/registry.py' 'codeflash/optimization/' \
'codeflash/verification/' 'codeflash-java-runtime/' \
'code_to_optimize/java/' 'tests/scripts/end_to_end_test_java*'
env:
MERGE_BASE: ${{ steps.merge_base.outputs.sha }}

Expand Down Expand Up @@ -108,29 +121,15 @@ jobs:
python-version: "3.14"
- os: windows-latest
python-version: "3.13"
continue-on-error: true
runs-on: ${{ matrix.os }}
env:
PYTHONIOENCODING: utf-8
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-depth: 1
token: ${{ secrets.GITHUB_TOKEN }}

- name: Set up JDK 11
uses: actions/setup-java@v4
with:
java-version: '11'
distribution: 'temurin'
cache: maven

- name: Build codeflash-runtime JAR
run: |
cd codeflash-java-runtime
mvn clean package -q -DskipTests
mvn install -q -DskipTests

- name: Install uv
uses: astral-sh/setup-uv@v8.0.0
with:
Expand All @@ -156,7 +155,7 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-depth: 1
token: ${{ secrets.GITHUB_TOKEN }}

- name: Install uv
Expand All @@ -180,14 +179,32 @@ jobs:
&& (needs.determine-changes.outputs.e2e == 'true'
|| needs.determine-changes.outputs.e2e_js == 'true')
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.head_ref }}
fetch-depth: 0
- uses: astral-sh/setup-uv@v8.0.0

- name: Auto-fix formatting
run: |
uv run ruff check --fix . || true
uv run ruff format .

- name: Commit and push fixes
run: |
git diff --quiet && exit 0
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add -u
git commit -m "style: auto-format with ruff"
git push

- uses: j178/prek-action@v1
with:
extra-args: '--from-ref origin/${{ github.base_ref }} --to-ref ${{ github.sha }}'
extra-args: '--from-ref origin/${{ github.base_ref }} --to-ref HEAD'

# ---------------------------------------------------------------------------
# E2E tests — only on pull_request and workflow_dispatch (not push to main)
Expand Down Expand Up @@ -231,7 +248,6 @@ jobs:
- name: init-optimization
script: end_to_end_test_init_optimization.py
expected_improvement: 10
name: ${{ matrix.name }}
environment: ${{ (github.event_name == 'workflow_dispatch' || (contains(toJSON(github.event.pull_request.files.*.filename), '.github/workflows/') && github.event.pull_request.user.login != 'misrasaurabh1' && github.event.pull_request.user.login != 'KRRT7')) && 'external-trusted-contributors' || '' }}
runs-on: ubuntu-latest
env:
Expand All @@ -251,21 +267,12 @@ jobs:

- name: Validate PR
if: github.event_name == 'pull_request'
run: |
if git diff --name-only "${{ github.event.pull_request.base.sha }}" "${{ github.event.pull_request.head.sha }}" | grep -q "^.github/workflows/"; then
echo "Workflow changes detected."
AUTHOR="${{ github.event.pull_request.user.login }}"
if [[ "$AUTHOR" == "misrasaurabh1" || "$AUTHOR" == "KRRT7" ]]; then
echo "Authorized user ($AUTHOR). Proceeding."
elif [[ "${{ github.event.pull_request.state }}" == "open" ]]; then
echo "PR is open. Protection rules in place. Proceeding."
else
echo "Unauthorized user ($AUTHOR). Exiting."
exit 1
fi
else
echo "No workflow file changes. Proceeding."
fi
uses: ./.github/actions/validate-pr
with:
base_sha: ${{ github.event.pull_request.base.sha }}
head_sha: ${{ github.event.pull_request.head.sha }}
author: ${{ github.event.pull_request.user.login }}
pr_state: ${{ github.event.pull_request.state }}

- name: Install uv
uses: astral-sh/setup-uv@v8.0.0
Expand Down Expand Up @@ -309,8 +316,7 @@ jobs:
e2e-js:
needs: determine-changes
if: >-
(needs.determine-changes.outputs.e2e == 'true'
|| needs.determine-changes.outputs.e2e_js == 'true')
needs.determine-changes.outputs.e2e_js == 'true'
&& github.event_name != 'push'
strategy:
fail-fast: false
Expand All @@ -328,7 +334,6 @@ jobs:
script: end_to_end_test_js_ts_class.py
js_project_dir: code_to_optimize/js/code_to_optimize_ts
expected_improvement: 30
name: ${{ matrix.name }}
environment: ${{ (github.event_name == 'workflow_dispatch' || (contains(toJSON(github.event.pull_request.files.*.filename), '.github/workflows/') && github.event.pull_request.user.login != 'misrasaurabh1' && github.event.pull_request.user.login != 'KRRT7')) && 'external-trusted-contributors' || '' }}
runs-on: ubuntu-latest
env:
Expand All @@ -350,21 +355,12 @@ jobs:

- name: Validate PR
if: github.event_name == 'pull_request'
run: |
if git diff --name-only "${{ github.event.pull_request.base.sha }}" "${{ github.event.pull_request.head.sha }}" | grep -q "^.github/workflows/"; then
echo "Workflow changes detected."
AUTHOR="${{ github.event.pull_request.user.login }}"
if [[ "$AUTHOR" == "misrasaurabh1" || "$AUTHOR" == "KRRT7" ]]; then
echo "Authorized user ($AUTHOR). Proceeding."
elif [[ "${{ github.event.pull_request.state }}" == "open" ]]; then
echo "PR is open. Protection rules in place. Proceeding."
else
echo "Unauthorized user ($AUTHOR). Exiting."
exit 1
fi
else
echo "No workflow file changes. Proceeding."
fi
uses: ./.github/actions/validate-pr
with:
base_sha: ${{ github.event.pull_request.base.sha }}
head_sha: ${{ github.event.pull_request.head.sha }}
author: ${{ github.event.pull_request.user.login }}
pr_state: ${{ github.event.pull_request.state }}

- name: Set up Node.js
uses: actions/setup-node@v4
Expand Down Expand Up @@ -396,8 +392,7 @@ jobs:
e2e-java:
needs: determine-changes
if: >-
(needs.determine-changes.outputs.e2e == 'true'
|| needs.determine-changes.outputs.e2e_java == 'true')
needs.determine-changes.outputs.e2e_java == 'true'
&& github.event_name != 'push'
strategy:
fail-fast: false
Expand All @@ -414,7 +409,6 @@ jobs:
script: end_to_end_test_java_void_optimization.py
expected_improvement: 70
remove_git: true
name: ${{ matrix.name }}
environment: ${{ (github.event_name == 'workflow_dispatch' || (contains(toJSON(github.event.pull_request.files.*.filename), '.github/workflows/') && github.event.pull_request.user.login != 'misrasaurabh1' && github.event.pull_request.user.login != 'KRRT7')) && 'external-trusted-contributors' || '' }}
runs-on: ubuntu-latest
env:
Expand All @@ -436,21 +430,12 @@ jobs:

- name: Validate PR
if: github.event_name == 'pull_request'
run: |
if git diff --name-only "${{ github.event.pull_request.base.sha }}" "${{ github.event.pull_request.head.sha }}" | grep -q "^.github/workflows/"; then
echo "Workflow changes detected."
AUTHOR="${{ github.event.pull_request.user.login }}"
if [[ "$AUTHOR" == "misrasaurabh1" || "$AUTHOR" == "KRRT7" ]]; then
echo "Authorized user ($AUTHOR). Proceeding."
elif [[ "${{ github.event.pull_request.state }}" == "open" ]]; then
echo "PR is open. Protection rules in place. Proceeding."
else
echo "Unauthorized user ($AUTHOR). Exiting."
exit 1
fi
else
echo "No workflow file changes. Proceeding."
fi
uses: ./.github/actions/validate-pr
with:
base_sha: ${{ github.event.pull_request.base.sha }}
head_sha: ${{ github.event.pull_request.head.sha }}
author: ${{ github.event.pull_request.user.login }}
pr_state: ${{ github.event.pull_request.state }}

- name: Set up JDK 11
uses: actions/setup-java@v4
Expand Down
2 changes: 1 addition & 1 deletion codeflash-benchmark/codeflash_benchmark/version.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# These version placeholders will be replaced by uv-dynamic-versioning during build.
__version__ = "0.20.1.post242.dev0+7c7eeb5b"
__version__ = "0.20.5.post146.dev0+5ff38597"
12 changes: 9 additions & 3 deletions tests/test_languages/test_java/test_comparator.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,18 @@

import pytest

from codeflash.languages.java.comparator import compare_invocations_directly, compare_test_results, values_equal
from codeflash.languages.java.comparator import (
_find_comparator_jar,
compare_invocations_directly,
compare_test_results,
values_equal,
)
from codeflash.models.models import TestDiffScope

# Skip tests that require Java runtime if Java is not available
# Skip tests that require the codeflash-runtime JAR (built by Maven from codeflash-java-runtime/)
requires_java = pytest.mark.skipif(
shutil.which("java") is None, reason="Java not found - skipping Comparator integration tests"
_find_comparator_jar() is None,
reason="codeflash-runtime JAR not found - skipping Comparator integration tests",
)

# Kryo-serialized bytes for common test values.
Expand Down
10 changes: 10 additions & 0 deletions tests/test_languages/test_java/test_run_and_parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@

import pytest

from codeflash.languages.java.comparator import _find_comparator_jar

requires_java_runtime = pytest.mark.skipif(
_find_comparator_jar() is None,
reason="codeflash-runtime JAR not found - skipping Java integration tests",
)

from codeflash.discovery.functions_to_optimize import FunctionToOptimize
from codeflash.languages.base import Language
from codeflash.languages.current import set_current_language
Expand Down Expand Up @@ -227,6 +234,7 @@ def _create_test_results_db(path: Path, results: list[dict]) -> None:
"""


@requires_java_runtime
class TestJavaRunAndParseBehavior:
def test_behavior_single_test_method(self, java_project):
"""Full pipeline: instrument → run → parse with precise field assertions."""
Expand Down Expand Up @@ -369,6 +377,7 @@ def test_behavior_multiple_test_methods(self, java_project):
assert "testAddPositive" in test_names
assert "testAddZero" in test_names

@requires_java_runtime
def test_behavior_return_value_correctness(self, tmp_path):
"""Verify the Comparator JAR correctly identifies equivalent vs. differing results.

Expand Down Expand Up @@ -405,6 +414,7 @@ def test_behavior_return_value_correctness(self, tmp_path):
assert equivalent is False


@requires_java_runtime
class TestJavaRunAndParsePerformance:
"""Tests that the performance instrumentation produces correct timing data.

Expand Down
Loading