-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathrun-ci.sh
executable file
·178 lines (159 loc) · 5.02 KB
/
run-ci.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
#!/usr/bin/env bash
## Run NuttX CI with Docker:
## sudo apt install gh glab
## cd $HOME/nuttx-release && sudo sh -c '. ../github-token.sh && ./run-ci.sh '$TMUX_PANE
## cd $HOME/nuttx-release && sudo sh -c '. ../gitlab-token.sh && ./run-ci.sh '$TMUX_PANE
## Change $TMUX_PANE to a Unique Instance ID. Each instance of this script will run under a different Instance ID.
## GitHub Token: Should have Gist Permission
## github-token.sh contains:
## export GITHUB_TOKEN=...
## GitLab Token: User Settings > Access tokens > Select Scopes
## api: Grants complete read/write access to the API, including all groups and projects, the container registry, the dependency proxy, and the package registry.
## gitlab-token.sh contains:
## export GITLAB_TOKEN=...
## export GITLAB_USER=lupyuen
## export GITLAB_REPO=nuttx-build-log
## Which means the GitLab Snippets will be created in the existing GitLab Repo "lupyuen/nuttx-build-log"
## Read the article: https://lupyuen.codeberg.page/articles/ci2.html
echo Now running https://github.com/lupyuen/nuttx-release/blob/main/run-ci.sh $1
set -x ## Echo commands
# Optional Parameter is Instance ID, like 1.
# Each instance of this script will run under a different Instance ID.
instance=$1
device=ci$instance
## Get the Script Directory
script_path="${BASH_SOURCE}"
script_dir="$(cd -P "$(dirname -- "${script_path}")" >/dev/null 2>&1 && pwd)"
log_file=/tmp/release-$device.log
## Get the `script` option
if [ "`uname`" == "Linux" ]; then
script_option=-c
else
script_option=
fi
## Run the job
function run_job {
local job=$1
pushd /tmp
script $log_file \
$script_option \
"$script_dir/run-job.sh $job $instance"
popd
}
## Strip the control chars
function clean_log {
local tmp_file=/tmp/release-$device-tmp.log
cat $log_file \
| tr -d '\r' \
| tr -d '\r' \
| sed 's/\x08/ /g' \
| sed 's/\x1B(B//g' \
| sed 's/\x1B\[K//g' \
| sed 's/\x1B[<=>]//g' \
| sed 's/\x1B\[[0-9:;<=>?]*[!]*[A-Za-z]//g' \
| sed 's/\x1B[@A-Z\\\]^_]\|\x1B\[[0-9:;<=>?]*[-!"#$%&'"'"'()*+,.\/]*[][\\@A-Z^_`a-z{|}~]//g' \
| cat -v \
>$tmp_file
mv $tmp_file $log_file
echo ----- "Done! $log_file"
}
## Search for Errors and Warnings
function find_messages {
local tmp_file=/tmp/release-$device-tmp.log
local msg_file=/tmp/release-$device-msg.log
local pattern='^(.*):(\d+):(\d+):\s+(warning|fatal error|error):\s+(.*)$'
grep '^\*\*\*\*\*' $log_file \
> $msg_file
grep -P "$pattern" $log_file \
| uniq \
>> $msg_file
cat $msg_file $log_file >$tmp_file
mv $tmp_file $log_file
}
## Upload to GitLab Snippet or GitHub Gist
function upload_log {
local job=$1
local nuttx_hash=$2
local apps_hash=$3
local desc="[$job] CI Log for nuttx @ $nuttx_hash / nuttx-apps @ $apps_hash"
local filename="ci-$job.log"
if [[ "$GITLAB_TOKEN" != "" ]]; then
if [[ "$GITLAB_USER" == "" ]]; then
echo '$GITLAB_USER is missing (e.g. lupyuen)'
exit 1
fi
if [[ "$GITLAB_REPO" == "" ]]; then
echo '$GITLAB_REPO is missing (e.g. nuttx-build-log)'
exit 1
fi
cat $log_file | \
glab snippet new \
--repo "$GITLAB_USER/$GITLAB_REPO" \
--visibility public \
--title "$desc" \
--filename "$filename"
else
cat $log_file | \
gh gist create \
--public \
--desc "$desc" \
--filename "$filename"
fi
}
## Skip to a Random CI Job. Assume max 32 CI Jobs.
let "skip = $RANDOM % 32"
echo Skipping $skip CI Jobs...
## Repeat forever for All CI Jobs
## risc-v-07: Python Build runs only on NuttX Build Farm, not GitHub CI, because it's costly to compile
## https://github.com/apache/nuttx/pull/15099#issuecomment-2537525041
for (( ; ; )); do
for job in \
arm-01 arm-02 arm-03 arm-04 \
arm-05 arm-06 arm-07 arm-08 \
arm-09 arm-10 arm-11 arm-12 \
arm-13 arm-14 \
arm64-01 \
other \
risc-v-01 risc-v-02 risc-v-03 risc-v-04 \
risc-v-05 risc-v-06 risc-v-07 \
sim-01 sim-02 sim-03 \
x86_64-01 \
xtensa-01 xtensa-02 xtensa-03
do
## Skip to a Random CI Job
if [[ $skip -gt 0 ]]; then
let skip--
continue
fi
## Run the CI Job and find errors / warnings
run_job $job
clean_log
find_messages
## Get the hashes for NuttX and Apps
nuttx_hash=$(
cat $log_file \
| grep --only-matching -E "nuttx/tree/[0-9a-z]+" \
| grep --only-matching -E "[0-9a-z]+$" --max-count=1
)
apps_hash=$(
cat $log_file \
| grep --only-matching -E "nuttx-apps/tree/[0-9a-z]+" \
| grep --only-matching -E "[0-9a-z]+$" --max-count=1
)
## Upload the log
upload_log $job $nuttx_hash $apps_hash
## Sleep a while. Quit on I/O Error.
set -e ## Exit when any command fails
sleep 10
set +e ## Ignore errors
done
## Free up the Docker disk space
sudo docker system prune --force
done
## Here's how we delete the 20 latest gists
function delete_gists {
local gist_ids=$(sudo gh gist list --limit 20 | cut --fields=1)
for gist_id in $gist_ids; do
sudo gh gist delete $gist_id
done
}