feat: enhance AI solver with LeetCode verification retry logic #64
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, master] | |
| paths: | |
| - 'src/**/*.cpp' | |
| - 'include/**/*.h' | |
| - 'test/**/*.cpp' | |
| - 'CMakeLists.txt' | |
| pull_request: | |
| branches: [main, master, develop] | |
| paths: | |
| - 'src/**/*.cpp' | |
| - 'include/**/*.h' | |
| - 'test/**/*.cpp' | |
| - 'CMakeLists.txt' | |
| # Cancel redundant workflows | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| detect-changes: | |
| name: Detect Changes | |
| runs-on: ubuntu-latest | |
| outputs: | |
| problems: ${{ steps.detect.outputs.problems }} | |
| problem_count: ${{ steps.detect.outputs.problem_count }} | |
| is_full_build: ${{ steps.strategy.outputs.is_full_build }} | |
| build_type: ${{ steps.strategy.outputs.build_type }} | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Restore file timestamps | |
| uses: chetan/git-restore-mtime-action@v2 | |
| - name: Detect changed problems | |
| id: detect | |
| run: | | |
| CHANGED_PROBLEMS=$(python3 script/ci/detect_changed_problems.py origin/main) | |
| PROBLEM_COUNT=$(echo "$CHANGED_PROBLEMS" | tr ';' '\n' | grep -c '^' || true) | |
| echo "problems=$CHANGED_PROBLEMS" >> $GITHUB_OUTPUT | |
| echo "problem_count=$PROBLEM_COUNT" >> $GITHUB_OUTPUT | |
| echo "Detected $PROBLEM_COUNT changed problem(s)" | |
| - name: Determine build strategy | |
| id: strategy | |
| run: | | |
| IS_PR="${{ github.event_name == 'pull_request' }}" | |
| PROBLEM_COUNT="${{ steps.detect.outputs.problem_count }}" | |
| if [ "$IS_PR" == "true" ]; then | |
| # PR: Use incremental build if <= 10 problems | |
| if [ "$PROBLEM_COUNT" -gt 10 ]; then | |
| echo "is_full_build=true" >> $GITHUB_OUTPUT | |
| echo "build_type=full" >> $GITHUB_OUTPUT | |
| echo "PR with many changes ($PROBLEM_COUNT), using full build" | |
| elif [ "$PROBLEM_COUNT" -eq 0 ]; then | |
| # Check if core files changed | |
| CORE_CHANGES=$(git diff --name-only origin/main HEAD | grep -E "(CMakeLists\.txt|include/leetcode/(core|solution)\.h|src/leetcode/utils/)" || true) | |
| if [ -n "$CORE_CHANGES" ]; then | |
| echo "is_full_build=true" >> $GITHUB_OUTPUT | |
| echo "build_type=full" >> $GITHUB_OUTPUT | |
| echo "Core files changed, using full build" | |
| else | |
| echo "is_full_build=false" >> $GITHUB_OUTPUT | |
| echo "build_type=skip" >> $GITHUB_OUTPUT | |
| echo "No relevant changes, skipping build" | |
| fi | |
| else | |
| echo "is_full_build=false" >> $GITHUB_OUTPUT | |
| echo "build_type=incremental" >> $GITHUB_OUTPUT | |
| echo "PR with $PROBLEM_COUNT problem(s), using incremental build" | |
| fi | |
| else | |
| # Push to main: Always full build | |
| echo "is_full_build=true" >> $GITHUB_OUTPUT | |
| echo "build_type=full" >> $GITHUB_OUTPUT | |
| echo "Push to main, using full build" | |
| fi | |
| build-incremental: | |
| name: Incremental Build | |
| runs-on: ubuntu-latest | |
| needs: detect-changes | |
| if: ${{ needs.detect-changes.outputs.build_type == 'incremental' }} | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Restore file timestamps | |
| uses: chetan/git-restore-mtime-action@v2 | |
| - name: Install dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y cmake build-essential ccache ninja-build python3 gcc g++ | |
| - name: Setup ccache | |
| uses: hendrikmuhs/ccache-action@v1.2 | |
| with: | |
| # Use problem list in key for incremental builds | |
| # This allows separate caches for different PRs but share within same problems | |
| key: ${{ runner.os }}-gcc-incremental-${{ hashFiles('CMakeLists.txt') }}-${{ needs.detect-changes.outputs.problems }} | |
| restore-keys: | | |
| ${{ runner.os }}-gcc-incremental-${{ hashFiles('CMakeLists.txt') }}- | |
| ${{ runner.os }}-gcc-incremental- | |
| ${{ runner.os }}-gcc-full- | |
| ${{ runner.os }}-gcc- | |
| max-size: 500M | |
| - name: Setup ccache symlinks | |
| run: | | |
| sudo mkdir -p /usr/local/lib/ccache | |
| sudo ln -sf $(which ccache) /usr/local/lib/ccache/gcc | |
| sudo ln -sf $(which ccache) /usr/local/lib/ccache/g++ | |
| sudo ln -sf $(which ccache) /usr/local/lib/ccache/cc | |
| sudo ln -sf $(which ccache) /usr/local/lib/ccache/c++ | |
| echo "/usr/local/lib/ccache" >> $GITHUB_PATH | |
| ccache --set-config=sloppiness=pch_defines,time_macros,include_file_mtime,include_file_ctime | |
| ccache -s | |
| - name: Build changed problems | |
| run: | | |
| PROBLEMS="${{ needs.detect-changes.outputs.problems }}" | |
| echo "Building problems: $PROBLEMS" | |
| mkdir -p build && cd build | |
| cmake .. -G Ninja \ | |
| -DCMAKE_BUILD_TYPE=Release \ | |
| -DCMAKE_C_COMPILER=/usr/local/lib/ccache/gcc \ | |
| -DCMAKE_CXX_COMPILER=/usr/local/lib/ccache/g++ \ | |
| -DLEETCODE_MULTI_PROBLEMS="$PROBLEMS" | |
| cmake --build . -j | |
| ccache -s | |
| - name: Run tests | |
| working-directory: build | |
| run: ./bin/multi_problem_test | |
| build-full: | |
| name: Full Build | |
| runs-on: ubuntu-latest | |
| needs: detect-changes | |
| if: ${{ needs.detect-changes.outputs.build_type == 'full' }} | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Restore file timestamps | |
| uses: chetan/git-restore-mtime-action@v2 | |
| - name: Install dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y cmake build-essential ccache ninja-build python3 gcc g++ | |
| - name: Setup ccache | |
| uses: hendrikmuhs/ccache-action@v1.2 | |
| with: | |
| # Full build cache - most comprehensive, used as fallback for all builds | |
| key: ${{ runner.os }}-gcc-full-${{ hashFiles('CMakeLists.txt', 'src/leetcode/utils/*.cpp', 'include/leetcode/*.h') }} | |
| restore-keys: | | |
| ${{ runner.os }}-gcc-full- | |
| ${{ runner.os }}-gcc- | |
| max-size: 500M | |
| - name: Setup ccache symlinks | |
| run: | | |
| # Create ccache symlinks to intercept all compiler calls (including FetchContent) | |
| sudo mkdir -p /usr/local/lib/ccache | |
| sudo ln -sf $(which ccache) /usr/local/lib/ccache/gcc | |
| sudo ln -sf $(which ccache) /usr/local/lib/ccache/g++ | |
| sudo ln -sf $(which ccache) /usr/local/lib/ccache/cc | |
| sudo ln -sf $(which ccache) /usr/local/lib/ccache/c++ | |
| echo "/usr/local/lib/ccache" >> $GITHUB_PATH | |
| ccache --set-config=sloppiness=pch_defines,time_macros,include_file_mtime,include_file_ctime | |
| ccache -s | |
| - name: Build project | |
| run: | | |
| mkdir -p build && cd build | |
| cmake .. -G Ninja \ | |
| -DCMAKE_BUILD_TYPE=Release \ | |
| -DCMAKE_C_COMPILER=/usr/local/lib/ccache/gcc \ | |
| -DCMAKE_CXX_COMPILER=/usr/local/lib/ccache/g++ | |
| cmake --build . -j | |
| ccache -s | |
| - name: Run all tests | |
| working-directory: build | |
| run: ctest --output-on-failure |