diff --git a/.github/workflows/build_x86_64_mlu.yaml b/.github/workflows/build_x86_64_mlu.yaml index 065ee453..8ef4841b 100644 --- a/.github/workflows/build_x86_64_mlu.yaml +++ b/.github/workflows/build_x86_64_mlu.yaml @@ -18,8 +18,6 @@ on: branches: [main] types: [opened, synchronize, reopened] paths-ignore: - - '.github/**' - - 'cibuild/**' - 'cmake/**' - 'docs/**' - 'third_party/**' @@ -27,7 +25,16 @@ on: - '*.md' - '*.txt' - '*.yml' - + pull_request_review: + types: [submitted] + paths-ignore: + - 'cmake/**' + - 'docs/**' + - 'third_party/**' + - 'tools/**' + - '*.md' + - '*.txt' + - '*.yml' env: JOBNAME: xllm-x86_64-mlu-cibuild-${{ github.run_id }} @@ -36,8 +43,128 @@ concurrency: cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }} jobs: + # need to review code first when sensitive files are modified. + check-sensitive-step-1: + runs-on: [self-hosted] + outputs: + should_check: ${{ steps.decide.outputs.should_check }} + approved: ${{ steps.decide.outputs.approved }} + steps: + - name: Decide whether to check sensitive file + id: decide + run: | + event="${{ github.event_name }}" + if [[ "$event" == "workflow_dispatch" || "$event" == "push" ]]; then + echo "ignore workflow_dispatch and push events in check-sensitive-step-1." + echo "should_check=false" >> $GITHUB_OUTPUT + echo "approved=false" >> $GITHUB_OUTPUT + elif [[ "$event" == "pull_request" ]]; then + echo "should_check=true" >> $GITHUB_OUTPUT + echo "approved=false" >> $GITHUB_OUTPUT + elif [[ "$event" == "pull_request_review" ]]; then + if [[ "${{ github.event.review.state }}" == "approved" ]]; then + echo "should_check=false" >> $GITHUB_OUTPUT + echo "approved=true" >> $GITHUB_OUTPUT + else + echo "should_check=false" >> $GITHUB_OUTPUT + echo "approved=false" >> $GITHUB_OUTPUT + fi + else + echo "should_check=false" >> $GITHUB_OUTPUT + echo "approved=false" >> $GITHUB_OUTPUT + fi + + check-sensitive-step-2: + needs: check-sensitive-step-1 + #if: > + # needs.check-sensitive-step-1.outputs.should_check == 'true' && + # (github.event_name == 'pull_request' || github.event_name == 'pull_request_review') + if: > + needs.check-sensitive-step-1.outputs.should_check == 'true' && github.event_name == 'pull_request' + runs-on: [self-hosted] + outputs: + do_build: ${{ steps.check.outputs.do_build }} + steps: + - name: Checkout Code + uses: actions/checkout@v4 + with: + fetch-depth: 0 # Ensure we can compare commits + + - name: Install jq + run: yum install -y jq + + - name: Check if sensitive files were changed + id: check_sensitive + run: | + sensitive_files=( + ".github/**.yaml" + "cibuild/**.sh" + "setup.py" + ) + changed_files=$(git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ github.sha }}) + requires_approval="false" + while IFS= read -r changed_file; do + [[ -z "$changed_file" ]] && continue + for pattern in "${sensitive_files[@]}"; do + if [[ "$changed_file" == $pattern ]]; then + requires_approval="true" + break 2 + fi + done + done < <(git diff --name-only "${{ github.event.pull_request.base.sha }}" "${{ github.sha }}") + + echo "requires_approval=$requires_approval" >> $GITHUB_OUTPUT + + - name: Check PR approvals + id: check_approved + if: ${{ github.event_name == 'pull_request' && steps.check_sensitive.outputs.requires_approval == 'true' }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + pr_number=${{ github.event.pull_request.number }} + response=$(curl -s -H "Authorization: Bearer $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github.v3+json" \ + "https://api.github.com/repos/${{ github.repository }}/pulls/$pr_number/reviews") + + if echo "$response" | jq -e '.[] | select(.state == "APPROVED")' > /dev/null; then + echo "approved=true" >> $GITHUB_OUTPUT + else + echo "approved=false" >> $GITHUB_OUTPUT + fi + + - name: Final check + id: check + run: | + if [ "${{ steps.check_sensitive.outputs.requires_approval }}" != "true" ]; then + echo "do_build=true" >> $GITHUB_OUTPUT + elif [ "${{ steps.check_approved.outputs.approved }}" == "true" ]; then + echo "do_build=true" >> $GITHUB_OUTPUT + else + echo "do_build=false" >> $GITHUB_OUTPUT + fi + + check-sensitive-step-3: + needs: check-sensitive-step-1 + if: > + github.event_name == 'pull_request_review' + runs-on: [self-hosted] + outputs: + do_build: ${{ steps.check.outputs.do_build }} + steps: + - name: Checkout status + id: check + run: + if [ "${{ needs.check-sensitive-step-1.outputs.approved }}" == "true" ]; then + echo "do_build=true" >> $GITHUB_OUTPUT + else + echo "do_build=false" >> $GITHUB_OUTPUT + fi + build: - if: ${{ github.event_name == 'workflow_dispatch' || github.event_name == 'push' || github.event_name == 'pull_request' }} + needs: [check-sensitive-step-1, check-sensitive-step-2, check-sensitive-step-3] + if: > + (github.event_name == 'workflow_dispatch' || github.event_name == 'push') || + (needs.check-sensitive-step-2.outputs.do_build == 'true' || needs.check-sensitive-step-3.outputs.do_build == 'true') runs-on: [self-hosted] steps: - name: Checkout Code diff --git a/.github/workflows/build_x86_64_npu.yaml b/.github/workflows/build_x86_64_npu.yaml index 25766cab..08d6d589 100644 --- a/.github/workflows/build_x86_64_npu.yaml +++ b/.github/workflows/build_x86_64_npu.yaml @@ -18,8 +18,16 @@ on: branches: [main] types: [opened, synchronize, reopened] paths-ignore: - - '.github/**' - - 'cibuild/**' + - 'cmake/**' + - 'docs/**' + - 'third_party/**' + - 'tools/**' + - '*.md' + - '*.txt' + - '*.yml' + pull_request_review: + types: [submitted] + paths-ignore: - 'cmake/**' - 'docs/**' - 'third_party/**' @@ -36,8 +44,128 @@ concurrency: cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }} jobs: + # need to review code first when sensitive files are modified. + check-sensitive-step-1: + runs-on: [self-hosted] + outputs: + should_check: ${{ steps.decide.outputs.should_check }} + approved: ${{ steps.decide.outputs.approved }} + steps: + - name: Decide whether to check sensitive file + id: decide + run: | + event="${{ github.event_name }}" + if [[ "$event" == "workflow_dispatch" || "$event" == "push" ]]; then + echo "ignore workflow_dispatch and push events in check-sensitive-step-1." + echo "should_check=false" >> $GITHUB_OUTPUT + echo "approved=false" >> $GITHUB_OUTPUT + elif [[ "$event" == "pull_request" ]]; then + echo "should_check=true" >> $GITHUB_OUTPUT + echo "approved=false" >> $GITHUB_OUTPUT + elif [[ "$event" == "pull_request_review" ]]; then + if [[ "${{ github.event.review.state }}" == "approved" ]]; then + echo "should_check=false" >> $GITHUB_OUTPUT + echo "approved=true" >> $GITHUB_OUTPUT + else + echo "should_check=false" >> $GITHUB_OUTPUT + echo "approved=false" >> $GITHUB_OUTPUT + fi + else + echo "should_check=false" >> $GITHUB_OUTPUT + echo "approved=false" >> $GITHUB_OUTPUT + fi + + check-sensitive-step-2: + needs: check-sensitive-step-1 + #if: > + # needs.check-sensitive-step-1.outputs.should_check == 'true' && + # (github.event_name == 'pull_request' || github.event_name == 'pull_request_review') + if: > + needs.check-sensitive-step-1.outputs.should_check == 'true' && github.event_name == 'pull_request' + runs-on: [self-hosted] + outputs: + do_build: ${{ steps.check.outputs.do_build }} + steps: + - name: Checkout Code + uses: actions/checkout@v4 + with: + fetch-depth: 0 # Ensure we can compare commits + + - name: Install jq + run: yum install -y jq + + - name: Check if sensitive files were changed + id: check_sensitive + run: | + sensitive_files=( + ".github/**.yaml" + "cibuild/**.sh" + "setup.py" + ) + changed_files=$(git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ github.sha }}) + requires_approval="false" + while IFS= read -r changed_file; do + [[ -z "$changed_file" ]] && continue + for pattern in "${sensitive_files[@]}"; do + if [[ "$changed_file" == $pattern ]]; then + requires_approval="true" + break 2 + fi + done + done < <(git diff --name-only "${{ github.event.pull_request.base.sha }}" "${{ github.sha }}") + + echo "requires_approval=$requires_approval" >> $GITHUB_OUTPUT + + - name: Check PR approvals + id: check_approved + if: ${{ github.event_name == 'pull_request' && steps.check_sensitive.outputs.requires_approval == 'true' }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + pr_number=${{ github.event.pull_request.number }} + response=$(curl -s -H "Authorization: Bearer $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github.v3+json" \ + "https://api.github.com/repos/${{ github.repository }}/pulls/$pr_number/reviews") + + if echo "$response" | jq -e '.[] | select(.state == "APPROVED")' > /dev/null; then + echo "approved=true" >> $GITHUB_OUTPUT + else + echo "approved=false" >> $GITHUB_OUTPUT + fi + + - name: Final check + id: check + run: | + if [ "${{ steps.check_sensitive.outputs.requires_approval }}" != "true" ]; then + echo "do_build=true" >> $GITHUB_OUTPUT + elif [ "${{ steps.check_approved.outputs.approved }}" == "true" ]; then + echo "do_build=true" >> $GITHUB_OUTPUT + else + echo "do_build=false" >> $GITHUB_OUTPUT + fi + + check-sensitive-step-3: + needs: check-sensitive-step-1 + if: > + github.event_name == 'pull_request_review' + runs-on: [self-hosted] + outputs: + do_build: ${{ steps.check.outputs.do_build }} + steps: + - name: Checkout status + id: check + run: + if [ "${{ needs.check-sensitive-step-1.outputs.approved }}" == "true" ]; then + echo "do_build=true" >> $GITHUB_OUTPUT + else + echo "do_build=false" >> $GITHUB_OUTPUT + fi + build: - if: ${{ github.event_name == 'workflow_dispatch' || github.event_name == 'push' || github.event_name == 'pull_request' }} + needs: [check-sensitive-step-1, check-sensitive-step-2, check-sensitive-step-3] + if: > + (github.event_name == 'workflow_dispatch' || github.event_name == 'push') || + (needs.check-sensitive-step-2.outputs.do_build == 'true' || needs.check-sensitive-step-3.outputs.do_build == 'true') runs-on: [self-hosted] steps: - name: Checkout Code diff --git a/xllm/api_service/chat_service_impl.cpp b/xllm/api_service/chat_service_impl.cpp index 362304c6..f8923f89 100644 --- a/xllm/api_service/chat_service_impl.cpp +++ b/xllm/api_service/chat_service_impl.cpp @@ -54,6 +54,9 @@ ToolCallResult process_tool_calls(std::string text, google::protobuf::Arena* arena = nullptr) { ToolCallResult result; + /// -------------- + LOG(ERROR) << "====================== test ======================="; + function_call::FunctionCallParser parser(tools, parser_format); if (!parser.has_tool_call(text)) {