@@ -20,62 +20,85 @@ jobs:
2020 with :
2121 fetch-depth : 0
2222
23- - name : Get changed directories
24- id : changes
23+ - name : Determine Base Reference
24+ id : base_ref
2525 run : |
2626 if [ "${{ github.event_name }}" == "pull_request" ]; then
27- FILES=$(git diff --name-only origin/${{ github.base_ref }} ${{ github.sha }})
27+ BASE_REF=" origin/${{ github.base_ref }}"
2828 else
29- FILES=$(git diff --name-only $ {{ github.event.before }} ${{ github.sha }})
29+ BASE_REF="$ {{ github.event.before }}"
3030 fi
31-
32- # Extract directories, sort, and remove duplicates
33- # Use -r to avoid running dirname on empty input
34- DIRS=$(echo "$FILES" | xargs -r dirname | sort | uniq)
31+ echo "Checking changes against base ref: $BASE_REF"
32+
33+ echo "base_ref=$BASE_REF" >> "$GITHUB_OUTPUT"
34+
35+ - name : Identify Changed Directories
36+ id : files
37+ run : |
38+ BASE_REF="${{ steps.base_ref.outputs.base_ref }}"
39+
40+ # Extract directories from changed files to later compare with the matrix.json entries.
41+ # Sort and remove duplicates to ensure each directory is listed only once.
42+ git diff --name-only $BASE_REF ${{ github.sha }} | xargs -r dirname | sort | uniq > changed_dirs.txt
3543
3644 echo "::group::Changed Directories"
37- echo "$DIRS"
45+ cat changed_dirs.txt
3846 echo "::endgroup::"
47+
48+ - name : Identify Matrix Changes
49+ id : matrix_changes
50+ run : |
51+ BASE_REF="${{ steps.base_ref.outputs.base_ref }}"
52+
53+ git show "$BASE_REF:matrix.json" > old_matrix.json
54+
55+ # Find items that are new in matrix.json (New - Old)
56+ # Deleted items are ignored by the subtraction.
57+ # If an item is present in 'old' but not in 'new', it is excluded from the output.
58+ jq -s '.[0] - .[1]' matrix.json old_matrix.json > by_matrix.json
3959
40- # Output as multiline string to preserve newlines
41- {
42- echo 'changed_dirs<<EOF'
43- echo "$DIRS"
44- echo 'EOF'
45- } >> $GITHUB_OUTPUT
60+ echo "::group::Matrix Changes (New Entries)"
61+ jq . by_matrix.json
62+ echo "::endgroup::"
63+
4664
47- - name : Generate filtered matrix
65+ - name : Generate Filtered Matrix
4866 id : filter
4967 run : |
50- # Get the list of changed directories from the previous step
51- CHANGED_DIRS="${{ steps.changes.outputs.changed_dirs }}"
68+ # Filter 'matrix.json' to keep ALL items whose CONTEXT matches one of the changed directories.
69+ # If a directory changed, every build configuration (matrix entry) associated with that directory is kept.
70+ jq -c --rawfile changed_dirs changed_dirs.txt '[.[] | select(.CONTEXT | inside($changed_dirs))]' matrix.json > by_dirs.json
5271
53- # Read the full build matrix from JSON file
54- MATRIX=$(cat matrix.json)
55-
56- # Filter the matrix using jq:
57- # 1. .[] : Unpack the array into individual objects
58- # 2. select(...) : Keep objects that match the condition
59- # 3. inside(...) : Check if CONTEXT is present in the CHANGED_DIRS string
60- FILTERED=$(echo "$MATRIX" | jq -c "[.[] | select(.CONTEXT | inside(\"$CHANGED_DIRS\"))]")
72+ # Merge the list from file changes (by_dirs.json) with added entries to matrix.json (by_matrix.json).
73+ # '| unique' : Removes duplicates in case an item was selected by both triggers.
74+ FILTERED=$(jq -c -s '.[0] + .[1] | unique' by_dirs.json by_matrix.json)
6175
6276 echo "::group::Filtered Matrix"
6377 echo "$FILTERED" | jq .
6478 echo "::endgroup::"
6579
66- # Generate Job Summary
80+ echo "matrix=$FILTERED" >> $GITHUB_OUTPUT
81+
82+ - name : Generate Job Summary
83+ env :
84+ FILTERED : ${{ steps.filter.outputs.matrix }}
85+ run : |
6786 echo "### Build Plan" >> $GITHUB_STEP_SUMMARY
6887 if [ "$FILTERED" == "[]" ]; then
6988 echo "No changes detected. Skipping builds." >> $GITHUB_STEP_SUMMARY
7089 else
7190 echo "| Context | Base Image | Tag | Export Tag | Updated |" >> $GITHUB_STEP_SUMMARY
7291 echo "| :--- | :--- | :--- | :--- | :--- |" >> $GITHUB_STEP_SUMMARY
73- echo "$FILTERED" | jq -r '.[] | "| `\(.CONTEXT)` | `\(.BASEIMAGE)` | `\(.TAG)` | `\(.EXPORT_TAG)` | `\(.UPDATED)` |"' >> $GITHUB_STEP_SUMMARY
92+ echo "$FILTERED" | jq -r '.[] | "| `\(.CONTEXT)` | `\(.BASEIMAGE // "-" )` | `\(.TAG)` | `\(.EXPORT_TAG // "-" )` | `\(.UPDATED // "-" )` |"' >> $GITHUB_STEP_SUMMARY
7493 fi
7594
76- # Set the filtered matrix as an output for the next job
77- echo "matrix=$FILTERED" >> $GITHUB_OUTPUT
78-
95+ # What is run explanation:
96+ # 1. File Changes (Directory based):
97+ # If a file changes in a directory (e.g. operating_systems/almalinux),
98+ # all matrix entries (releases) pointing to that directory (CONTEXT) are selected.
99+ # This ensures that a code change triggers a rebuild for all versions of that product.
100+ # 2. Matrix Additions (Config based):
101+ # If a new entry is added to matrix.json, only that specific new entry is selected.
79102 build :
80103 needs : filter
81104 if : needs.filter.outputs.matrix != '[]'
0 commit comments