Skip to content

feat: enhance AI solver with LeetCode verification retry logic #64

feat: enhance AI solver with LeetCode verification retry logic

feat: enhance AI solver with LeetCode verification retry logic #64

Workflow file for this run

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