perf: prefilter files by path before read_text() in discovery #352
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: CI | |
| on: | |
| push: | |
| branches: [main] | |
| paths: | |
| - 'codeflash/**' | |
| - 'codeflash-benchmark/**' | |
| - 'codeflash-java-runtime/**' | |
| - 'tests/**' | |
| - 'packages/**' | |
| - 'pyproject.toml' | |
| - 'uv.lock' | |
| - 'mypy_allowlist.txt' | |
| - '.github/workflows/ci.yaml' | |
| - '.github/actions/**' | |
| pull_request: | |
| workflow_dispatch: | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref_name }} | |
| cancel-in-progress: true | |
| jobs: | |
| # --------------------------------------------------------------------------- | |
| # Linked issue check — every PR must reference an issue or discussion. | |
| # Skipped on push to main and workflow_dispatch. | |
| # --------------------------------------------------------------------------- | |
| check-linked-issue: | |
| if: github.event_name == 'pull_request' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| pull-requests: read | |
| steps: | |
| - name: Check PR body for linked issue or discussion | |
| env: | |
| PR_BODY: ${{ github.event.pull_request.body }} | |
| PR_AUTHOR: ${{ github.event.pull_request.user.login }} | |
| AUTHOR_ASSOCIATION: ${{ github.event.pull_request.author_association }} | |
| run: | | |
| # Skip for bots (dependabot, renovate, github-actions) | |
| if [[ "$PR_AUTHOR" == *"[bot]"* || "$PR_AUTHOR" == "dependabot" ]]; then | |
| echo "Bot PR — skipping linked issue check." | |
| exit 0 | |
| fi | |
| # Skip for org members and collaborators | |
| if [[ "$AUTHOR_ASSOCIATION" == "MEMBER" || "$AUTHOR_ASSOCIATION" == "COLLABORATOR" || "$AUTHOR_ASSOCIATION" == "OWNER" ]]; then | |
| echo "Org member ($PR_AUTHOR, $AUTHOR_ASSOCIATION) — skipping linked issue check." | |
| exit 0 | |
| fi | |
| if [ -z "$PR_BODY" ]; then | |
| echo "::error::PR body is empty. Every PR must link an issue or discussion." | |
| echo "Use 'Closes #<number>', 'Fixes #<number>', 'Relates to #<number>', or include a discussion URL." | |
| exit 1 | |
| fi | |
| # Match: #123, GH-123, org/repo#123, Closes/Fixes/Relates/Resolves #123, | |
| # or a github.com URL to an issue or discussion | |
| if echo "$PR_BODY" | grep -qiP '(close[sd]?|fix(e[sd])?|relate[sd]?\s+to|resolve[sd]?)\s+#\d+'; then | |
| echo "Found linked issue keyword." | |
| exit 0 | |
| fi | |
| if echo "$PR_BODY" | grep -qP '#\d+'; then | |
| echo "Found issue reference." | |
| exit 0 | |
| fi | |
| if echo "$PR_BODY" | grep -qiP 'github\.com/[^\s]+/(issues|discussions)/\d+'; then | |
| echo "Found GitHub issue/discussion URL." | |
| exit 0 | |
| fi | |
| if echo "$PR_BODY" | grep -qiP 'CF-#?\d+'; then | |
| echo "Found Linear ticket reference." | |
| exit 0 | |
| fi | |
| echo "::error::No linked issue or discussion found in PR body." | |
| echo "Every PR must reference an issue or discussion. See CONTRIBUTING.md for details." | |
| echo "Use 'Closes #<number>', 'Fixes #<number>', 'Relates to #<number>', or include a discussion URL." | |
| exit 1 | |
| # --------------------------------------------------------------------------- | |
| # Change detection — decides which downstream jobs actually run. | |
| # On push/workflow_dispatch every flag is true so all jobs execute. | |
| # On pull_request we diff against the merge base. | |
| # --------------------------------------------------------------------------- | |
| determine-changes: | |
| uses: codeflash-ai/github-workflows/.github/workflows/determine-changes.yml@main | |
| with: | |
| path-filters: | | |
| { | |
| "unit_tests": ["codeflash/", "codeflash-benchmark/", "tests/", "packages/", "pyproject.toml", "uv.lock"], | |
| "type_check": ["codeflash/", "pyproject.toml", "uv.lock", "mypy_allowlist.txt"], | |
| "e2e": ["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"], | |
| "e2e_js": ["codeflash/languages/javascript/", "codeflash/languages/base.py", "codeflash/languages/registry.py", "codeflash/optimization/", "codeflash/verification/", "packages/", "code_to_optimize/js/", "tests/scripts/end_to_end_test_js*"], | |
| "e2e_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*", "tests/test_languages/fixtures/java_tracer_e2e/"] | |
| } | |
| # --------------------------------------------------------------------------- | |
| # Unit tests — 6 Linux + 1 Windows matrix | |
| # --------------------------------------------------------------------------- | |
| unit-tests: | |
| needs: determine-changes | |
| if: fromJSON(needs.determine-changes.outputs.flags).unit_tests == 'true' | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - os: ubuntu-latest | |
| python-version: "3.9" | |
| - os: ubuntu-latest | |
| python-version: "3.10" | |
| - os: ubuntu-latest | |
| python-version: "3.11" | |
| - os: ubuntu-latest | |
| python-version: "3.12" | |
| - os: ubuntu-latest | |
| python-version: "3.13" | |
| - os: ubuntu-latest | |
| python-version: "3.14" | |
| - os: windows-latest | |
| python-version: "3.13" | |
| runs-on: ${{ matrix.os }} | |
| env: | |
| PYTHONIOENCODING: utf-8 | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 1 | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v8.1.0 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| enable-cache: true | |
| - name: Install dependencies | |
| shell: bash | |
| run: | | |
| if [[ "${{ matrix.python-version }}" == "3.9" || "${{ matrix.python-version }}" == "3.13" ]]; then | |
| uv sync --group tests | |
| else | |
| uv sync | |
| fi | |
| - name: Unit tests | |
| run: uv run pytest tests/ | |
| # --------------------------------------------------------------------------- | |
| # Coverage — single run on ubuntu/py3.13 to enforce the coverage floor. | |
| # --------------------------------------------------------------------------- | |
| coverage: | |
| needs: determine-changes | |
| if: fromJSON(needs.determine-changes.outputs.flags).unit_tests == 'true' | |
| runs-on: ubuntu-latest | |
| env: | |
| PYTHONIOENCODING: utf-8 | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 1 | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v8.1.0 | |
| with: | |
| python-version: "3.13" | |
| enable-cache: true | |
| - name: Install dependencies | |
| run: uv sync | |
| - name: Run tests with coverage | |
| run: uv run pytest tests/ --ignore=tests/test_tracer.py --cov=codeflash --cov-report=xml:coverage.xml --cov-report=term-missing --cov-config=.coveragerc | |
| - name: Check coverage floor | |
| run: uv run coverage report --fail-under=58 | |
| - name: Upload coverage report | |
| if: always() | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: coverage-report | |
| path: coverage.xml | |
| retention-days: 30 | |
| # --------------------------------------------------------------------------- | |
| # Mypy type checking | |
| # --------------------------------------------------------------------------- | |
| type-check: | |
| needs: determine-changes | |
| if: fromJSON(needs.determine-changes.outputs.flags).type_check == 'true' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 1 | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v8.1.0 | |
| with: | |
| enable-cache: true | |
| - name: Install dependencies | |
| run: uv sync | |
| - name: Run mypy | |
| run: uv run mypy --non-interactive --config-file pyproject.toml @mypy_allowlist.txt | |
| # --------------------------------------------------------------------------- | |
| # Lint (prek) — pull_request only | |
| # --------------------------------------------------------------------------- | |
| prek: | |
| needs: determine-changes | |
| if: >- | |
| github.event_name == 'pull_request' | |
| && (fromJSON(needs.determine-changes.outputs.flags).e2e == 'true' | |
| || fromJSON(needs.determine-changes.outputs.flags).e2e_js == 'true') | |
| uses: codeflash-ai/github-workflows/.github/workflows/prek-lint.yml@main | |
| permissions: | |
| contents: write | |
| with: | |
| auto-fix: true | |
| checkout-ref: ${{ github.head_ref }} | |
| restore-paths: "codeflash/version.py codeflash-benchmark/codeflash_benchmark/version.py" | |
| # --------------------------------------------------------------------------- | |
| # E2E tests — only on pull_request and workflow_dispatch (not push to main) | |
| # --------------------------------------------------------------------------- | |
| # --- Standard Python E2Es (9 tests) --- | |
| e2e-python: | |
| needs: determine-changes | |
| if: >- | |
| fromJSON(needs.determine-changes.outputs.flags).e2e == 'true' | |
| && github.event_name != 'push' | |
| && github.actor != 'dependabot[bot]' | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - name: tracer-replay | |
| script: end_to_end_test_tracer_replay.py | |
| expected_improvement: 10 | |
| - name: bubble-sort-pytest-nogit | |
| script: end_to_end_test_bubblesort_pytest.py | |
| expected_improvement: 70 | |
| remove_git: true | |
| - name: bubble-sort-unittest | |
| script: end_to_end_test_bubblesort_unittest.py | |
| expected_improvement: 40 | |
| - name: futurehouse-structure | |
| script: end_to_end_test_futurehouse.py | |
| expected_improvement: 5 | |
| - name: topological-sort | |
| script: end_to_end_test_topological_sort_worktree.py | |
| expected_improvement: 5 | |
| - name: async-optimization | |
| script: end_to_end_test_async.py | |
| expected_improvement: 10 | |
| - name: benchmark-bubble-sort | |
| script: end_to_end_test_benchmark_sort.py | |
| expected_improvement: 5 | |
| - name: coverage-e2e | |
| script: end_to_end_test_coverage.py | |
| extra_deps: black | |
| - name: init-optimization | |
| script: end_to_end_test_init_optimization.py | |
| expected_improvement: 10 | |
| environment: ${{ ((github.event_name == 'workflow_dispatch' && github.actor != 'misrasaurabh1' && github.actor != 'KRRT7') || (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: | |
| CODEFLASH_AIS_SERVER: prod | |
| POSTHOG_API_KEY: ${{ secrets.POSTHOG_API_KEY }} | |
| CODEFLASH_API_KEY: ${{ secrets.CODEFLASH_API_KEY }} | |
| MAX_RETRIES: 3 | |
| RETRY_DELAY: 5 | |
| CODEFLASH_END_TO_END: 1 | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| ref: ${{ github.event.pull_request.head.ref || '' }} | |
| repository: ${{ github.event.pull_request.head.repo.full_name || '' }} | |
| fetch-depth: 0 | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Validate PR | |
| if: github.event_name == 'pull_request' | |
| 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.1.0 | |
| with: | |
| python-version: 3.11.6 | |
| enable-cache: true | |
| - name: Install dependencies | |
| run: uv sync | |
| - name: Install extra dependencies | |
| if: matrix.extra_deps | |
| run: uv add ${{ matrix.extra_deps }} | |
| - name: Set test configuration | |
| if: matrix.expected_improvement | |
| run: | | |
| echo "COLUMNS=110" >> "$GITHUB_ENV" | |
| echo "EXPECTED_IMPROVEMENT_PCT=${{ matrix.expected_improvement }}" >> "$GITHUB_ENV" | |
| - name: Remove .git | |
| if: matrix.remove_git | |
| run: | | |
| if [ -d ".git" ]; then | |
| echo ".git directory exists!" | |
| sudo rm -rf .git | |
| if [ -d ".git" ]; then | |
| echo ".git directory still exists after removal attempt!" | |
| exit 1 | |
| else | |
| echo ".git directory successfully removed." | |
| fi | |
| else | |
| echo ".git directory does not exist. Nothing to remove." | |
| exit 1 | |
| fi | |
| - name: Run E2E test | |
| run: uv run python tests/scripts/${{ matrix.script }} | |
| # --- JS E2Es (3 tests, need Node.js + packages/) --- | |
| e2e-js: | |
| needs: determine-changes | |
| if: >- | |
| fromJSON(needs.determine-changes.outputs.flags).e2e_js == 'true' | |
| && github.event_name != 'push' | |
| && github.actor != 'dependabot[bot]' | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - name: js-cjs-function | |
| script: end_to_end_test_js_cjs_function.py | |
| js_project_dir: code_to_optimize/js/code_to_optimize_js | |
| expected_improvement: 50 | |
| - name: js-esm-async | |
| script: end_to_end_test_js_esm_async.py | |
| js_project_dir: code_to_optimize/js/code_to_optimize_js_esm | |
| expected_improvement: 10 | |
| allow_failure: true | |
| - name: js-ts-class | |
| script: end_to_end_test_js_ts_class.py | |
| js_project_dir: code_to_optimize/js/code_to_optimize_ts | |
| expected_improvement: 30 | |
| continue-on-error: ${{ matrix.allow_failure || false }} | |
| environment: ${{ ((github.event_name == 'workflow_dispatch' && github.actor != 'misrasaurabh1' && github.actor != 'KRRT7') || (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: | |
| CODEFLASH_AIS_SERVER: prod | |
| POSTHOG_API_KEY: ${{ secrets.POSTHOG_API_KEY }} | |
| CODEFLASH_API_KEY: ${{ secrets.CODEFLASH_API_KEY }} | |
| COLUMNS: 110 | |
| MAX_RETRIES: 3 | |
| RETRY_DELAY: 5 | |
| EXPECTED_IMPROVEMENT_PCT: ${{ matrix.expected_improvement }} | |
| CODEFLASH_END_TO_END: 1 | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| ref: ${{ github.event.pull_request.head.ref || '' }} | |
| repository: ${{ github.event.pull_request.head.repo.full_name || '' }} | |
| fetch-depth: 0 | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Validate PR | |
| if: github.event_name == 'pull_request' | |
| 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@v6 | |
| with: | |
| node-version: '20' | |
| cache: 'npm' | |
| cache-dependency-path: | | |
| packages/codeflash/package-lock.json | |
| code_to_optimize/js/*/package-lock.json | |
| - name: Install codeflash npm package dependencies | |
| run: | | |
| cd packages/codeflash | |
| npm install | |
| - name: Install JS test project dependencies | |
| run: | | |
| cd ${{ matrix.js_project_dir }} | |
| npm install | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v8.1.0 | |
| with: | |
| python-version: 3.11.6 | |
| enable-cache: true | |
| - name: Install dependencies | |
| run: uv sync | |
| - name: Run E2E test | |
| run: uv run python tests/scripts/${{ matrix.script }} | |
| # --- Java E2Es (3 tests, need JDK + Maven) --- | |
| e2e-java: | |
| needs: determine-changes | |
| if: >- | |
| fromJSON(needs.determine-changes.outputs.flags).e2e_java == 'true' | |
| && github.event_name != 'push' | |
| && github.actor != 'dependabot[bot]' | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - name: java-fibonacci-nogit | |
| script: end_to_end_test_java_fibonacci.py | |
| expected_improvement: 70 | |
| remove_git: true | |
| - name: java-tracer | |
| script: end_to_end_test_java_tracer.py | |
| expected_improvement: 10 | |
| - name: java-void-optimization-nogit | |
| script: end_to_end_test_java_void_optimization.py | |
| expected_improvement: 70 | |
| remove_git: true | |
| environment: ${{ ((github.event_name == 'workflow_dispatch' && github.actor != 'misrasaurabh1' && github.actor != 'KRRT7') || (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: | |
| CODEFLASH_AIS_SERVER: prod | |
| POSTHOG_API_KEY: ${{ secrets.POSTHOG_API_KEY }} | |
| CODEFLASH_API_KEY: ${{ secrets.CODEFLASH_API_KEY }} | |
| COLUMNS: 110 | |
| MAX_RETRIES: 3 | |
| RETRY_DELAY: 5 | |
| EXPECTED_IMPROVEMENT_PCT: ${{ matrix.expected_improvement }} | |
| CODEFLASH_END_TO_END: 1 | |
| CODEFLASH_LOOPING_TIME: 5 | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| ref: ${{ github.event.pull_request.head.ref || '' }} | |
| repository: ${{ github.event.pull_request.head.repo.full_name || '' }} | |
| fetch-depth: 0 | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Validate PR | |
| if: github.event_name == 'pull_request' | |
| 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@v5 | |
| with: | |
| java-version: '11' | |
| distribution: 'temurin' | |
| cache: maven | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v8.1.0 | |
| with: | |
| python-version: 3.11.6 | |
| enable-cache: true | |
| - name: Install dependencies | |
| run: uv sync | |
| - name: Cache codeflash-runtime JAR | |
| id: runtime-jar-cache | |
| uses: actions/cache@v5 | |
| with: | |
| path: ~/.m2/repository/io/codeflash | |
| key: codeflash-runtime-${{ hashFiles('codeflash-java-runtime/pom.xml', 'codeflash-java-runtime/src/**') }} | |
| - name: Build and install codeflash-runtime JAR | |
| if: steps.runtime-jar-cache.outputs.cache-hit != 'true' | |
| run: | | |
| cd codeflash-java-runtime | |
| mvn install -q -DskipTests | |
| - name: Remove .git | |
| if: matrix.remove_git | |
| run: | | |
| if [ -d ".git" ]; then | |
| sudo rm -rf .git | |
| echo ".git directory removed." | |
| else | |
| echo ".git directory does not exist." | |
| exit 1 | |
| fi | |
| - name: Run E2E test | |
| run: uv run python tests/scripts/${{ matrix.script }} | |
| # --------------------------------------------------------------------------- | |
| # Gate job — the ONLY required check in the GitHub ruleset. | |
| # Accepts "success" and "skipped" (job skipped by change detection). | |
| # Rejects "failure" and "cancelled". | |
| # --------------------------------------------------------------------------- | |
| required-checks-passed: | |
| name: required checks passed | |
| if: always() | |
| needs: | |
| - check-linked-issue | |
| - unit-tests | |
| - coverage | |
| - type-check | |
| - prek | |
| - e2e-python | |
| - e2e-js | |
| - e2e-java | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: codeflash-ai/github-workflows/.github/actions/required-checks-gate@main | |
| with: | |
| needs-json: ${{ toJSON(needs) }} |