Skip to content

Commit 24bd374

Browse files
committed
[CI] Reusable matrix step
1 parent 9a2845f commit 24bd374

File tree

3 files changed

+158
-172
lines changed

3 files changed

+158
-172
lines changed
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
name: Build Matrix
2+
3+
on:
4+
workflow_call:
5+
outputs:
6+
packages:
7+
description: 'List of packages (components and bundles)'
8+
value: ${{ jobs.matrix.outputs.packages }}
9+
packages-include:
10+
description: 'Package includes for test matrix'
11+
value: ${{ jobs.matrix.outputs.packages-include }}
12+
bridges:
13+
description: 'Combined list of all bridges'
14+
value: ${{ jobs.matrix.outputs.bridges }}
15+
store-bridges:
16+
description: 'List of store bridges'
17+
value: ${{ jobs.matrix.outputs.store-bridges }}
18+
store-bridges-include:
19+
description: 'Store bridge includes for test matrix'
20+
value: ${{ jobs.matrix.outputs.store-bridges-include }}
21+
tool-bridges:
22+
description: 'List of tool bridges'
23+
value: ${{ jobs.matrix.outputs.tool-bridges }}
24+
tool-bridges-include:
25+
description: 'Tool bridge includes for test matrix'
26+
value: ${{ jobs.matrix.outputs.tool-bridges-include }}
27+
platform-bridges:
28+
description: 'List of platform bridges'
29+
value: ${{ jobs.matrix.outputs.platform-bridges }}
30+
platform-bridges-include:
31+
description: 'Platform bridge includes for test matrix'
32+
value: ${{ jobs.matrix.outputs.platform-bridges-include }}
33+
34+
jobs:
35+
matrix:
36+
name: Build
37+
runs-on: ubuntu-latest
38+
outputs:
39+
packages: ${{ steps.set-matrix.outputs.packages }}
40+
packages-include: ${{ steps.set-matrix.outputs.packages-include }}
41+
bridges: ${{ steps.set-matrix.outputs.bridges }}
42+
store-bridges: ${{ steps.set-matrix.outputs.store-bridges }}
43+
store-bridges-include: ${{ steps.set-matrix.outputs.store-bridges-include }}
44+
tool-bridges: ${{ steps.set-matrix.outputs.tool-bridges }}
45+
tool-bridges-include: ${{ steps.set-matrix.outputs.tool-bridges-include }}
46+
platform-bridges: ${{ steps.set-matrix.outputs.platform-bridges }}
47+
platform-bridges-include: ${{ steps.set-matrix.outputs.platform-bridges-include }}
48+
steps:
49+
- name: Checkout
50+
uses: actions/checkout@v6
51+
52+
- name: Set matrix
53+
id: set-matrix
54+
run: |
55+
# Helper function to convert "ai-bundle" to "AI Bundle"
56+
to_title() {
57+
echo "$1" | sed 's/-/ /g' | awk '{for(i=1;i<=NF;i++) $i=toupper(substr($i,1,1)) substr($i,2)}1' \
58+
| sed 's/\bAi\b/AI/g; s/\bMcp\b/MCP/g'
59+
}
60+
61+
# Packages (components and bundles)
62+
PACKAGES="[]"
63+
for pkg in $(find src/ -mindepth 2 -type f -name composer.json -not -path "*/vendor/*" -not -path "*/Bridge/*" | xargs -I{} dirname {} | sed 's|^src/||' | grep -Ev "examples" | sort); do
64+
if [[ "$pkg" == *-bundle ]]; then
65+
type="Bundle"
66+
else
67+
type="Component"
68+
fi
69+
name=$(to_title "$pkg")
70+
PACKAGES=$(echo "$PACKAGES" | jq -c --arg path "$pkg" --arg type "$type" --arg name "$name" '. + [{path: $path, type: $type, name: $name}]')
71+
done
72+
echo "packages=$PACKAGES" >> $GITHUB_OUTPUT
73+
74+
# Bridges
75+
STORE_BRIDGES=$(ls -1 src/store/src/Bridge/ | sort \
76+
| jq -R -s -c 'split("\n") | map(select(length > 0)) | map({component: "store", type: "Store", bridge: .})')
77+
TOOL_BRIDGES=$(ls -1 src/agent/src/Bridge/ | sort \
78+
| jq -R -s -c 'split("\n") | map(select(length > 0)) | map({component: "agent", type: "Tool", bridge: .})')
79+
PLATFORM_BRIDGES=$(ls -1 src/platform/src/Bridge/ | sort \
80+
| jq -R -s -c 'split("\n") | map(select(length > 0)) | map({component: "platform", type: "Platform", bridge: .})')
81+
82+
# Combined bridges (for code-quality)
83+
BRIDGES=$(jq -n -c --argjson store "$STORE_BRIDGES" --argjson tool "$TOOL_BRIDGES" --argjson platform "$PLATFORM_BRIDGES" '$store + $tool + $platform')
84+
echo "bridges=$BRIDGES" >> $GITHUB_OUTPUT
85+
86+
# Individual bridges without type (for tests)
87+
echo "store-bridges=$(echo "$STORE_BRIDGES" | jq -c 'map(del(.type))')" >> $GITHUB_OUTPUT
88+
echo "tool-bridges=$(echo "$TOOL_BRIDGES" | jq -c 'map(del(.type))')" >> $GITHUB_OUTPUT
89+
echo "platform-bridges=$(echo "$PLATFORM_BRIDGES" | jq -c 'map({bridge: .bridge})')" >> $GITHUB_OUTPUT
90+
91+
# Package includes (lowest, Symfony 7.4, Symfony 8.0)
92+
PACKAGES_INCLUDE=$(echo "$PACKAGES" | jq -c '
93+
. as $pkgs |
94+
($pkgs | map(. + {"php-version": "8.2", "dependency-version": "lowest"})) +
95+
($pkgs | map(. + {"php-version": "8.2", "symfony-version": "7.4.*"})) +
96+
($pkgs | map(. + {"php-version": "8.5", "symfony-version": "8.0.*"}))
97+
| map({package: {path: .path, type: .type, name: .name}} + (. | del(.path, .type, .name)))
98+
')
99+
echo "packages-include=$PACKAGES_INCLUDE" >> $GITHUB_OUTPUT
100+
101+
# Store bridge includes
102+
STORE_BRIDGES_INCLUDE=$(echo "$STORE_BRIDGES" | jq -c '
103+
map(del(.type)) as $bridges |
104+
($bridges | map(. + {"php-version": "8.2", "dependency-version": "lowest"})) +
105+
($bridges | map(. + {"php-version": "8.2", "symfony-version": "7.4.*"})) +
106+
($bridges | map(. + {"php-version": "8.5", "symfony-version": "8.0.*"}))
107+
| map({bridge: {component: .component, bridge: .bridge}} + (. | del(.component, .bridge)))
108+
')
109+
echo "store-bridges-include=$STORE_BRIDGES_INCLUDE" >> $GITHUB_OUTPUT
110+
111+
# Tool bridge includes
112+
TOOL_BRIDGES_INCLUDE=$(echo "$TOOL_BRIDGES" | jq -c '
113+
map(del(.type)) as $bridges |
114+
($bridges | map(. + {"php-version": "8.2", "dependency-version": "lowest"})) +
115+
($bridges | map(. + {"php-version": "8.2", "symfony-version": "7.4.*"})) +
116+
($bridges | map(. + {"php-version": "8.5", "symfony-version": "8.0.*"}))
117+
| map({bridge: {component: .component, bridge: .bridge}} + (. | del(.component, .bridge)))
118+
')
119+
echo "tool-bridges-include=$TOOL_BRIDGES_INCLUDE" >> $GITHUB_OUTPUT
120+
121+
# Platform bridge includes
122+
PLATFORM_BRIDGES_INCLUDE=$(echo "$PLATFORM_BRIDGES" | jq -c '
123+
map({bridge: .bridge}) as $bridges |
124+
($bridges | map(. + {"php-version": "8.2", "dependency-version": "lowest"})) +
125+
($bridges | map(. + {"php-version": "8.2", "symfony-version": "7.4.*"})) +
126+
($bridges | map(. + {"php-version": "8.5", "symfony-version": "8.0.*"}))
127+
| map({bridge: {bridge: .bridge}} + (. | del(.bridge)))
128+
')
129+
echo "platform-bridges-include=$PLATFORM_BRIDGES_INCLUDE" >> $GITHUB_OUTPUT
130+
131+
# Pretty print
132+
echo "::group::Packages"
133+
echo "$PACKAGES" | jq .
134+
echo "::endgroup::"
135+
echo "::group::Bridges"
136+
echo "$BRIDGES" | jq .
137+
echo "::endgroup::"

.github/workflows/code-quality.yaml

Lines changed: 16 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -19,57 +19,18 @@ env:
1919
REQUIRED_PHP_EXTENSIONS: 'mongodb, redis'
2020

2121
jobs:
22-
phpstan-matrix:
23-
name: PHPStan / Matrix
24-
runs-on: ubuntu-latest
25-
outputs:
26-
packages: ${{ steps.set-matrix.outputs.packages }}
27-
bridges: ${{ steps.set-matrix.outputs.bridges }}
28-
steps:
29-
- name: Checkout
30-
uses: actions/checkout@v6
31-
32-
- name: Set matrix
33-
id: set-matrix
34-
run: |
35-
# Helper function to convert "ai-bundle" to "AI Bundle"
36-
to_title() {
37-
echo "$1" | sed 's/-/ /g' | awk '{for(i=1;i<=NF;i++) $i=toupper(substr($i,1,1)) substr($i,2)}1' \
38-
| sed 's/\bAi\b/AI/g; s/\bMcp\b/MCP/g'
39-
}
40-
41-
# Packages (components and bundles)
42-
PACKAGES="[]"
43-
for pkg in $(find src/ -mindepth 2 -type f -name composer.json -not -path "*/vendor/*" -not -path "*/Bridge/*" -printf '%h\n' | sed 's|^src/||' | grep -Ev "examples" | sort); do
44-
if [[ "$pkg" == *-bundle ]]; then
45-
type="Bundle"
46-
else
47-
type="Component"
48-
fi
49-
name=$(to_title "$pkg")
50-
PACKAGES=$(echo "$PACKAGES" | jq -c --arg path "$pkg" --arg type "$type" --arg name "$name" '. + [{path: $path, type: $type, name: $name}]')
51-
done
52-
echo "packages=$PACKAGES" >> $GITHUB_OUTPUT
53-
54-
# Bridges (store, tool, and platform)
55-
STORE_BRIDGES=$(find src/store/src/Bridge/ -mindepth 1 -maxdepth 1 -type d -printf '%f\n' | sort \
56-
| jq -R -s -c 'split("\n") | map(select(length > 0)) | map({component: "store", type: "Store", bridge: .})')
57-
TOOL_BRIDGES=$(find src/agent/src/Bridge/ -mindepth 1 -maxdepth 1 -type d -printf '%f\n' | sort \
58-
| jq -R -s -c 'split("\n") | map(select(length > 0)) | map({component: "agent", type: "Tool", bridge: .})')
59-
PLATFORM_BRIDGES=$(find src/platform/src/Bridge/ -mindepth 1 -maxdepth 1 -type d -printf '%f\n' | sort \
60-
| jq -R -s -c 'split("\n") | map(select(length > 0)) | map({component: "platform", type: "Platform", bridge: .})')
61-
BRIDGES=$(jq -n -c --argjson store "$STORE_BRIDGES" --argjson tool "$TOOL_BRIDGES" --argjson platform "$PLATFORM_BRIDGES" '$store + $tool + $platform')
62-
echo "bridges=$BRIDGES" >> $GITHUB_OUTPUT
63-
64-
# Pretty print for info
65-
echo "### Packages"
66-
echo "$PACKAGES" | jq .
67-
echo ""
68-
echo "### Bridges"
69-
echo "$BRIDGES" | jq .
70-
22+
# ===========================================
23+
# Build Matrix
24+
# ===========================================
25+
matrix:
26+
name: Matrix
27+
uses: ./.github/workflows/build-matrix.yaml
28+
29+
# ===========================================
30+
# PHPStan
31+
# ===========================================
7132
phpstan-demo:
72-
needs: phpstan-matrix
33+
needs: matrix
7334
name: PHPStan / Demo
7435
runs-on: ubuntu-latest
7536
steps:
@@ -100,7 +61,7 @@ jobs:
10061
run: cd demo && vendor/bin/phpstan
10162

10263
phpstan-examples:
103-
needs: phpstan-matrix
64+
needs: matrix
10465
name: PHPStan / Examples
10566
runs-on: ubuntu-latest
10667
steps:
@@ -132,12 +93,12 @@ jobs:
13293

13394
phpstan-package:
13495
name: PHPStan / ${{ matrix.package.type }} / ${{ matrix.package.name }}
135-
needs: phpstan-matrix
96+
needs: matrix
13697
runs-on: ubuntu-latest
13798
strategy:
13899
fail-fast: false
139100
matrix:
140-
package: ${{ fromJson(needs.phpstan-matrix.outputs.packages) }}
101+
package: ${{ fromJson(needs.matrix.outputs.packages) }}
141102
steps:
142103
- name: Checkout
143104
uses: actions/checkout@v6
@@ -164,12 +125,12 @@ jobs:
164125

165126
phpstan-bridge:
166127
name: PHPStan / ${{ matrix.bridge.type }} / ${{ matrix.bridge.bridge }}
167-
needs: phpstan-matrix
128+
needs: matrix
168129
runs-on: ubuntu-latest
169130
strategy:
170131
fail-fast: false
171132
matrix:
172-
bridge: ${{ fromJson(needs.phpstan-matrix.outputs.bridges) }}
133+
bridge: ${{ fromJson(needs.matrix.outputs.bridges) }}
173134
steps:
174135
- name: Checkout
175136
uses: actions/checkout@v6

.github/workflows/tests.yaml

Lines changed: 5 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -19,127 +19,15 @@ env:
1919

2020
jobs:
2121
# ===========================================
22-
# Unit Tests
22+
# Build Matrix
2323
# ===========================================
2424
matrix:
2525
name: Matrix
26-
runs-on: ubuntu-latest
27-
outputs:
28-
packages: ${{ steps.set-matrix.outputs.packages }}
29-
packages-include: ${{ steps.set-matrix.outputs.packages-include }}
30-
store-bridges: ${{ steps.set-matrix.outputs.store-bridges }}
31-
store-bridges-include: ${{ steps.set-matrix.outputs.store-bridges-include }}
32-
tool-bridges: ${{ steps.set-matrix.outputs.tool-bridges }}
33-
tool-bridges-include: ${{ steps.set-matrix.outputs.tool-bridges-include }}
34-
platform-bridges: ${{ steps.set-matrix.outputs.platform-bridges }}
35-
platform-bridges-include: ${{ steps.set-matrix.outputs.platform-bridges-include }}
36-
steps:
37-
- name: Checkout
38-
uses: actions/checkout@v6
39-
40-
- name: Set matrix
41-
id: set-matrix
42-
run: |
43-
# Helper function to convert "ai-bundle" to "AI Bundle"
44-
to_title() {
45-
echo "$1" | sed 's/-/ /g' | awk '{for(i=1;i<=NF;i++) $i=toupper(substr($i,1,1)) substr($i,2)}1' \
46-
| sed 's/\bAi\b/AI/g; s/\bMcp\b/MCP/g'
47-
}
48-
49-
# Packages (components and bundles)
50-
PACKAGES="[]"
51-
for pkg in $(find src/ -mindepth 2 -type f -name composer.json -not -path "*/vendor/*" -not -path "*/Bridge/*" | xargs -I{} dirname {} | sed 's|^src/||' | grep -Ev "examples" | sort); do
52-
if [[ "$pkg" == *-bundle ]]; then
53-
type="Bundle"
54-
else
55-
type="Component"
56-
fi
57-
name=$(to_title "$pkg")
58-
PACKAGES=$(echo "$PACKAGES" | jq -c --arg path "$pkg" --arg type "$type" --arg name "$name" '. + [{path: $path, type: $type, name: $name}]')
59-
done
60-
echo "packages=$PACKAGES" >> $GITHUB_OUTPUT
61-
62-
# Generate package includes (lowest, Symfony 7.4, Symfony 8.0)
63-
PACKAGES_INCLUDE=$(echo "$PACKAGES" | jq -c '
64-
. as $pkgs |
65-
# lowest deps with PHP 8.2
66-
($pkgs | map(. + {"php-version": "8.2", "dependency-version": "lowest"})) +
67-
# Symfony 7.4 LTS with PHP 8.2
68-
($pkgs | map(. + {"php-version": "8.2", "symfony-version": "7.4.*"})) +
69-
# Symfony 8.0 with PHP 8.5
70-
($pkgs | map(. + {"php-version": "8.5", "symfony-version": "8.0.*"}))
71-
| map({package: {path: .path, type: .type, name: .name}} + (. | del(.path, .type, .name)))
72-
')
73-
echo "packages-include=$PACKAGES_INCLUDE" >> $GITHUB_OUTPUT
74-
75-
# Store Bridges
76-
STORE_BRIDGES=$(ls -1 src/store/src/Bridge/ | sort \
77-
| jq -R -s -c 'split("\n") | map(select(length > 0)) | map({component: "store", bridge: .})')
78-
echo "store-bridges=$STORE_BRIDGES" >> $GITHUB_OUTPUT
79-
80-
# Generate store bridge includes (lowest, Symfony 7.4, Symfony 8.0)
81-
STORE_BRIDGES_INCLUDE=$(echo "$STORE_BRIDGES" | jq -c '
82-
. as $bridges |
83-
# lowest deps with PHP 8.2
84-
($bridges | map(. + {"php-version": "8.2", "dependency-version": "lowest"})) +
85-
# Symfony 7.4 LTS with PHP 8.2
86-
($bridges | map(. + {"php-version": "8.2", "symfony-version": "7.4.*"})) +
87-
# Symfony 8.0 with PHP 8.5
88-
($bridges | map(. + {"php-version": "8.5", "symfony-version": "8.0.*"}))
89-
| map({bridge: {component: .component, bridge: .bridge}} + (. | del(.component, .bridge)))
90-
')
91-
echo "store-bridges-include=$STORE_BRIDGES_INCLUDE" >> $GITHUB_OUTPUT
92-
93-
# Tool Bridges
94-
TOOL_BRIDGES=$(ls -1 src/agent/src/Bridge/ | sort \
95-
| jq -R -s -c 'split("\n") | map(select(length > 0)) | map({component: "agent", bridge: .})')
96-
echo "tool-bridges=$TOOL_BRIDGES" >> $GITHUB_OUTPUT
97-
98-
# Generate tool bridge includes (lowest, Symfony 7.4, Symfony 8.0)
99-
TOOL_BRIDGES_INCLUDE=$(echo "$TOOL_BRIDGES" | jq -c '
100-
. as $bridges |
101-
# lowest deps with PHP 8.2
102-
($bridges | map(. + {"php-version": "8.2", "dependency-version": "lowest"})) +
103-
# Symfony 7.4 LTS with PHP 8.2
104-
($bridges | map(. + {"php-version": "8.2", "symfony-version": "7.4.*"})) +
105-
# Symfony 8.0 with PHP 8.5
106-
($bridges | map(. + {"php-version": "8.5", "symfony-version": "8.0.*"}))
107-
| map({bridge: {component: .component, bridge: .bridge}} + (. | del(.component, .bridge)))
108-
')
109-
echo "tool-bridges-include=$TOOL_BRIDGES_INCLUDE" >> $GITHUB_OUTPUT
110-
111-
# Platform bridges
112-
PLATFORM_BRIDGES=$(ls -1 src/platform/src/Bridge/ | sort \
113-
| jq -R -s -c 'split("\n") | map(select(length > 0)) | map({bridge: .})')
114-
echo "platform-bridges=$PLATFORM_BRIDGES" >> $GITHUB_OUTPUT
115-
116-
# Generate platform bridge includes (lowest, Symfony 7.4, Symfony 8.0)
117-
PLATFORM_BRIDGES_INCLUDE=$(echo "$PLATFORM_BRIDGES" | jq -c '
118-
. as $bridges |
119-
# lowest deps with PHP 8.2
120-
($bridges | map(. + {"php-version": "8.2", "dependency-version": "lowest"})) +
121-
# Symfony 7.4 LTS with PHP 8.2
122-
($bridges | map(. + {"php-version": "8.2", "symfony-version": "7.4.*"})) +
123-
# Symfony 8.0 with PHP 8.5
124-
($bridges | map(. + {"php-version": "8.5", "symfony-version": "8.0.*"}))
125-
| map({bridge: {bridge: .bridge}} + (. | del(.bridge)))
126-
')
127-
echo "platform-bridges-include=$PLATFORM_BRIDGES_INCLUDE" >> $GITHUB_OUTPUT
128-
129-
# Pretty print for info
130-
echo "::group::Packages"
131-
echo "$PACKAGES" | jq .
132-
echo "::endgroup::"
133-
echo "::group::Store Bridges"
134-
echo "$STORE_BRIDGES" | jq .
135-
echo "::endgroup::"
136-
echo "::group::Tool Bridges"
137-
echo "$TOOL_BRIDGES" | jq .
138-
echo "::endgroup::"
139-
echo "::group::Platform Bridges"
140-
echo "$PLATFORM_BRIDGES" | jq .
141-
echo "::endgroup::"
26+
uses: ./.github/workflows/build-matrix.yaml
14227

28+
# ===========================================
29+
# Unit Tests
30+
# ===========================================
14331
packages:
14432
name: Unit / ${{ matrix.package.type }} / ${{ matrix.package.name }} / PHP ${{ matrix.php-version }}${{ matrix.dependency-version == 'lowest' && ' / lowest' || '' }}${{ matrix.symfony-version && format(' / Symfony {0}', matrix.symfony-version) || '' }}
14533
needs: matrix

0 commit comments

Comments
 (0)