1+ name : Check OTA Flash Space (Unified)
2+
3+ on :
4+ push :
5+ branches :
6+ - feature/ota-space-check
7+ schedule :
8+ - cron : " 0 0 * * *"
9+ workflow_dispatch :
10+ inputs :
11+ build-type :
12+ description : " Build type"
13+ required : true
14+ type : choice
15+ options :
16+ - standard
17+ - full
18+ default : standard
19+
20+ permissions :
21+ contents : read
22+ actions : write
23+
24+ jobs :
25+ set-build-type :
26+ runs-on : ubuntu-latest
27+ outputs :
28+ build-type : ${{ steps.set.outputs.build-type }}
29+ steps :
30+ - id : set
31+ run : |
32+ if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
33+ echo "build-type=${{ github.event.inputs.build-type }}" >> "$GITHUB_OUTPUT"
34+ elif [[ "${{ github.event_name }}" == "schedule" ]]; then
35+ echo "build-type=full" >> "$GITHUB_OUTPUT"
36+ else
37+ echo "build-type=standard" >> "$GITHUB_OUTPUT"
38+ fi
39+
40+ ota-check :
41+ name : OTA flash check (${{ matrix.display }})
42+ needs : set-build-type
43+ runs-on : ubuntu-latest
44+ strategy :
45+ fail-fast : false
46+ matrix :
47+ include :
48+ - id : mg24
49+ display : MG24
50+ page_size : 8192
51+ available_flash : 1499136
52+ image_ext : .s37
53+ exclude_path : " */matter-bootloader/*"
54+ json_file : ./.github/silabs-builds-mg24-ota.json
55+ lighting_path : slc/apps/lighting-app/thread/lighting-app-series-2.slcw
56+ platform_template_path : slc/apps/platform-template/thread/platform-template-series-2.slcw
57+ lock_path : slc/apps/lock-app/thread/lock-app-series-2.slcw
58+ light_switch_path : slc/apps/light-switch-app/thread/light-switch-app-series-2.slcw
59+
60+ - id : mg26
61+ display : MG26
62+ page_size : 8192
63+ available_flash : 3145728
64+ image_ext : .s37
65+ exclude_path : " */matter-bootloader/*"
66+ json_file : ./.github/silabs-builds-mg26-ota.json
67+ lighting_path : slc/apps/lighting-app/thread/lighting-app-series-2.slcw
68+ platform_template_path : slc/apps/platform-template/thread/platform-template-series-2.slcw
69+ lock_path : slc/apps/lock-app/thread/lock-app-series-2.slcw
70+ light_switch_path : slc/apps/light-switch-app/thread/light-switch-app-series-2.slcw
71+
72+ - id : siwx
73+ display : 917 SiWx
74+ page_size : 256
75+ available_flash : 4194304
76+ image_ext : .rps
77+ exclude_path : " "
78+ json_file : ./.github/silabs-builds-siwx-ota.json
79+ lighting_path : slc/apps/lighting-app/wifi/lighting-app-siwx.slcw
80+ platform_template_path : slc/apps/platform-template/wifi/platform-template-siwx.slcw
81+ lock_path : slc/apps/lock-app/wifi/lock-app-siwx.slcw
82+ light_switch_path : slc/apps/light-switch-app/wifi/light-switch-app-siwx.slcw
83+
84+ steps :
85+ - name : Checkout
86+ uses : actions/checkout@v5
87+ with :
88+ submodules : " true"
89+
90+ - name : Install tools
91+ uses : ./.github/actions/install-tools
92+
93+ - name : Build lighting-app
94+ uses : SiliconLabsSoftware/matter_build_action@v2.0.0
95+ with :
96+ json-file-path : ${{ matrix.json_file }}
97+ path-to-example-app : ${{ matrix.lighting_path }}
98+ example-app : lighting-app
99+ build-script : " ./slc/build.sh"
100+ output-directory : " "
101+ build-type : ${{ needs.set-build-type.outputs.build-type }}
102+
103+ - name : Build platform-template
104+ if : needs.set-build-type.outputs.build-type == 'full'
105+ uses : SiliconLabsSoftware/matter_build_action@v2.0.0
106+ with :
107+ json-file-path : ${{ matrix.json_file }}
108+ path-to-example-app : ${{ matrix.platform_template_path }}
109+ example-app : platform-template
110+ build-script : " ./slc/build.sh"
111+ output-directory : " "
112+ build-type : full
113+
114+ - name : Build lock-app
115+ if : needs.set-build-type.outputs.build-type == 'full'
116+ uses : SiliconLabsSoftware/matter_build_action@v2.0.0
117+ with :
118+ json-file-path : ${{ matrix.json_file }}
119+ path-to-example-app : ${{ matrix.lock_path }}
120+ example-app : lock-app
121+ build-script : " ./slc/build.sh"
122+ output-directory : " "
123+ build-type : full
124+
125+ - name : Build light-switch-app
126+ if : needs.set-build-type.outputs.build-type == 'full'
127+ uses : SiliconLabsSoftware/matter_build_action@v2.0.0
128+ with :
129+ json-file-path : ${{ matrix.json_file }}
130+ path-to-example-app : ${{ matrix.light_switch_path }}
131+ example-app : light-switch-app
132+ build-script : " ./slc/build.sh"
133+ output-directory : " "
134+ build-type : full
135+
136+ - name : Check OTA image flash size
137+ shell : bash
138+ run : |
139+ set -euo pipefail
140+
141+ PAGE_SIZE=${{ matrix.page_size }}
142+ AVAILABLE_FLASH=${{ matrix.available_flash }}
143+ IMAGE_EXT="${{ matrix.image_ext }}"
144+ EXCLUDE_PATH="${{ matrix.exclude_path }}"
145+ PLATFORM="${{ matrix.display }}"
146+ BUILD_TYPE="${{ needs.set-build-type.outputs.build-type }}"
147+
148+ echo "========================================"
149+ echo "OTA flash check (${PLATFORM})"
150+ echo "Workflow: ${{ github.workflow }}"
151+ echo "Run: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
152+ echo "Event: ${{ github.event_name }} Ref: ${{ github.ref }} SHA: ${{ github.sha }}"
153+ echo "Build type: ${BUILD_TYPE}"
154+ echo "========================================"
155+
156+ {
157+ echo "## OTA flash check (${PLATFORM})"
158+ echo "- **Build type:** \`${BUILD_TYPE}\`"
159+ echo "- **Event:** \`${{ github.event_name }}\`"
160+ echo "- **Ref:** \`${{ github.ref }}\` @ \`${{ github.sha }}\`"
161+ echo "- [Open this run in GitHub](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})"
162+ echo ""
163+ } >> "$GITHUB_STEP_SUMMARY"
164+
165+ if ! command -v commander >/dev/null 2>&1; then
166+ echo "commander not found, skipping OTA flash size check"
167+ exit 0
168+ fi
169+
170+ if [[ -n "$EXCLUDE_PATH" ]]; then
171+ IMAGES=$(find out -type f -name "*${IMAGE_EXT}" ! -path "$EXCLUDE_PATH" 2>/dev/null)
172+ else
173+ IMAGES=$(find out -type f -name "*${IMAGE_EXT}" 2>/dev/null)
174+ fi
175+
176+ if [[ -z "$IMAGES" ]]; then
177+ echo "No ${IMAGE_EXT} image found under out/, skipping OTA flash size check"
178+ exit 0
179+ fi
180+
181+ FAIL=0
182+
183+ for IMAGE in $IMAGES; do
184+ board=$(echo "$IMAGE" | cut -d'/' -f2)
185+ [[ -z "$board" ]] && continue
186+
187+ echo ""
188+ echo " Board: $board Image: $IMAGE"
189+
190+ if [[ "$IMAGE_EXT" == ".s37" ]]; then
191+ app_name="${board}-$(basename "$IMAGE" .s37)"
192+ pushd /tmp >/dev/null
193+
194+ commander gbl create "temporary-${app_name}.gbl" --app "$GITHUB_WORKSPACE/$IMAGE" 1>/dev/null
195+ file_size_running=$(stat -c "%s" "temporary-${app_name}.gbl")
196+ rounded_running=$(( PAGE_SIZE * (file_size_running + PAGE_SIZE - 1) / PAGE_SIZE ))
197+
198+ commander gbl create --compress lzma "temporary-${app_name}.gbl" --app "$GITHUB_WORKSPACE/$IMAGE" 1>/dev/null
199+ file_size_ota=$(stat -c "%s" "temporary-${app_name}.gbl")
200+ rounded_ota=$(( PAGE_SIZE * (file_size_ota + PAGE_SIZE - 1) / PAGE_SIZE ))
201+
202+ sum=$(( rounded_running + rounded_ota ))
203+ remaining=$(( AVAILABLE_FLASH - sum ))
204+
205+ popd >/dev/null
206+
207+ echo " Running (rounded): $rounded_running B OTA LZMA (rounded): $rounded_ota B Remaining: $remaining B"
208+
209+ if [[ "$sum" -gt "$AVAILABLE_FLASH" ]]; then
210+ FAIL=1
211+ shortfall=$(( sum - AVAILABLE_FLASH ))
212+ echo " FAIL: OTA image will NOT fit in ${AVAILABLE_FLASH} B"
213+ echo "::error title=${PLATFORM} OTA flash exceeded::board=${board} sum=${sum}B limit=${AVAILABLE_FLASH}B shortfall=${shortfall}B image=${IMAGE}"
214+ else
215+ echo " PASS: OTA image fits"
216+ fi
217+
218+ else
219+ image_size=$(commander util rpsinfo "$IMAGE" 2>/dev/null | grep "Image size" | sed -n 's/.*(\([0-9]*\)).*/\1/p')
220+ [[ -z "$image_size" ]] && continue
221+
222+ rounded=$(( PAGE_SIZE * (image_size + PAGE_SIZE - 1) / PAGE_SIZE ))
223+ sum=$(( 2 * rounded ))
224+ remaining=$(( AVAILABLE_FLASH - sum ))
225+
226+ echo " Image size (rounded): $rounded B Running+OTA: $sum B Remaining: $remaining B"
227+
228+ if [[ "$sum" -gt "$AVAILABLE_FLASH" ]]; then
229+ FAIL=1
230+ shortfall=$(( sum - AVAILABLE_FLASH ))
231+ echo " FAIL: OTA image will NOT fit in ${AVAILABLE_FLASH} B"
232+ echo "::error title=${PLATFORM} OTA flash exceeded::board=${board} sum=${sum}B limit=${AVAILABLE_FLASH}B shortfall=${shortfall}B image=${IMAGE}"
233+ else
234+ echo " PASS: OTA image fits"
235+ fi
236+ fi
237+ done
238+
239+ if [[ "$FAIL" -eq 1 ]]; then
240+ echo ""
241+ echo "========================================"
242+ echo "OTA FLASH CHECK FAILED (${PLATFORM})"
243+ echo "Run: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
244+ echo "Ref: ${{ github.ref }} @ ${{ github.sha }}"
245+ echo "Build type: ${BUILD_TYPE}"
246+ echo "========================================"
247+ exit 1
248+ fi
249+
250+ echo ""
251+ echo "All ${PLATFORM} OTA flash checks passed."
252+ {
253+ echo "### Result"
254+ echo "All ${PLATFORM} OTA flash checks **passed**."
255+ } >> "$GITHUB_STEP_SUMMARY"
0 commit comments