Skip to content

Commit 7a3511c

Browse files
committed
CI: espidf: run sample test in parallel
Signed-off-by: Mike Szczys <mike@golioth.io>
1 parent 3e81251 commit 7a3511c

File tree

1 file changed

+97
-44
lines changed

1 file changed

+97
-44
lines changed

.github/workflows/hil-sample-esp-idf.yml

Lines changed: 97 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,19 @@ on:
4747
default: "firmware_ci"
4848

4949
jobs:
50-
rand_name:
50+
matrix:
51+
name: espidf-${{ inputs.hil_board }}-sample-matrix
5152
runs-on: ubuntu-24.04
52-
name: esp-idf-device-name
5353

5454
outputs:
5555
device_name: ${{ steps.generate-name.outputs.device_name }}
56+
sample_list: ${{ steps.gather-samples.outputs.sample_list }}
5657

5758
steps:
59+
- name: Checkout repository
60+
uses: actions/checkout@v4
61+
62+
5863
- name: Generate device name
5964
id: generate-name
6065
shell: python
@@ -72,10 +77,41 @@ jobs:
7277
with open(os.environ['GITHUB_OUTPUT'], 'a') as github_output:
7378
print(f'device_name={device_name}', file=github_output)
7479
80+
- name: Prepare tests matrix
81+
id: gather-samples
82+
shell: python
83+
84+
run: |
85+
import json
86+
import os
87+
88+
SAMPLES_ROOT = 'examples/esp_idf'
89+
sample_dirs = list()
90+
for root, dirs, files in os.walk(SAMPLES_ROOT):
91+
if 'pytest' in dirs:
92+
sample_dirs.append(root)
93+
94+
sample_list = list()
95+
96+
for directory in sample_dirs:
97+
name = os.path.relpath(directory, SAMPLES_ROOT).replace('/', '_')
98+
sample_list.append({"name":name, "dir":directory})
99+
100+
with open(os.environ['GITHUB_OUTPUT'], 'a') as github_output:
101+
print('sample_list=' + json.dumps(sample_list), file=github_output)
102+
75103
build:
76-
name: esp-idf-${{ inputs.hil_board }}-sample-build
104+
name: espidf-${{ inputs.hil_board }}-sample-build (${{ matrix.name }})
105+
needs: matrix
106+
strategy:
107+
fail-fast: false
108+
matrix:
109+
include: ${{ fromJSON(needs.matrix.outputs.sample_list) }}
110+
111+
env:
112+
DEVICE_NAME: ${{ needs.matrix.outputs.device_name }}
113+
77114
runs-on: ubuntu-24.04
78-
needs: rand_name
79115
steps:
80116
- name: Checkout Repository and Submodules
81117
uses: actions/checkout@v4
@@ -87,12 +123,9 @@ jobs:
87123
run: |
88124
rm -rf test_binaries
89125
mkdir test_binaries
90-
echo sample_list=$(find examples/esp_idf -type d -name pytest -exec dirname "{}" \;) \
91-
>> "$GITHUB_OUTPUT"
92126
93127
- name: Generate certificates
94-
env:
95-
DEVICE_NAME: ${{ needs.rand_name.outputs.device_name }}
128+
if: ${{ matrix.name == 'certificate_auth' }}
96129
shell: bash
97130
run: |
98131
scripts/certificates/generate_root_certificate.sh
@@ -111,35 +144,53 @@ jobs:
111144
esp_idf_version: v5.4.1
112145
target: ${{ inputs.idf_target }}
113146
command: |
114-
for sample in ${{ steps.build_prep.outputs.sample_list }};
115-
do
147+
export SAMPLE_NAME="${{ matrix.name }}"
148+
export SAMPLE_DIR="${{ matrix.dir }}"
149+
echo -e "SAMPLE_NAME=$SAMPLE_NAME"
150+
echo -e "SAMPLE_DIR=$SAMPLE_DIR"
151+
116152
echo CONFIG_GOLIOTH_COAP_HOST_URI=\"${{ inputs.coap_gateway_url }}\" \
117-
>> ${sample}/sdkconfig.defaults
153+
>> ${SAMPLE_DIR}/sdkconfig.defaults
118154
119-
if [[ "${sample##*/}" == "fw_update" ]]; then echo
155+
if [[ "${SAMPLE_NAME}" == "fw_update" ]]; then echo
120156
echo CONFIG_GOLIOTH_FW_UPDATE_PACKAGE_NAME=\"${{ inputs.hil_board }}_espidf\" \
121-
>> ${sample}/sdkconfig.defaults
122-
echo CONFIG_GOLIOTH_OTA_MAX_PACKAGE_NAME_LEN=32 >> ${sample}/sdkconfig.defaults
157+
>> ${SAMPLE_DIR}/sdkconfig.defaults
158+
echo CONFIG_GOLIOTH_OTA_MAX_PACKAGE_NAME_LEN=32 >> ${SAMPLE_DIR}/sdkconfig.defaults
123159
fi
124160
125-
idf.py -C $sample build
161+
idf.py -C ${SAMPLE_DIR} build
126162
127-
mv ${sample}/build/merged.bin test_binaries/$(basename $sample).bin || \
128-
EXITCODE=$?
129-
done
130-
exit $EXITCODE
163+
mv ${SAMPLE_DIR}/build/merged.bin test_binaries/${SAMPLE_NAME}.bin
131164
132165
- name: Save Artifacts
133166
uses: actions/upload-artifact@v4
134167
with:
135-
name: ${{ inputs.hil_board }}-sample-esp-idf
168+
name: ${{ inputs.hil_board }}-sample-espidf-${{ matrix.name }}
136169
path: test_binaries/*
137170

171+
verify_build:
172+
name: espidf-${{ inputs.hil_board }}-sample-verify-build
173+
if: always()
174+
needs:
175+
- matrix
176+
- build
177+
runs-on: ubuntu-24.04
178+
179+
steps:
180+
- name: Decide whether the needed jobs succeeded or failed
181+
uses: re-actors/alls-green@05ac9388f0aebcb5727afa17fcccfecd6f8ec5fe
182+
with:
183+
jobs: ${{ toJSON(needs) }}
184+
138185
test:
139-
name: esp-idf-${{ inputs.hil_board }}-sample-test
186+
name: espidf-${{ inputs.hil_board }}-sample-test (${{ matrix.name }})
140187
needs:
188+
- matrix
141189
- build
142-
- rand_name
190+
strategy:
191+
fail-fast: false
192+
matrix:
193+
include: ${{ fromJSON(needs.matrix.outputs.sample_list) }}
143194
runs-on:
144195
- is_active
145196
- has_${{ inputs.hil_board }}
@@ -155,56 +206,58 @@ jobs:
155206
steps:
156207
- name: Checkout repository
157208
uses: actions/checkout@v4
209+
158210
- name: Setup Python dependencies
159211
run: |
160212
uv pip install \
161213
pytest==8.4.2 \
162214
pytest-timeout \
163215
tests/hil/scripts/pytest-hil \
164216
git+https://github.com/golioth/python-golioth-tools@v0.8.1
217+
165218
- name: Power On USB Hub
166219
run: python3 /opt/golioth-scripts/usb_hub_power.py on
220+
167221
- name: Download build
168222
uses: actions/download-artifact@v4
169223
with:
170-
name: ${{ inputs.hil_board }}-sample-esp-idf
224+
name: ${{ inputs.hil_board }}-sample-espidf-${{ matrix.name }}
171225
path: .
226+
172227
- name: Run test
173228
shell: bash
174229
env:
175230
hil_board: ${{ inputs.hil_board }}
176-
GOLIOTH_DEVICE_CERT_NAME: ${{ needs.rand_name.outputs.device_name }}
231+
SAMPLE_NAME: ${{ matrix.name }}
232+
SAMPLE_DIR: ${{ matrix.dir }}
233+
GOLIOTH_DEVICE_CERT_NAME: ${{ needs.matrix.outputs.device_name }}
177234
GOLIOTH_ROOT_CERTIFICATE: "golioth.crt.pem"
178235
run: |
179236
rm -rf allure-reports
180237
source /opt/credentials/runner_env.sh
181238
PORT_VAR=CI_${hil_board^^}_PORT
182-
for sample in $(find examples/esp_idf -type d -name pytest -exec dirname "{}" \;)
183-
do
184-
pytest --rootdir . $sample/pytest \
185-
--board ${{ inputs.hil_board }}_espidf \
186-
--port ${!PORT_VAR} \
187-
--fw-image $(basename $sample).bin \
188-
--api-url ${{ inputs.api-url }} \
189-
--api-key ${{ secrets[inputs.api-key-id] }} \
190-
--wifi-ssid ${{ secrets[format('{0}_WIFI_SSID', runner.name)] }} \
191-
--wifi-psk ${{ secrets[format('{0}_WIFI_PSK', runner.name)] }} \
192-
--mask-secrets \
193-
--timeout=600 \
194-
--alluredir=allure-reports \
195-
--allure-platform=esp-idf \
196-
--runner-name ${{ runner.name }} \
197-
--custom-suitename=sample \
198-
|| EXITCODE=$?
199-
done
200-
exit $EXITCODE
239+
240+
pytest --rootdir . ${SAMPLE_DIR}/pytest \
241+
--board ${{ inputs.hil_board }}_espidf \
242+
--port ${!PORT_VAR} \
243+
--fw-image ${SAMPLE_NAME}.bin \
244+
--api-url ${{ inputs.api-url }} \
245+
--api-key ${{ secrets[inputs.api-key-id] }} \
246+
--wifi-ssid ${{ secrets[format('{0}_WIFI_SSID', runner.name)] }} \
247+
--wifi-psk ${{ secrets[format('{0}_WIFI_PSK', runner.name)] }} \
248+
--mask-secrets \
249+
--timeout=600 \
250+
--alluredir=allure-reports \
251+
--allure-platform=esp-idf \
252+
--runner-name ${{ runner.name }} \
253+
--custom-suitename=sample
201254
202255
- name: Safe upload Allure reports
203256
if: success() || failure()
204257
uses: ./.github/actions/safe-upload-artifacts
205258
with:
206259
secrets-json: ${{ toJson(secrets) }}
207-
name: allure-reports-samples-espidf-${{ inputs.hil_board }}
260+
name: allure-reports-samples-espidf-${{ inputs.hil_board }}-${{ matrix.name }}
208261
path: allure-reports
209262

210263
- name: Erase flash

0 commit comments

Comments
 (0)