1+ # Copyright 2025- FlagOS Contributors
2+ #
3+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4+ # of this software and associated documentation files (the "Software"), to deal
5+ # in the Software without restriction, including without limitation the rights
6+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+ # copies of the Software, and to permit persons to whom the Software is
8+ # furnished to do so, subject to the following conditions:
9+ #
10+ # The above copyright notice and this permission notice shall be included in all
11+ # copies or substantial portions of the Software.
12+ #
13+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19+ # SOFTWARE.
20+
121name : ' Check if backend-relevant files changed'
222description : ' Determine whether the CI for a given backend should run or be skipped'
323inputs :
2646
2747 # Check if the workflow is triggered by a Pull Request event
2848 if [ "${{ github.event_name }}" == "pull_request" ]; then
29- FILES=$(git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ github.sha }})
49+ # Use three-dot syntax to compare the merge base (common ancestor) with the HEAD commit
50+ # This ensures we only detect files changed in this PR, excluding changes already merged to base branch
51+ FILES=$(git diff --name-only ${{ github.event.pull_request.base.sha }}...${{ github.sha }})
3052 else
3153 # Handle 'push' events (or other events where 'base_ref' isn't applicable)
3254 # Check if the 'before' SHA is all zeros, which indicates a newly created/pushed branch
@@ -41,46 +63,95 @@ runs:
4163 fi
4264 fi
4365
44- SHOULD_SKIP=true
45- # If no changes were made, we need to run the CI process to avoid any misjudgments.
46- if [ -z "$FILES" ]; then
47- echo "No files changed, running CI by default"
48- SHOULD_SKIP=false
49- else
50- while IFS= read -r file; do
51- # Skip empty lines
52- if [ -z "$file" ]; then
53- continue
54- fi
55- # Current workflow file changed → always run
56- if [[ "$file" == "$CURRENT_WORKFLOW" ]]; then
57- echo "'$file' -> This workflow file changed, need to run"
58- SHOULD_SKIP=false
59- break
60- fi
61- # Check if the file is a documentation file (same logic as check-docs-only)
62- if [[ ! "$file" =~ CMakeLists\.txt$ ]] && [[ "$file" =~ (\.(md|yml|txt|png|jpg|jpeg|gif|svg|ico|webp)$|CODEOWNERS$) ]]; then
63- echo "'$file' -> Doc file, not relevant to CI decision"
64- continue
66+ NEED_CI_TEST=(
67+ "bin"
68+ "cmake"
69+ "include"
70+ "lib"
71+ "python"
72+ "scripts"
73+ "test"
74+ "unittest"
75+ "utils"
76+ "third_party/proton"
77+ "third_party/tle"
78+ "third_party/f2reduce"
79+ "CMakeLists.txt"
80+ "Makefile"
81+ "MANIFEST.in"
82+ "pyproject.toml"
83+ "setup.py"
84+ ".github/actions"
85+ ".github/workflows/code-format-check.yml"
86+ )
87+
88+ # ============================================================
89+ # Function: Check if file should trigger CI test
90+ # ============================================================
91+ need_ci_test() {
92+ local file="$1"
93+ for item in "${NEED_CI_TEST[@]}"; do
94+ # Check if it's a directory (ends with / or no extension)
95+ # or check if file matches exactly or is under the directory
96+ if [[ "$file" == "$item" ]] || [[ "$file" == "$item/"* ]]; then
97+ return 0
6598 fi
66- # It is a code file. Check whether it lives inside third_party/
67- if [[ "$file" == third_party/* ]]; then
68- if [[ "$file" == third_party/${BACKEND}/* ]]; then
69- echo "'$file' -> Backend '$BACKEND' file changed, need to run"
70- SHOULD_SKIP=false
71- break
72- else
73- echo "'$file' -> Other backend file, not relevant to '$BACKEND'"
74- continue
75- fi
76- else
77- # Core code file (outside third_party/) — affects all backends
78- echo "'$file' -> Core code file changed, need to run"
99+ done
100+ return 1
101+ }
102+
103+
104+ # ================================================================
105+ # MAIN LOGIC: Determine whether to run CI
106+ # ================================================================
107+ # CI will run if ANY changed file matches one of these three rules:
108+ # 1. The current workflow file itself
109+ # 2. The NEED_CI_TEST white list above
110+ # 3. third_party/${BACKEND}/ directory
111+ #
112+ # Otherwise, CI will be skipped.
113+ #
114+ # Documentation files (markdown, images, text files, etc.) are automatically
115+ # skipped and do NOT trigger CI, unless they are CMakeLists.txt.
116+ # ================================================================
117+ SHOULD_SKIP=true
118+
119+ while IFS= read -r file; do
120+ # Skip empty lines
121+ if [ -z "$file" ]; then
122+ continue
123+ fi
124+
125+ # Skip documentation files
126+ if [[ ! "$file" =~ CMakeLists\.txt$ ]] && [[ "$file" =~ (\.(md|txt|png|jpg|jpeg|gif|svg|ico|webp)$|CODEOWNERS$) ]]; then
127+ echo "'$file' -> Doc file, not relevant to CI decision"
128+ continue
129+ fi
130+
131+ # Current workflow file changed → always run
132+ if [[ "$file" == "$CURRENT_WORKFLOW" ]]; then
133+ echo "'$file' -> This workflow file changed, need to run"
134+ SHOULD_SKIP=false
135+ break
136+ fi
137+
138+ # Files/directories in NEED_CI_TEST → run CI
139+ if need_ci_test "$file"; then
140+ echo "'$file' -> In NEED_CI_TEST list, need to run"
141+ SHOULD_SKIP=false
142+ break
143+ fi
144+
145+ # It is a code file. Check whether it lives inside third_party/ or .github/workflows/benchmark/
146+ if [[ "$file" == third_party/* ]] || [[ "$file" == .github/workflows/benchmark/* ]]; then
147+ if [[ "$file" == third_party/${BACKEND}/* ]] || [[ "$file" == .github/workflows/benchmark/${BACKEND}/* ]]; then
148+ echo "'$file' -> Backend '$BACKEND' file changed, need to run"
79149 SHOULD_SKIP=false
80150 break
81151 fi
82- done <<< "$FILES"
83- fi
152+ fi
153+ done <<< "$FILES"
154+
84155 echo "should_skip=$SHOULD_SKIP" >> $GITHUB_OUTPUT
85156 if [ "$SHOULD_SKIP" == "true" ]; then
86157 echo "✅ No relevant files changed for backend '$BACKEND'. Will skip CI."
0 commit comments