Skip to content

Commit 994257a

Browse files
authored
Merge pull request #626 from sysprog21/improve-cicd
Improve CI/CD
2 parents c9f1882 + 16862b0 commit 994257a

File tree

7 files changed

+193
-51
lines changed

7 files changed

+193
-51
lines changed

.ci/boot-linux-prepare.sh

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@ which mkfs.ext4 > /dev/null 2>&1 || which $(brew --prefix e2fsprogs)/sbin/mkfs.e
1616
echo "Error: mkfs.ext4 not found"
1717
exit 1
1818
}
19-
which 7z > /dev/null 2>&1 || {
20-
echo "Error: 7z not found"
21-
exit 1
22-
}
19+
# Optional tooling used later in the test suite
20+
if ! command -v debugfs > /dev/null 2>&1 && ! command -v 7z > /dev/null 2>&1; then
21+
print_warning "Neither debugfs nor 7z is available; virtio-blk verification will be skipped."
22+
fi
2323

2424
ACTION=$1
2525

.ci/boot-linux.sh

Lines changed: 63 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,54 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
66

77
check_platform
88

9-
function cleanup
9+
cleanup()
1010
{
1111
sleep 1
1212
pkill -9 rv32emu
1313
}
1414

15-
function ASSERT
15+
check_image_for_file()
16+
{
17+
local image_path=$1
18+
local file_path=$2
19+
local tool_available=0
20+
local debugfs_cmd
21+
22+
debugfs_cmd=$(command -v debugfs 2> /dev/null || true)
23+
if [ -z "${debugfs_cmd}" ] && [ -x /sbin/debugfs ]; then
24+
debugfs_cmd=/sbin/debugfs
25+
fi
26+
27+
if [ -n "${debugfs_cmd}" ]; then
28+
tool_available=1
29+
if "${debugfs_cmd}" -R "stat ${file_path}" "${image_path}" > /dev/null 2>&1; then
30+
return 0
31+
fi
32+
fi
33+
34+
if command -v 7z > /dev/null 2>&1; then
35+
tool_available=1
36+
if 7z l "${image_path}" | grep -q "${file_path}"; then
37+
return 0
38+
fi
39+
fi
40+
41+
if [ -n "${debugfs_cmd}" ]; then
42+
tool_available=1
43+
if sudo "${debugfs_cmd}" -R "stat ${file_path}" "${image_path}" > /dev/null 2>&1; then
44+
return 0
45+
fi
46+
fi
47+
48+
if [ "${tool_available}" -eq 0 ]; then
49+
print_warning "Skipping verification of ${file_path} in ${image_path}: neither debugfs nor 7z is available."
50+
return 0
51+
fi
52+
53+
return 1
54+
}
55+
56+
ASSERT()
1657
{
1758
$*
1859
local RES=$?
@@ -130,9 +171,12 @@ for i in "${!TEST_OPTIONS[@]}"; do
130171

131172
OPTS="${OPTS_BASE}"
132173
# No need to add option when running base test
133-
if [[ ! "${TEST_OPTIONS[$i]}" =~ "base" ]]; then
134-
OPTS+="${TEST_OPTIONS[$i]}"
135-
fi
174+
case "${TEST_OPTIONS[$i]}" in
175+
*base*) ;;
176+
*)
177+
OPTS+="${TEST_OPTIONS[$i]}"
178+
;;
179+
esac
136180
RUN_LINUX="build/rv32emu ${OPTS}"
137181

138182
ASSERT expect <<- DONE
@@ -145,13 +189,20 @@ for i in "${!TEST_OPTIONS[@]}"; do
145189
cleanup
146190

147191
printf "\nBoot Linux Test: [ ${MESSAGES[$ret]}${COLOR_N} ]\n"
148-
if [[ "${TEST_OPTIONS[$i]}" =~ vblk ]]; then
149-
# read-only test first, so the emu.txt definitely does not exist, skipping the check
150-
if [[ ! "${TEST_OPTIONS[$i]}" =~ readonly ]]; then
151-
7z l ${VBLK_IMG} | grep emu.txt > /dev/null 2>&1 || ret=4
152-
fi
153-
printf "Virtio-blk Test: [ ${MESSAGES[$ret]}${COLOR_N} ]\n"
154-
fi
192+
case "${TEST_OPTIONS[$i]}" in
193+
*vblk*)
194+
# read-only test first, so the emu.txt definitely does not exist, skipping the check
195+
case "${TEST_OPTIONS[$i]}" in
196+
*readonly*) ;;
197+
*)
198+
if ! check_image_for_file "${VBLK_IMG}" emu.txt; then
199+
ret=4
200+
fi
201+
;;
202+
esac
203+
printf "Virtio-blk Test: [ ${MESSAGES[$ret]}${COLOR_N} ]\n"
204+
;;
205+
esac
155206
done
156207

157208
exit ${ret}

.ci/check-format.sh

Lines changed: 51 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,31 +4,58 @@
44

55
set -u -o pipefail
66

7-
set -x
8-
97
REPO_ROOT="$(git rev-parse --show-toplevel)"
108

11-
C_SOURCES=$(find "${REPO_ROOT}" | egrep "\.(c|cxx|cpp|h|hpp)$")
12-
for file in ${C_SOURCES}; do
13-
clang-format-18 ${file} > expected-format
14-
diff -u -p --label="${file}" --label="expected coding style" ${file} expected-format
15-
done
16-
C_MISMATCH_LINE_CNT=$(clang-format-18 --output-replacements-xml ${C_SOURCES} | egrep -c "</replacement>")
17-
18-
SH_SOURCES=$(find "${REPO_ROOT}" | egrep "\.sh$")
19-
for file in ${SH_SOURCES}; do
20-
shfmt -d "${file}"
21-
done
22-
SH_MISMATCH_FILE_CNT=$(shfmt -l ${SH_SOURCES})
23-
24-
PY_SOURCES=$(find "${REPO_ROOT}" | egrep "\.py$")
25-
for file in ${PY_SOURCES}; do
26-
echo "Checking Python file: ${file}"
27-
black --diff "${file}"
28-
done
29-
PY_MISMATCH_FILE_CNT=0
30-
if [ -n "${PY_SOURCES}" ]; then
31-
PY_MISMATCH_FILE_CNT=$(echo "$(black --check ${PY_SOURCES} 2>&1)" | grep -c "^would reformat ")
9+
# Use git ls-files to exclude submodules and untracked files
10+
C_SOURCES=()
11+
while IFS= read -r file; do
12+
[ -n "$file" ] && C_SOURCES+=("$file")
13+
done < <(git ls-files -- '*.c' '*.cxx' '*.cpp' '*.h' '*.hpp')
14+
15+
if [ ${#C_SOURCES[@]} -gt 0 ]; then
16+
if command -v clang-format-18 > /dev/null 2>&1; then
17+
echo "Checking C/C++ files..."
18+
clang-format-18 -n --Werror "${C_SOURCES[@]}"
19+
C_FORMAT_EXIT=$?
20+
else
21+
echo "Skipping C/C++ format check: clang-format-18 not found" >&2
22+
C_FORMAT_EXIT=0
23+
fi
24+
else
25+
C_FORMAT_EXIT=0
26+
fi
27+
28+
SH_SOURCES=()
29+
while IFS= read -r file; do
30+
[ -n "$file" ] && SH_SOURCES+=("$file")
31+
done < <(git ls-files -- '*.sh')
32+
33+
if [ ${#SH_SOURCES[@]} -gt 0 ]; then
34+
echo "Checking shell scripts..."
35+
MISMATCHED_SH=$(shfmt -l "${SH_SOURCES[@]}")
36+
if [ -n "$MISMATCHED_SH" ]; then
37+
echo "The following shell scripts are not formatted correctly:"
38+
printf '%s\n' "$MISMATCHED_SH"
39+
shfmt -d "${SH_SOURCES[@]}"
40+
SH_FORMAT_EXIT=1
41+
else
42+
SH_FORMAT_EXIT=0
43+
fi
44+
else
45+
SH_FORMAT_EXIT=0
46+
fi
47+
48+
PY_SOURCES=()
49+
while IFS= read -r file; do
50+
[ -n "$file" ] && PY_SOURCES+=("$file")
51+
done < <(git ls-files -- '*.py')
52+
53+
if [ ${#PY_SOURCES[@]} -gt 0 ]; then
54+
echo "Checking Python files..."
55+
black --check --diff "${PY_SOURCES[@]}"
56+
PY_FORMAT_EXIT=$?
57+
else
58+
PY_FORMAT_EXIT=0
3259
fi
3360

34-
exit $((C_MISMATCH_LINE_CNT + SH_MISMATCH_FILE_CNT + PY_MISMATCH_FILE_CNT))
61+
exit $((C_FORMAT_EXIT + SH_FORMAT_EXIT + PY_FORMAT_EXIT))

.ci/common.sh

Lines changed: 67 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
# Bash strict mode (enabled only when executed directly, not sourced)
2+
if ! (return 0 2> /dev/null); then
3+
set -euo pipefail
4+
fi
5+
16
# Expect host is Linux/x86_64, Linux/aarch64, macOS/arm64
27

38
MACHINE_TYPE=$(uname -m)
@@ -15,12 +20,67 @@ check_platform()
1520
esac
1621
}
1722

18-
if [[ "${OS_TYPE}" == "Linux" ]]; then
23+
if [ "${OS_TYPE}" = "Linux" ]; then
1924
PARALLEL=-j$(nproc)
2025
else
2126
PARALLEL=-j$(sysctl -n hw.logicalcpu)
2227
fi
2328

29+
# Color output helpers
30+
RED='\033[0;31m'
31+
GREEN='\033[0;32m'
32+
YELLOW='\033[1;33m'
33+
NC='\033[0m' # No Color
34+
35+
print_success()
36+
{
37+
echo -e "${GREEN}[SUCCESS]${NC} $1"
38+
}
39+
40+
print_error()
41+
{
42+
echo -e "${RED}[ERROR]${NC} $1" >&2
43+
}
44+
45+
print_warning()
46+
{
47+
echo -e "${YELLOW}[WARNING]${NC} $1"
48+
}
49+
50+
# Assertion function for tests
51+
# Usage: ASSERT <condition> <error_message>
52+
ASSERT()
53+
{
54+
local condition=$1
55+
shift
56+
local message="$*"
57+
58+
if ! eval "${condition}"; then
59+
print_error "Assertion failed: ${message}"
60+
print_error "Condition: ${condition}"
61+
return 1
62+
fi
63+
}
64+
65+
# Cleanup function registry
66+
CLEANUP_FUNCS=()
67+
68+
register_cleanup()
69+
{
70+
CLEANUP_FUNCS+=("$1")
71+
}
72+
73+
cleanup()
74+
{
75+
local func
76+
for func in "${CLEANUP_FUNCS[@]-}"; do
77+
[ -n "${func}" ] || continue
78+
eval "${func}" || true
79+
done
80+
}
81+
82+
trap cleanup EXIT
83+
2484
# Universal download utility with curl/wget compatibility
2585
# Provides consistent interface regardless of which tool is available
2686

@@ -49,7 +109,7 @@ download_to_stdout()
49109
local url="$1"
50110
case "$DOWNLOAD_TOOL" in
51111
curl)
52-
curl -fsSL "$url"
112+
curl -fS --retry 5 --retry-delay 2 --retry-max-time 60 -sL "$url"
53113
;;
54114
wget)
55115
wget -qO- "$url"
@@ -66,7 +126,7 @@ download_to_file()
66126
local output="$2"
67127
case "$DOWNLOAD_TOOL" in
68128
curl)
69-
curl -fsSL -o "$output" "$url"
129+
curl -fS --retry 5 --retry-delay 2 --retry-max-time 60 -sL -o "$output" "$url"
70130
;;
71131
wget)
72132
wget -q -O "$output" "$url"
@@ -88,7 +148,7 @@ download_with_headers()
88148
for header in "$@"; do
89149
headers+=(-H "$header")
90150
done
91-
curl -fsSL "${headers[@]}" "$url"
151+
curl -fS --retry 5 --retry-delay 2 --retry-max-time 60 -sL "${headers[@]}" "$url"
92152
;;
93153
wget)
94154
for header in "$@"; do
@@ -107,7 +167,7 @@ download_silent()
107167
local url="$1"
108168
case "$DOWNLOAD_TOOL" in
109169
curl)
110-
curl -fsSL "$url"
170+
curl -fS --retry 5 --retry-delay 2 --retry-max-time 60 -sL "$url"
111171
;;
112172
wget)
113173
wget -qO- "$url"
@@ -124,7 +184,7 @@ download_with_progress()
124184
local output="$2"
125185
case "$DOWNLOAD_TOOL" in
126186
curl)
127-
curl -fL -# -o "$output" "$url"
187+
curl -fS --retry 5 --retry-delay 2 --retry-max-time 60 -L -# -o "$output" "$url"
128188
;;
129189
wget)
130190
wget -O "$output" "$url"
@@ -141,7 +201,7 @@ check_url()
141201
local url="$1"
142202
case "$DOWNLOAD_TOOL" in
143203
curl)
144-
curl -fsSL --head "$url" > /dev/null 2>&1
204+
curl -fS --retry 5 --retry-delay 2 --retry-max-time 60 -sL --head "$url" > /dev/null 2>&1
145205
;;
146206
wget)
147207
wget --spider -q "$url" 2> /dev/null

.ci/gdbstub-test.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ prefixes=("${CROSS_COMPILE}" "riscv32-unknown-elf-" "riscv-none-elf-")
99
for prefix in "${prefixes[@]}"; do
1010
utility=${prefix}gdb
1111
set +e # temporarily disable exit on error
12-
command -v "${utility}" &> /dev/null
13-
if [[ $? == 0 ]]; then
12+
command -v "${utility}" > /dev/null 2>&1
13+
if [ $? = 0 ]; then
1414
GDB=${utility}
1515
fi
1616
set -e

.ci/riscv-toolchain-install.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
99
check_platform
1010
mkdir -p toolchain
1111

12-
if [[ "$#" == "0" ]] || [[ "$1" != "riscv-collab" ]]; then
12+
if [ "$#" = "0" ] || [ "$1" != "riscv-collab" ]; then
1313
GCC_VER=15.2.0-1
1414
TOOLCHAIN_REPO=https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack
1515

16-
if [[ "${OS_TYPE}" == "Linux" ]]; then
16+
if [ "${OS_TYPE}" = "Linux" ]; then
1717
case "${MACHINE_TYPE}" in
1818
"x86_64")
1919
TOOLCHAIN_URL=${TOOLCHAIN_REPO}/releases/download/v${GCC_VER}/xpack-riscv-none-elf-gcc-${GCC_VER}-linux-x64.tar.gz

.github/workflows/main.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,10 @@ jobs:
345345
.ci/riscv-toolchain-install.sh
346346
echo "${{ github.workspace }}/toolchain/bin" >> $GITHUB_PATH
347347
echo "$(brew --prefix llvm@18)/bin" >> $GITHUB_PATH
348+
- name: Set up Python 3.12
349+
uses: actions/setup-python@v6
350+
with:
351+
python-version: '3.12'
348352
- name: Install compiler
349353
id: install_cc
350354
uses: rlalik/setup-cpp-compiler@master

0 commit comments

Comments
 (0)