Skip to content

Commit 1d79437

Browse files
committed
.github: add CI for libretro-common/samples test programs
New workflow that builds every sample under libretro-common/samples on each push/PR touching libretro-common/, runs the self-testing binaries, and fails CI if any test returns non-zero. Runs 8 self-testing samples: compat_fnmatch_test, snprintf, unbase64_test, archive_zip_test, config_file_test, path_resolve_realpath_test, nbio_test, rpng Build-only (need arguments or fixtures, not run): formats/xml, streams/rzip Skipped entirely: net/ -- Makefile references symbols without listing the corresponding sources (fill_pathname_resolve_relative, cpu_features_get_time_usec); remove from SKIP_DIRS once fixed. Dependencies: build-essential, zlib1g-dev. Runs under ubuntu-latest.
1 parent 15c6484 commit 1d79437

1 file changed

Lines changed: 178 additions & 0 deletions

File tree

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
name: CI Linux libretro-common samples
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
paths:
8+
- 'libretro-common/**'
9+
- '.github/workflows/Linux-libretro-common-samples.yml'
10+
pull_request:
11+
branches:
12+
- master
13+
paths:
14+
- 'libretro-common/**'
15+
- '.github/workflows/Linux-libretro-common-samples.yml'
16+
workflow_dispatch:
17+
18+
permissions:
19+
contents: read
20+
21+
env:
22+
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
23+
24+
jobs:
25+
samples:
26+
name: Build and run libretro-common/samples
27+
runs-on: ubuntu-latest
28+
timeout-minutes: 15
29+
30+
steps:
31+
- name: Install dependencies
32+
run: |
33+
sudo apt-get update -y
34+
sudo apt-get install -y build-essential zlib1g-dev
35+
36+
- name: Checkout
37+
uses: actions/checkout@v3
38+
39+
- name: Build and run samples
40+
shell: bash
41+
working-directory: libretro-common/samples
42+
run: |
43+
set -u
44+
set -o pipefail
45+
46+
# Samples whose binary, when invoked with no arguments, runs a
47+
# self-contained test and exits 0 on success / non-zero on
48+
# failure. These are built AND executed.
49+
declare -a RUN_TARGETS=(
50+
compat_fnmatch_test
51+
snprintf
52+
unbase64_test
53+
archive_zip_test
54+
config_file_test
55+
path_resolve_realpath_test
56+
nbio_test
57+
rpng
58+
)
59+
60+
# Per-binary run command (overrides ./<binary> if present).
61+
# config_file_test has pre-existing sample leaks unrelated to
62+
# any regression so we disable the ASan leak detector -- if a
63+
# real leak shows up elsewhere it will be flagged during build
64+
# of ASan-enabled configurations, not here.
65+
declare -A RUN_ENV=(
66+
[config_file_test]="ASAN_OPTIONS=detect_leaks=0"
67+
)
68+
69+
# Samples that are build-only (either they require command-line
70+
# arguments, open network sockets, need extra fixtures, or are
71+
# interactive demos). They are compiled to catch build-time
72+
# regressions but not executed.
73+
declare -a BUILD_ONLY_DIRS=(
74+
formats/xml
75+
streams/rzip
76+
)
77+
78+
# Samples that are currently broken at build time on a stock
79+
# Ubuntu host and are therefore neither built nor run. The
80+
# net/ Makefile references symbols (fill_pathname_resolve_relative,
81+
# cpu_features_get_time_usec) without adding the corresponding
82+
# source files to its SOURCES list; fixing that is out of
83+
# scope for this workflow. Remove from this list once the
84+
# Makefile is corrected.
85+
declare -a SKIP_DIRS=(
86+
net
87+
)
88+
89+
is_in() {
90+
local needle=$1; shift
91+
local h
92+
for h in "$@"; do [[ "$h" == "$needle" ]] && return 0; done
93+
return 1
94+
}
95+
96+
fails=0
97+
builds=0
98+
runs=0
99+
100+
# Collect all Makefile directories (one or two levels deep).
101+
mapfile -t MKDIRS < <(find . -name Makefile -printf '%h\n' | sort)
102+
103+
printf '\n==> %d sample directories found\n' "${#MKDIRS[@]}"
104+
for d in "${MKDIRS[@]}"; do printf ' %s\n' "${d#./}"; done
105+
printf '\n'
106+
107+
for d in "${MKDIRS[@]}"; do
108+
rel=${d#./}
109+
printf '========================================\n'
110+
printf '[%s] %s\n' "$(is_in "$rel" "${SKIP_DIRS[@]}" && echo skip || echo build)" "$rel"
111+
printf '========================================\n'
112+
113+
if is_in "$rel" "${SKIP_DIRS[@]}"; then
114+
printf '[skip] %s is on the skip list\n\n' "$rel"
115+
continue
116+
fi
117+
118+
# Build
119+
if ! ( cd "$d" && make clean all ); then
120+
printf '\n::error title=Build failed::%s failed to build\n' "$rel"
121+
fails=$((fails+1))
122+
continue
123+
fi
124+
builds=$((builds+1))
125+
126+
# Skip run for build-only dirs
127+
if is_in "$rel" "${BUILD_ONLY_DIRS[@]}"; then
128+
printf '[skip-run] %s (build-only list)\n\n' "$rel"
129+
continue
130+
fi
131+
132+
# Extract targets from Makefile (handles both TARGET := foo
133+
# and TARGETS = a b c).
134+
mapfile -t targets < <(
135+
grep -hE '^(TARGET|TARGETS)[[:space:]]*[:?]?=' "$d/Makefile" \
136+
| head -1 \
137+
| sed -E 's/^[^=]*=[[:space:]]*//' \
138+
| tr -s ' \t' '\n' \
139+
| grep -v '^$'
140+
)
141+
142+
for t in "${targets[@]}"; do
143+
if ! is_in "$t" "${RUN_TARGETS[@]}"; then
144+
printf '[skip-run] %s/%s (not in run allowlist)\n' "$rel" "$t"
145+
continue
146+
fi
147+
148+
bin="$d/$t"
149+
if [[ ! -x "$bin" ]]; then
150+
printf '::error title=Missing binary::%s was in the run allowlist but %s does not exist after build\n' "$t" "$bin"
151+
fails=$((fails+1))
152+
continue
153+
fi
154+
155+
extra_env=${RUN_ENV[$t]:-}
156+
157+
printf '\n[run] %s\n' "$bin"
158+
if ( cd "$d" && env $extra_env timeout 60 "./$t" ); then
159+
printf '[pass] %s\n\n' "$t"
160+
runs=$((runs+1))
161+
else
162+
rc=$?
163+
printf '\n::error title=Test failed::%s exited with status %d\n' "$t" "$rc"
164+
fails=$((fails+1))
165+
fi
166+
done
167+
done
168+
169+
printf '========================================\n'
170+
printf 'Summary\n'
171+
printf '========================================\n'
172+
printf ' Built: %d\n' "$builds"
173+
printf ' Ran: %d\n' "$runs"
174+
printf ' Failed: %d\n' "$fails"
175+
176+
if [[ $fails -gt 0 ]]; then
177+
exit 1
178+
fi

0 commit comments

Comments
 (0)