Skip to content

Commit 0d70787

Browse files
Change: filter workflow to catch matrix changes (#123)
* Change: filter workflow to catch matrix changes * Change: update matrix filtering to use compact JSON output * Change: split filter matrix step in to multiple * Change: filter job changed_dirs step refactor
1 parent bc524bb commit 0d70787

File tree

1 file changed

+54
-31
lines changed

1 file changed

+54
-31
lines changed

.github/workflows/filter.yml

Lines changed: 54 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)