Skip to content

Commit 7de207b

Browse files
committed
feat: filter for changed projects only
1 parent a1b3dce commit 7de207b

File tree

1 file changed

+108
-13
lines changed

1 file changed

+108
-13
lines changed

.github/workflows/ci.yml

Lines changed: 108 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,31 @@ on:
77
branches: [main]
88

99
jobs:
10-
# Discover all projects in the repository
10+
# Discover all projects in the repository and filter by changed files
1111
discover:
1212
runs-on: ubuntu-latest
1313
outputs:
14-
node-projects: ${{ steps.find-projects.outputs.node-projects }}
15-
poetry-projects: ${{ steps.find-projects.outputs.poetry-projects }}
16-
uv-projects: ${{ steps.find-projects.outputs.uv-projects }}
17-
pip-projects: ${{ steps.find-projects.outputs.pip-projects }}
14+
node-projects: ${{ steps.filter-projects.outputs.node-projects }}
15+
poetry-projects: ${{ steps.filter-projects.outputs.poetry-projects }}
16+
uv-projects: ${{ steps.filter-projects.outputs.uv-projects }}
17+
pip-projects: ${{ steps.filter-projects.outputs.pip-projects }}
1818
steps:
1919
- uses: actions/checkout@v4
20+
with:
21+
fetch-depth: 0
22+
23+
- name: Get changed files
24+
id: changed-files
25+
run: |
26+
if [ "${{ github.event_name }}" == "pull_request" ]; then
27+
# For PRs, compare against the base branch
28+
CHANGED_FILES=$(git diff --name-only origin/${{ github.base_ref }}...HEAD | tr '\n' ' ')
29+
else
30+
# For pushes, compare against the previous commit
31+
CHANGED_FILES=$(git diff --name-only HEAD~1...HEAD 2>/dev/null | tr '\n' ' ' || echo "")
32+
fi
33+
echo "Changed files: $CHANGED_FILES"
34+
echo "files=$CHANGED_FILES" >> $GITHUB_OUTPUT
2035
2136
- name: Find all projects
2237
id: find-projects
@@ -41,11 +56,79 @@ jobs:
4156
done | sort -u | jq -R -s -c 'split("\n") | map(select(length > 0))')
4257
echo "pip-projects=$PIP_PROJECTS" >> $GITHUB_OUTPUT
4358
59+
- name: Filter projects by changed files
60+
id: filter-projects
61+
run: |
62+
CHANGED_FILES="${{ steps.changed-files.outputs.files }}"
63+
64+
echo "DEBUG: Changed files = '$CHANGED_FILES'"
65+
66+
# If no changed files detected (e.g., first commit), run all projects
67+
if [ -z "$CHANGED_FILES" ]; then
68+
echo "No changed files detected, running all projects"
69+
echo "node-projects=${{ steps.find-projects.outputs.node-projects }}" >> $GITHUB_OUTPUT
70+
echo "poetry-projects=${{ steps.find-projects.outputs.poetry-projects }}" >> $GITHUB_OUTPUT
71+
echo "uv-projects=${{ steps.find-projects.outputs.uv-projects }}" >> $GITHUB_OUTPUT
72+
echo "pip-projects=${{ steps.find-projects.outputs.pip-projects }}" >> $GITHUB_OUTPUT
73+
exit 0
74+
fi
75+
76+
# Check if CI workflow itself changed - if so, run all projects
77+
if echo "$CHANGED_FILES" | grep -qE "(^|[[:space:]])\.github/workflows/ci\.yml([[:space:]]|$)"; then
78+
echo "CI workflow changed, running all projects"
79+
echo "node-projects=${{ steps.find-projects.outputs.node-projects }}" >> $GITHUB_OUTPUT
80+
echo "poetry-projects=${{ steps.find-projects.outputs.poetry-projects }}" >> $GITHUB_OUTPUT
81+
echo "uv-projects=${{ steps.find-projects.outputs.uv-projects }}" >> $GITHUB_OUTPUT
82+
echo "pip-projects=${{ steps.find-projects.outputs.pip-projects }}" >> $GITHUB_OUTPUT
83+
exit 0
84+
fi
85+
86+
# Filter projects based on changed files
87+
filter_projects() {
88+
local projects_json="$1"
89+
local matched_projects=""
90+
91+
# Parse JSON array and check each project
92+
while IFS= read -r project; do
93+
[ -z "$project" ] && continue
94+
95+
# Remove leading ./ for comparison
96+
project_path="${project#./}"
97+
98+
# Check if any changed file starts with this project path
99+
for changed_file in $CHANGED_FILES; do
100+
changed_file_clean="${changed_file#./}"
101+
if [[ "$changed_file_clean" == "$project_path"* ]]; then
102+
if [ -z "$matched_projects" ]; then
103+
matched_projects="\"$project\""
104+
else
105+
matched_projects="$matched_projects,\"$project\""
106+
fi
107+
break
108+
fi
109+
done
110+
done < <(echo "$projects_json" | jq -r '.[]')
111+
112+
# Return as JSON array
113+
echo "[$matched_projects]"
114+
}
115+
116+
# Filter each project type
117+
NODE_FILTERED=$(filter_projects '${{ steps.find-projects.outputs.node-projects }}')
118+
POETRY_FILTERED=$(filter_projects '${{ steps.find-projects.outputs.poetry-projects }}')
119+
UV_FILTERED=$(filter_projects '${{ steps.find-projects.outputs.uv-projects }}')
120+
PIP_FILTERED=$(filter_projects '${{ steps.find-projects.outputs.pip-projects }}')
121+
122+
echo "node-projects=$NODE_FILTERED" >> $GITHUB_OUTPUT
123+
echo "poetry-projects=$POETRY_FILTERED" >> $GITHUB_OUTPUT
124+
echo "uv-projects=$UV_FILTERED" >> $GITHUB_OUTPUT
125+
echo "pip-projects=$PIP_FILTERED" >> $GITHUB_OUTPUT
126+
44127
# Debug output
45-
echo "Node.js projects: $NODE_PROJECTS"
46-
echo "Poetry projects: $POETRY_PROJECTS"
47-
echo "uv projects: $UV_PROJECTS"
48-
echo "pip projects: $PIP_PROJECTS"
128+
echo "Filtered Node.js projects: $NODE_FILTERED"
129+
echo "Filtered Poetry projects: $POETRY_FILTERED"
130+
echo "Filtered uv projects: $UV_FILTERED"
131+
echo "Filtered pip projects: $PIP_FILTERED"
49132
50133
# Build and lint Node.js projects
51134
node:
@@ -266,10 +349,22 @@ jobs:
266349
steps:
267350
- name: Check all jobs passed
268351
run: |
269-
if [ "${{ needs.node.result }}" == "failure" ] || \
270-
[ "${{ needs.poetry.result }}" == "failure" ] || \
271-
[ "${{ needs.uv.result }}" == "failure" ] || \
272-
[ "${{ needs.pip.result }}" == "failure" ]; then
352+
# Check each job result - 'skipped' is OK (no projects to build)
353+
# 'success' is OK, 'failure' is not OK
354+
NODE_RESULT="${{ needs.node.result }}"
355+
POETRY_RESULT="${{ needs.poetry.result }}"
356+
UV_RESULT="${{ needs.uv.result }}"
357+
PIP_RESULT="${{ needs.pip.result }}"
358+
359+
echo "Node job result: $NODE_RESULT"
360+
echo "Poetry job result: $POETRY_RESULT"
361+
echo "uv job result: $UV_RESULT"
362+
echo "pip job result: $PIP_RESULT"
363+
364+
if [ "$NODE_RESULT" == "failure" ] || \
365+
[ "$POETRY_RESULT" == "failure" ] || \
366+
[ "$UV_RESULT" == "failure" ] || \
367+
[ "$PIP_RESULT" == "failure" ]; then
273368
echo "One or more jobs failed"
274369
exit 1
275370
fi

0 commit comments

Comments
 (0)