Skip to content

Daily LeetCode Challenge #31

Daily LeetCode Challenge

Daily LeetCode Challenge #31

name: Daily LeetCode Challenge
on:
schedule:
# 每天 UTC 时间 0:00 运行(北京时间 8:00)
- cron: '0 0 * * *'
workflow_dispatch: # 允许手动触发
jobs:
solve-daily-challenge:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
issues: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y cmake build-essential ccache ninja-build just
- name: Set up Python virtual environment
run: |
python3 -m venv venv
source venv/bin/activate
pip install --upgrade pip
pip install -r requirements.txt
- name: Run AI solver
env:
DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }}
DEEPSEEK_USE_REASONER: ${{ secrets.DEEPSEEK_USE_REASONER || 'true' }}
run: |
source venv/bin/activate
python script/leetcode/ai_solver.py
continue-on-error: true # 即使失败也继续,以便创建 PR 报告问题
- name: Get problem ID and files
id: get_files
run: |
# 查找解题报告并提取 problem_id
REPORT_FILE=$(ls SOLUTION_REPORT_*.md 2>/dev/null | head -1)
PROBLEM_ID=$(echo ${REPORT_FILE#SOLUTION_REPORT_} | sed 's/\.md$//')
# 设置默认输出
echo "problem_id=${PROBLEM_ID:-}" >> $GITHUB_OUTPUT
echo "report_file=${REPORT_FILE:-}" >> $GITHUB_OUTPUT
echo "skip_pr=false" >> $GITHUB_OUTPUT
echo "has_solution=false" >> $GITHUB_OUTPUT
# 如果没有报告文件,直接退出
[ -z "$REPORT_FILE" ] && echo "✗ 未找到解题报告" && exit 0
echo "✓ 找到报告: $REPORT_FILE (ID: $PROBLEM_ID)"
# 检查 SKIP_PR 标记
if [ -f "SKIP_PR" ]; then
echo "skip_pr=true" >> $GITHUB_OUTPUT
{
echo "skip_reason<<EOF"
cat SKIP_PR
echo "EOF"
} >> $GITHUB_OUTPUT
echo "⚠️ 跳过 PR: $(cat SKIP_PR)"
exit 0
fi
# 使用 git 查找新生成的代码文件
SOURCE_FILE=$(git status --porcelain | grep '^??' | grep 'src/leetcode/problems/.*\.cpp$' | awk '{print $2}' | head -1)
HEADER_FILE=$(git status --porcelain | grep '^??' | grep 'include/leetcode/problems/.*\.h$' | awk '{print $2}' | head -1)
TEST_FILE=$(git status --porcelain | grep '^??' | grep 'test/leetcode/problems/.*\.cpp$' | awk '{print $2}' | head -1)
# 检查所有文件是否存在
if [ -n "$SOURCE_FILE" ] && [ -n "$HEADER_FILE" ] && [ -n "$TEST_FILE" ]; then
echo "has_solution=true" >> $GITHUB_OUTPUT
echo "source_file=$SOURCE_FILE" >> $GITHUB_OUTPUT
echo "header_file=$HEADER_FILE" >> $GITHUB_OUTPUT
echo "test_file=$TEST_FILE" >> $GITHUB_OUTPUT
echo "✓ 找到所有文件,将创建 PR"
else
echo "✗ 文件不完整 (SOURCE: ${SOURCE_FILE:-未找到}, HEADER: ${HEADER_FILE:-未找到}, TEST: ${TEST_FILE:-未找到})"
fi
- name: Log skip reason
if: steps.get_files.outputs.skip_pr == 'true'
run: |
echo "⏭️ 跳过 PR 创建"
echo "原因: ${{ steps.get_files.outputs.skip_reason }}"
- name: Upload artifacts
if: steps.get_files.outputs.report_file != ''
uses: actions/upload-artifact@v4
with:
name: solution-files-problem-${{ steps.get_files.outputs.problem_id }}
path: |
${{ steps.get_files.outputs.report_file }}
${{ steps.get_files.outputs.source_file }}
${{ steps.get_files.outputs.header_file }}
${{ steps.get_files.outputs.test_file }}
retention-days: 30
if-no-files-found: ignore
- name: Create Pull Request
if: steps.get_files.outputs.has_solution == 'true'
uses: peter-evans/create-pull-request@v5
with:
commit-message: "feat: Solve LeetCode Daily Challenge #${{ steps.get_files.outputs.problem_id }}"
title: "🤖 Daily Challenge: Problem #${{ steps.get_files.outputs.problem_id }}"
body-path: ${{ steps.get_files.outputs.report_file }}
branch: daily-challenge-${{ steps.get_files.outputs.problem_id }}-${{ github.run_id }}
base: main
labels: |
daily-challenge
ai-generated
draft: false
delete-branch: true