GitRoot
Craft your forge, Build your project, Grow your community freely
1#!/usr/bin/env bash
2
3# SPDX-FileCopyrightText: 2025 Romain Maneschi <romain@gitroot.dev>
4#
5# SPDX-License-Identifier: EUPL-1.2
6
7trap 'catch $LINENO' ERR
8
9MY_LOG=${MY_LOG:-"/tmp/mylog.txt"}
10EXPECTED_ERROR=0
11
12catch() {
13 if [[ $EXPECTED_ERROR == 0 ]]; then
14 echo "🛑 unexpected error line $1"
15 exit 1
16 fi
17 report "🟢 expected err line $1"
18}
19
20mySleep() {
21 echo "🕐 wait $1"
22 echo "🕐 $1" >> $MY_LOG
23 sleep $1
24}
25
26function wait_for() {
27 start=`date +%s`
28 timeout=100
29 until [ $timeout -le 0 ] || (grep -q $1 $2 &> /dev/null); do
30 sleep 0.1
31 timeout=$(( timeout - 1 ))
32 done
33 if [ $timeout -le 0 ]; then
34 return 1
35 fi
36 end=`date +%s`
37 echo "🕐 $@ in `expr $end - $start` seconds"
38}
39
40function wait_ls() {
41 local start=$(date +%s)
42 local timeout=500
43 local target="$1"
44
45 until [ $timeout -le 0 ]; do
46 count=$(find "$target" -maxdepth 1 -mindepth 1 2>/dev/null | wc -l)
47 if [ "$count" -eq 3 ]; then
48 break
49 fi
50 sleep 0.1
51 ((timeout--))
52 done
53 if [ $timeout -le 0 ]; then
54 return 1
55 fi
56 local end=`date +%s`
57 echo "🕐 $@ in `expr $end - $start` seconds"
58 mySleep 0.3
59}
60
61function init_local_git() {
62 git config commit.gpgSign true
63 git config gpg.format ssh
64 git config user.signingkey $3
65 git config core.sshCommand "ssh -i ${4} -o IdentitiesOnly=yes"
66 git config user.email "$1"
67 git config user.name "$2"
68 git config gpg.ssh.allowedSignersFile "$(pwd)/.gitroot/allowed_signers"
69 echo "$1 $(cat $3)" >> "$(pwd)/.gitroot/allowed_signers"
70}
71
72EXIT_CODE=0
73
74SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
75
76source "${SCRIPT_DIR}/lib/pushandwait.sh"
77source "${SCRIPT_DIR}/lib/git.sh"
78source "${SCRIPT_DIR}/lib/report.sh"
79
80SERVER_PORT=${SERVER_PORT:-4545}
81SERVER_PORT_HTTP=${SERVER_PORT_HTTP:-4546}
82SERVER_URL=${1:-"127.0.0.1:$SERVER_PORT"}
83SERVER_DATA_DIR="/tmp/gitrootData"
84
85ROOT_REPO_NAME="root"
86ROOT_REPO_URL="ssh://${SERVER_URL}/${ROOT_REPO_NAME}"
87REPO1_NAME="repo1"
88REPO1_URL="ssh://user@${SERVER_URL}/${REPO1_NAME}"
89REPO2_NAME="repo2"
90REPO2_URL="ssh://user@${SERVER_URL}/${REPO2_NAME}"
91REPO3_NAME="repo3"
92REPO3_URL="ssh://user@${SERVER_URL}/${REPO3_NAME}"
93
94SSH_KEY="${SCRIPT_DIR}/user1/ed25519"
95SSH_KEY2="${SCRIPT_DIR}/user2/ed25519"
96
97LADYBUG_WASM="pkg://gitroot/gitroot/ladybug@0.0.5?registry=file://${SCRIPT_DIR}/../plugins/ladybug&checksum=none"
98SILO_WASM="pkg://gitroot/gitroot/silo@0.0.5?registry=file://${SCRIPT_DIR}/../plugins/silo&checksum=none"
99GRAFTER_WASM="pkg://gitroot/gitroot/grafter@0.0.5?registry=file://${SCRIPT_DIR}/../plugins/grafter&checksum=none"
100APEX_WASM="pkg://gitroot/gitroot/apex@0.0.5?registry=file://${SCRIPT_DIR}/../plugins/apex&checksum=none"
101APEX_MARKDOWN_WASM="pkg://gitroot/gitroot/apex_markdown@0.0.5?registry=file://${SCRIPT_DIR}/../plugins/apex&checksum=none"
102APEX_CODE_WASM="pkg://gitroot/gitroot/apex_code@0.0.5?registry=file://${SCRIPT_DIR}/../plugins/apex&checksum=none"
103APEX_CODE_MERMAID_WASM="pkg://gitroot/gitroot/apex_mermaid@0.0.2?registry=file://${SCRIPT_DIR}/../plugins/apex_mermaid&checksum=none"
104POLLEN_WASM="pkg://gitroot/gitroot/pollen@0.0.4?registry=file://${SCRIPT_DIR}/../plugins/pollen&checksum=none"
105HOP_WASM="pkg://gitroot/gitroot/hop@0.0.3?registry=file://${SCRIPT_DIR}/../plugins/hop&checksum=none"
106STIGMA_WASM="pkg://gitroot/gitroot/stigma@0.0.2?registry=file://${SCRIPT_DIR}/../plugins/stigma&checksum=none"
107
108##### clean
109report "🏁 clean"
110
111cd /tmp
112rm -rf ${SERVER_DATA_DIR}
113rm -rf ${ROOT_REPO_NAME}
114rm -rf ${ROOT_REPO_NAME}_2
115rm -rf ${REPO1_NAME}
116rm -rf ${REPO2_NAME}
117rm -rf ${REPO1_NAME}_2
118rm -rf ${REPO2_NAME}_2
119rm -rf ${REPO3_NAME}
120rm -f ${MY_LOG}
121APP=$(lsof -i tcp:${SERVER_PORT} | awk 'NR!=1 {print $2}')
122if [ -z "$APP" ]; then
123 report "🟢 Gitroot not launched"
124else
125 kill ${APP}
126 report "🟢 Gitroot killed"
127fi
128ssh-keygen -f "$HOME/.ssh/known_hosts" -R "[127.0.0.1]:$SERVER_PORT"
129
130##### launch gitroot
131report "🏁 launch gitroot"
132
133cd ${SCRIPT_DIR}/../server
134mkdir -p "${SERVER_DATA_DIR}"
135go run -race . -initConfig="${SERVER_DATA_DIR}/config"
136sed -i -e "s/sshaddr: 0.0.0.0:4545/sshaddr: 0.0.0.0:$SERVER_PORT/g" "${SERVER_DATA_DIR}/config"
137sed -i -e "s/httpaddr: 0.0.0.0:4546/httpaddr: 0.0.0.0:$SERVER_PORT_HTTP/g" "${SERVER_DATA_DIR}/config"
138GIT_TRACE_PACKET=false go run -race . -data="${SERVER_DATA_DIR}" -config="${SERVER_DATA_DIR}/config" &>> $MY_LOG &
139
140wait_for "starting SSH server on" $MY_LOG
141
142##### forgeConfig
143report "🏁 forgeConfig"
144
145cd /tmp
146quiet_git clone -c "core.sshCommand=ssh -i ${SSH_KEY} -o IdentitiesOnly=yes -o StrictHostKeyChecking=accept-new" ${ROOT_REPO_URL}
147cd ${ROOT_REPO_NAME}
148init_local_git forgeConfig@gitroot.dev forgeConfig ${SSH_KEY}.pub ${SSH_KEY}
149
150printf "${REPO1_NAME}:\n defaultbranch: main" >> .gitroot/repositories.yml
151quiet_git add .
152quiet_git commit -m "create first repo"
153quiet_git push origin main
154report "🟢 ${ROOT_REPO_NAME} push first repo"
155
156mySleep 0.05
157
158##### Repo1
159report "🏁 Repo1"
160
161cd /tmp
162GIT_SSH_COMMAND="ssh -i ${SSH_KEY} -o IdentitiesOnly=yes" quiet_git clone --quiet "${REPO1_URL}"
163cd ${REPO1_NAME}
164init_local_git repo1@gitroot.dev user1 ${SSH_KEY}.pub ${SSH_KEY}
165
166quiet_git add .
167quiet_git commit -m "init user"
168report "🟢 ${REPO1_NAME} commit user"
169
170quiet_git checkout -b "branch1"
171quiet_git push origin main branch1
172report "🟢 ${REPO1_NAME} push main+branch1"
173quiet_git checkout main
174quiet_git push origin :branch1
175report "🟢 ${REPO1_NAME} delete :branch1"
176quiet_git push origin main
177report "🟢 ${REPO1_NAME} push empty main"
178
179##### first plugin
180report "🏁 first plugin"
181
182cd /tmp/${ROOT_REPO_NAME}
183echo "- purl: ${LADYBUG_WASM}" >> .gitroot/plugins.yml
184quiet_git add .
185quiet_git commit -m "init ladybug plugin"
186printf "\n${REPO2_NAME}:\n defaultbranch: main" >> .gitroot/repositories.yml
187quiet_git add .
188quiet_git commit -m "create second repo"
189quiet_git push origin main
190report "🟢 ${ROOT_REPO_NAME} push first plugin and second repo"
191
192wait_ls "${SERVER_DATA_DIR}/data/plugins/gitroot-ladybug"
193
194if [[ $(ls "${SERVER_DATA_DIR}/data/plugins/gitroot-ladybug" | wc -l) -eq 3 ]]; then
195 report "🟢 ${SERVER_DATA_DIR}/data/plugins/gitroot-ladybug loaded"
196else
197 report "🛑 ${SERVER_DATA_DIR}/data/plugins/gitroot-ladybug not downloaded"
198 EXIT_CODE=1
199fi
200
201quiet_git pull origin main
202
203if grep -Fxq " - path: issues/**/*.md" .gitroot/plugins.yml
204then
205 report "🟢 ${ROOT_REPO_NAME} plugin ladybug initialized"
206else
207 report "🛑 ${ROOT_REPO_NAME} plugin ladybug not initialized"
208 EXIT_CODE=1
209fi
210
211if grep -Fxq " metadata:" .gitroot/plugins.yml
212then
213 report "🟢 ${ROOT_REPO_NAME} plugin config initialized"
214else
215 report "🛑 ${ROOT_REPO_NAME} not initialized"
216 EXIT_CODE=1
217fi
218
219if grep -Fxq " - gitroot-ladybug@localhost" .gitroot/users.yml
220then
221 report "🟢 ${ROOT_REPO_NAME} plugin user initialized"
222else
223 report "🛑 ${ROOT_REPO_NAME} plugin user not initialized"
224 EXIT_CODE=1
225fi
226
227cd /tmp
228GIT_SSH_COMMAND="ssh -i ${SSH_KEY} -o IdentitiesOnly=yes" quiet_git clone --quiet "${REPO2_URL}"
229cd ${REPO2_NAME}
230init_local_git repo2@gitroot.dev user1 ${SSH_KEY}.pub ${SSH_KEY}
231
232if grep -Fxq " metadata:" .gitroot/plugins.yml
233then
234 report "🟢 ${REPO2_NAME} plugin config initialized"
235else
236 report "🛑 ${REPO2_NAME} not initialized"
237 EXIT_CODE=1
238fi
239
240if grep -q " - path: issues/\\*\\*/\\*.md" .gitroot/plugins.yml
241then
242 report "🟢 ${REPO2_NAME} plugin path initialized"
243else
244 report "🛑 ${REPO2_NAME} not initialized"
245 EXIT_CODE=1
246fi
247
248sed -i -e 's/active: false/active: true/g' .gitroot/plugins.yml
249
250mkdir issues
251echo "#my Issue" >> issues/1.md
252echo "Beatiful issue" >> issues/1.md
253quiet_git add .
254quiet_git commit -m "first issue in second repo"
255quiet_git push origin main
256report "🟢 ${REPO2_NAME} first issue in second repo"
257
258mySleep 0.05
259
260quiet_git pull
261
262if grep -q "priority: 50" issues/1.md
263then
264 report "🟢 issues/1.md initialized"
265else
266 report "🛑 issues/1.md not initialized"
267 EXIT_CODE=1
268fi
269
270##### repo1 should have issue available
271report "🏁 repo1 should have issue available"
272
273cd /tmp/${REPO1_NAME}
274
275quiet_git pull
276
277if grep -q " - path: issues/\\*\\*/\\*.md" .gitroot/plugins.yml
278then
279 report "🟢 ${REPO1_NAME} plugin path initialized"
280else
281 report "🛑 ${REPO1_NAME} not initialized"
282 EXIT_CODE=1
283fi
284
285sed -i -e 's/active: false/active: true/g' .gitroot/plugins.yml
286
287mkdir issues
288echo "#my Issue" >> issues/1.md
289echo "Beatiful issue" >> issues/1.md
290quiet_git add .
291quiet_git commit -m "first issue in first repo"
292quiet_git push origin main
293report "🟢 ${REPO1_NAME} first issue in first repo"
294
295mySleep 0.05
296
297quiet_git pull
298
299if grep -q "priority: 50" issues/1.md
300then
301 report "🟢 issues/1.md initialized"
302else
303 report "🛑 issues/1.md not initialized"
304 EXIT_CODE=1
305fi
306
307##### user2 rights
308report "🏁 user2 rights"
309
310cd /tmp
311GIT_SSH_COMMAND="ssh -i ${SSH_KEY2} -o IdentitiesOnly=yes" quiet_git clone --quiet "${REPO1_URL}" ${REPO1_NAME}_2
312cd ${REPO1_NAME}_2
313git config core.sshCommand "ssh -i ${SSH_KEY2} -o IdentitiesOnly=yes"
314git config user.email user2repo1@gitroot.dev
315git config user.name user2
316
317echo "# my Issue" >> issues/cac-1.md
318echo "Beatiful issue" >> issues/cac-1.md
319
320quiet_git add .
321quiet_git commit -m "user2 config and add an issue"
322EXPECTED_ERROR=1
323quiet_git push origin main
324if [[ "$?" == "0" ]]; then
325 report "🛑 user2 has push on main in repo1"
326 EXIT_CODE=1
327else
328 report "🟢 user2 can not push on main in repo1"
329fi
330EXPECTED_ERROR=0
331
332quiet_git reset --soft HEAD~1
333quiet_git checkout -b user2_branch_on_repo1
334quiet_git add .
335quiet_git commit -m "user2 config and an issue"
336
337echo "# my Issue" >> issues/cac-2.md
338echo "Beatiful issue" >> issues/cac-2.md
339quiet_git add .
340quiet_git commit -m "issue cac2"
341
342quiet_git push origin user2_branch_on_repo1
343
344if [[ "$?" == "0" ]]; then
345 report "🟢 user2 can push on user2_branch_on_repo1 branch in repo1"
346else
347 report "🛑 user2 can not push on user2_branch_on_repo1 branch in repo1"
348 EXIT_CODE=1
349fi
350
351mySleep 0.05
352quiet_git pull origin user2_branch_on_repo1
353
354if grep -q "priority: 50" issues/cac-1.md
355then
356 report "🟢 issues/cac-1.md initialized"
357else
358 report "🛑 issues/cac-1.md not initialized"
359 EXIT_CODE=1
360fi
361
362echo "New readme" > "README.md"
363quiet_git add .
364quiet_git commit -m "update readme"
365quiet_git push origin user2_branch_on_repo1
366
367if [[ "$?" == "0" ]]; then
368 report "🟢 user2 can push on user2_branch_on_repo1 branch in repo1 second time"
369else
370 report "🛑 user2 can not push on user2_branch_on_repo1 branch in repo1 second time"
371 EXIT_CODE=1
372fi
373
374quiet_git checkout main
375
376cd /tmp/${REPO1_NAME}
377quiet_git fetch origin user2_branch_on_repo1
378quiet_git checkout user2_branch_on_repo1
379
380echo "New readme by user 1" > "README.md"
381quiet_git add .
382quiet_git commit -m "update readme"
383quiet_git push origin user2_branch_on_repo1
384report "🟢 user1 can push on user2_branch_on_repo1 branch in repo1"
385
386quiet_git checkout main
387
388##### second plugin
389report "🏁 second plugin"
390
391cd /tmp/${ROOT_REPO_NAME}
392echo "- purl: ${SILO_WASM}" >> .gitroot/plugins.yml
393quiet_git add .
394quiet_git commit -m "init silo plugin"
395quiet_git push origin main
396echo "🟢 ${ROOT_REPO_NAME} push second plugin"
397
398wait_ls "${SERVER_DATA_DIR}/data/plugins/gitroot-silo"
399
400quiet_git pull origin main
401
402cd /tmp/${REPO1_NAME}
403
404quiet_git pull
405
406if grep -q "title: "Roadmaps"" .gitroot/plugins.yml
407then
408 report "🟢 ${REPO1_NAME} plugin path initialized"
409else
410 report "🛑 ${REPO1_NAME} not initialized"
411 EXIT_CODE=1
412fi
413
414sed -i -e 's/active: false/active: true/g' .gitroot/plugins.yml
415
416echo "---" >> issues/roadmap1.md
417echo "id: 22C3" >> issues/roadmap1.md
418echo "priority: 50" >> issues/roadmap1.md
419echo "assignee: null" >> issues/roadmap1.md
420echo "kind: 'roadmap'" >> issues/roadmap1.md
421echo "---" >> issues/roadmap1.md
422echo "# step 1: conquers the world" >> issues/roadmap1.md
423echo "" >> issues/roadmap1.md
424echo "To do that just imagine the world is small." >> issues/roadmap1.md
425
426echo "---" >> issues/roadmap2.md
427echo "id: 22C3" >> issues/roadmap2.md
428echo "priority: 10" >> issues/roadmap2.md
429echo "assignee: null" >> issues/roadmap2.md
430echo "kind: 'roadmap'" >> issues/roadmap2.md
431echo "---" >> issues/roadmap2.md
432echo "# step 2: profit" >> issues/roadmap2.md
433echo "" >> issues/roadmap2.md
434echo "Finally take in peace." >> issues/roadmap2.md
435
436quiet_git add .
437quiet_git commit -m "active silo and build first roadmap ticket"
438quiet_git push origin main
439
440mySleep 0.1
441
442quiet_git pull
443
444if grep -q "issues/roadmap1.md" boards/roadmap.md
445then
446 report "🟢 ${REPO1_NAME} roadmap initialized"
447else
448 report "🛑 ${REPO1_NAME} roadmap not initialized"
449 EXIT_CODE=1
450fi
451
452if grep -q "issues/1.md" boards/issues.md
453then
454 report "🟢 ${REPO1_NAME} issues board initialized"
455else
456 report "🛑 ${REPO1_NAME} issues board not initialized"
457 EXIT_CODE=1
458fi
459
460if grep -q "issues/1.md" boards/triage.md
461then
462 report "🟢 ${REPO1_NAME} triage board initialized"
463else
464 report "🛑 ${REPO1_NAME} triage board not initialized"
465 EXIT_CODE=1
466fi
467
468quiet_git pull --rebase origin main
469
470for (( i=0; i<=50; i++ ))
471do
472 echo "# My issue $i" >> issues/issue_$i.md
473 echo "" >> issues/issue_$i.md
474 echo "Beatiful issue" >> issues/issue_$i.md
475done
476
477quiet_git add .
478quiet_git commit -m "create lot of issues"
479quiet_git push origin main
480
481mySleep 0.5
482
483quiet_git pull
484
485for (( i=0; i<=50; i++ ))
486do
487 PRIO=$(shuf -i 0-99 -n 1)
488 sed -i -e "s/priority: 50/priority: $PRIO/g" issues/issue_$i.md
489done
490
491quiet_git add .
492quiet_git commit -m "update random prio of lot of issues"
493quiet_git push origin main
494
495mySleep 0.05
496
497quiet_git pull
498
499##### Repo2 don't allow anonymous contrib
500report "🏁 Repo2 don't allow anonymous contrib"
501
502cd /tmp/${REPO2_NAME}
503
504quiet_git pull
505
506echo "" >> .gitroot/users.yml
507echo "\"*\":" >> .gitroot/users.yml
508echo " branches:" >> .gitroot/users.yml
509echo " - name: \"*\"" >> .gitroot/users.yml
510echo " users: []" >> .gitroot/users.yml
511
512quiet_git add .
513quiet_git commit -m "block all modifications of anonymous users"
514quiet_git push origin main
515
516cd /tmp
517GIT_SSH_COMMAND="ssh -i ${SSH_KEY2} -o IdentitiesOnly=yes" quiet_git clone --quiet "${REPO2_URL}" ${REPO2_NAME}_2
518cd ${REPO2_NAME}_2
519init_local_git user2repo2@gitroot.dev user2 ${SSH_KEY2}.pub ${SSH_KEY2}
520
521quiet_git checkout -b tryToAddMe
522quiet_git add .
523quiet_git commit -m "user2 config"
524
525EXPECTED_ERROR=1
526quiet_git push origin tryToAddMe
527if [[ "$?" == "0" ]]; then
528 report "🛑 user2 can push on tryToAddMe branch in repo2"
529 EXIT_CODE=1
530else
531 report "🟢 user2 can not push on tryToAddMe branch in repo2"
532fi
533EXPECTED_ERROR=0
534
535##### User2 can add issue in repo1 on branch user2_issue_on_repo1
536report "🏁 User2 can add issue in repo1 on branch user2_issue_on_repo1"
537
538cd /tmp/${REPO1_NAME}_2
539
540quiet_git pull origin main
541
542quiet_git checkout -b user2_issue_on_repo1
543
544echo "# My issue" >> issues/2.md
545echo "" >> issues/2.md
546echo "This is my issue" >> issues/2.md
547
548quiet_git add .
549quiet_git commit -m "user2 issue 1"
550
551echo "---" >> issues/roadmap3.md
552echo "id: 22E3" >> issues/roadmap3.md
553echo "priority: 40" >> issues/roadmap3.md
554echo "assignee: null" >> issues/roadmap3.md
555echo "kind: 'roadmap'" >> issues/roadmap3.md
556echo "---" >> issues/roadmap3.md
557echo "# step 3: give" >> issues/roadmap3.md
558echo "" >> issues/roadmap3.md
559echo "Just fun." >> issues/roadmap3.md
560
561quiet_git add .
562quiet_git commit -m "user2 roadmap 3"
563
564quiet_git push origin user2_issue_on_repo1 :user2_branch_on_repo1
565push_and_wait origin user2_issue_on_repo1
566
567quiet_git pull origin user2_issue_on_repo1
568
569if grep -q "id:" issues/2.md
570then
571 report "🟢 ${REPO1_NAME}_2 issues/2.md initialized"
572else
573 report "🛑 ${REPO1_NAME}_2 issues/2.md not initialized"
574 EXIT_CODE=1
575fi
576
577if grep -q "step 3: give" boards/roadmap.md
578then
579 report "🛑 ${REPO1_NAME}_2 boards/roadmap should not be updated has silo is only on main"
580 EXIT_CODE=1
581else
582 report "🟢 ${REPO1_NAME}_2 boards/roadmap not updated"
583fi
584
585quiet_git checkout -b user2_issue2_on_repo1
586
587echo "# My issue" >> issues/3.md
588echo "" >> issues/3.md
589echo "This is my issue" >> issues/3.md
590
591quiet_git add .
592quiet_git commit -m "user2 issue 2"
593push_and_wait origin user2_issue2_on_repo1
594
595quiet_git pull origin user2_issue2_on_repo1
596
597if grep -q "id:" issues/3.md
598then
599 report "🟢 ${REPO1_NAME}_2 issues/3.md initialized"
600else
601 report "🛑 ${REPO1_NAME}_2 issues/3.md not initialized"
602 EXIT_CODE=1
603fi
604
605NB_SILO=$(grep "step 3: give" boards/roadmap.md | wc -l)
606if [[ "$NB_SILO" == "0" ]]; then
607 report "🟢 ${REPO1_NAME}_2 silo has not been called"
608else
609 report "🛑 ${REPO1_NAME}_2 silo has been called $NB_SILO times"
610 EXIT_CODE=1
611fi
612
613##### User1 push force in repo1 on main
614report "🏁 User1 push force in repo1 on main"
615cd /tmp/${REPO1_NAME}
616mySleep 0.1
617quiet_git pull
618echo "not authorized" > issues/1.md
619quiet_git add .
620quiet_git commit --amend --no-edit
621
622EXPECTED_ERROR=1
623quiet_git push -f origin main
624if [[ "$?" == "0" ]]; then
625 report "🛑 user1 can push force on main"
626 EXIT_CODE=1
627else
628 report "🟢 user1 can not push force on main"
629fi
630EXPECTED_ERROR=0
631quiet_git fetch origin main
632quiet_git reset --hard origin/HEAD
633
634##### User2 push force in repo1 on branch user2_branch2_on_repo1
635report "🏁 User2 push force in repo1 on branch user2_branch2_on_repo1"
636
637cd /tmp/${REPO1_NAME}_2
638quiet_git checkout main
639quiet_git checkout -b user2_branch2_on_repo1
640
641#add a commit
642cd /tmp/${REPO1_NAME}
643quiet_git checkout main
644echo "hello" >> README.md
645quiet_git add .
646quiet_git commit -m "fake commit to conflict"
647quiet_git push origin main
648
649mySleep 0.2
650
651cd /tmp/${REPO1_NAME}_2
652echo "---" >> issues/roadmap4.md
653echo "id: 22C3" >> issues/roadmap4.md
654echo "priority: 50" >> issues/roadmap4.md
655echo "assignee: null" >> issues/roadmap4.md
656echo "kind: 'roadmap'" >> issues/roadmap4.md
657echo "---" >> issues/roadmap4.md
658echo "# step 1: conquers the world" >> issues/roadmap4.md
659echo "" >> issues/roadmap4.md
660echo "To do that just imagine the world is small." >> issues/roadmap4.md
661
662quiet_git add .
663quiet_git commit -m "roadmap4"
664quiet_git push origin user2_branch2_on_repo1
665
666quiet_git checkout main
667quiet_git pull --rebase origin main
668quiet_git checkout user2_branch2_on_repo1
669
670quiet_git rebase -X ours main
671report "🟢 Rebase ok"
672
673quiet_git push -f origin user2_branch2_on_repo1
674mySleep 0.05
675quiet_git pull origin user2_branch2_on_repo1
676report "🟢 Push -f ok"
677
678NB_SILO=$(grep "step 1:" boards/roadmap.md | wc -l)
679if [[ "$NB_SILO" == "1" ]]; then
680 report "🟢 ${REPO1_NAME}_2 silo has not been called"
681else
682 report "🛑 ${REPO1_NAME}_2 silo has been called $NB_SILO times"
683 EXIT_CODE=1
684fi
685
686##### Add grafter plugin in repo1
687report "🏁 Add grafter plugin in repo1"
688
689cd /tmp/${ROOT_REPO_NAME}
690echo "- purl: ${GRAFTER_WASM}" >> .gitroot/plugins.yml
691quiet_git add .
692quiet_git commit -m "init grafter plugin"
693quiet_git push origin main
694
695wait_ls "${SERVER_DATA_DIR}/data/plugins/gitroot-grafter"
696quiet_git pull origin main
697
698cd /tmp/${REPO1_NAME}
699quiet_git pull origin main
700sed -i -e 's/active: false/active: true/g' .gitroot/plugins.yml
701report "🟢 ${REPO1_NAME} grafter plugin initialized"
702quiet_git add .
703quiet_git commit -m "active grafter plugin"
704quiet_git push origin main
705
706report "🟢 ${REPO1_NAME} grafter plugin activated"
707quiet_git checkout -b graft_something
708echo "hello" >> tada.md
709quiet_git add .
710quiet_git commit -m "first graft"
711push_and_wait origin graft_something
712quiet_git pull origin graft_something
713
714NB_STATUS_DRAFT=$(grep "status: draft" grafts/graft_something.md | wc -l)
715if [[ $NB_STATUS_DRAFT -ge 1 ]]; then
716 report "🟢 ${REPO1_NAME} status: draft ok"
717else
718 report "🛑 ${REPO1_NAME} status: draft ko"
719 EXIT_CODE=1
720fi
721report "🟢 ${REPO1_NAME} first graft created"
722
723rm issues/1.md
724quiet_git add .
725quiet_git commit -m "rm issue first graft"
726echo "second" > issues/2.md
727quiet_git add .
728quiet_git commit -m "second issue first graft"
729mv issues/roadmap1.md issues/roadmap.md
730quiet_git add .
731quiet_git commit -m "move roadmap first graft"
732push_and_wait origin graft_something
733quiet_git pull origin graft_something
734
735NB_PUSH=$(grep "Push " grafts/graft_something.md | wc -l)
736NB_COMMIT=$(grep "### " grafts/graft_something.md | wc -l)
737if [[ "$NB_COMMIT" == "6" ]] && [[ "$NB_PUSH" == "3" ]]; then
738 report "🟢 ${REPO1_NAME} graft has 3 push and 6 commits"
739else
740 report "🛑 ${REPO1_NAME} graft has $NB_PUSH push and $NB_COMMIT commits"
741 EXIT_CODE=1
742fi
743
744NB_COMMIT=$(git log --oneline graft_something ^main | wc -l)
745if [[ $NB_COMMIT -eq 9 ]]; then
746 report "🟢 ${REPO1_NAME} has 9 commits on branch graft_something"
747else
748 report "🛑 ${REPO1_NAME} has $NB_COMMIT commits on branch graft_something"
749 EXIT_CODE=1
750fi
751
752sed -i -e 's/status: draft/status: review/g' grafts/graft_something.md
753quiet_git add .
754quiet_git commit -m "review first graft"
755push_and_wait origin graft_something
756quiet_git pull origin graft_something
757
758NB_STATUS_DRAFT=$(grep "status: draft" grafts/graft_something.md | wc -l)
759if [[ "$NB_STATUS_DRAFT" == "0" ]]; then
760 report "🟢 ${REPO1_NAME} status no more draft"
761else
762 report "🛑 ${REPO1_NAME} status: draft ko"
763 EXIT_CODE=1
764fi
765NB_REVIEWERS=$(grep "reviewers: " grafts/graft_something.md | wc -l)
766if [[ "$NB_REVIEWERS" == "1" ]]; then
767 report "🟢 ${REPO1_NAME} reviewers added"
768else
769 report "🛑 ${REPO1_NAME} reviewers ko"
770 EXIT_CODE=1
771fi
772NB_MENTION_OF_REVIEW=$(grep "review first graft" grafts/graft_something.md | wc -l)
773if [[ "$NB_MENTION_OF_REVIEW" == "0" ]]; then
774 report "🟢 ${REPO1_NAME} commit review skipped"
775else
776 report "🛑 ${REPO1_NAME} commit review not skipped"
777 EXIT_CODE=1
778fi
779report "🟢 ${REPO1_NAME} first graft ready to review"
780
781echo "second is 2" > issues/2.md
782quiet_git add .
783quiet_git commit -m "second issue review first graft"
784push_and_wait origin graft_something
785quiet_git pull origin graft_something
786
787NB_DIFF=$(grep -F '```diff' grafts/graft_something.md | wc -l)
788if [[ "$NB_DIFF" == "2" ]]; then
789 report "🟢 ${REPO1_NAME} diff added"
790else
791 report "🛑 ${REPO1_NAME} diff ko $NB_DIFF"
792 EXIT_CODE=1
793fi
794
795sed -i -e 's/status: review/status: merge/g' grafts/graft_something.md
796quiet_git add .
797quiet_git commit -m "merge first graft"
798quiet_git push origin graft_something
799
800mySleep 0.5
801
802quiet_git checkout main
803quiet_git pull --rebase origin main
804quiet_git fetch --prune
805BRANCH_EXIST=$(git branch -r | grep "origin/graft_something" | wc -l)
806if [[ "$BRANCH_EXIST" == "0" ]]; then
807 report "🟢 ${REPO1_NAME} branch graft_something deleted"
808else
809 report "🛑 ${REPO1_NAME} branch graft_something no deleted"
810 EXIT_CODE=1
811fi
812
813report "🟢 ${REPO1_NAME} recreate branch graft_something for test shallow-exclude"
814quiet_git push origin graft_something
815
816##### Add apex plugin in repo1
817report "🏁 Add apex plugin in repo1"
818
819cd /tmp/${ROOT_REPO_NAME}
820echo "- purl: ${APEX_WASM}" >> .gitroot/plugins.yml
821echo "- purl: ${APEX_CODE_MERMAID_WASM}" >> .gitroot/plugins.yml
822echo "- purl: ${APEX_CODE_WASM}" >> .gitroot/plugins.yml
823echo "- purl: ${APEX_MARKDOWN_WASM}" >> .gitroot/plugins.yml
824quiet_git add .
825quiet_git commit -m "init apex plugin"
826quiet_git push origin main
827
828wait_ls "${SERVER_DATA_DIR}/data/plugins/gitroot-apex_markdown"
829wait_ls "${SERVER_DATA_DIR}/data/plugins/gitroot-apex"
830wait_ls "${SERVER_DATA_DIR}/data/plugins/gitroot-apex_code"
831quiet_git pull origin main
832report "🟢 ${ROOT_REPO_NAME} apex plugin installed"
833
834cd /tmp/${REPO1_NAME}
835quiet_git pull origin main
836sed -i -e 's/active: false/active: true/g' .gitroot/plugins.yml
837sed -i -e 's/layout: \[\]/layout:\
838 \- glob: issues\/**\
839 path: layout.html/g' .gitroot/plugins.yml
840echo "<dl>" > layout.html
841echo " <dt>priority</dt><dd>{{priority}}</dd>" >> layout.html
842echo " <dt>status</dt><dd>{{status}}</dd>" >> layout.html
843echo " <dt>kind</dt><dd>{{kind}}</dd>" >> layout.html
844echo "</dl>" >> layout.html
845echo "<br />" >> layout.html
846echo "{{content}}" >> layout.html
847report "🟢 ${REPO1_NAME} apex plugin initialized"
848quiet_git add .
849quiet_git commit -m "active apex plugin"
850
851push_and_wait origin main
852
853META_FOUND=$(wget -q http://127.0.0.1:$SERVER_PORT_HTTP/repo1/issues/issue_9.html -O - | grep "<dt>" | wc -l)
854if [[ $META_FOUND -eq 3 ]]; then
855 report "🟢 issue_9.html has 3 meta"
856else
857 report "🛑 issue_9.html has no meta"
858 EXIT_CODE=1
859fi
860
861quiet_git pull origin main
862
863report "🟢 ${REPO1_NAME} apex plugin activated"
864echo "# hello" > hello2.md
865echo "## hello2" >> hello2.md
866echo "### hello3" >> hello2.md
867quiet_git add .
868quiet_git commit -m "first html"
869
870quiet_git push origin main
871
872sed -i -e 's/style: simple.min.css/style: style.css/g' .gitroot/plugins.yml
873sed -i -e 's/header: <h1>{{repo.name}}/header: <h1>{{repo.name}} <small>{{page.title}}<\/small>/g' .gitroot/plugins.yml
874
875cp ${SCRIPT_DIR}/../server/resources/styles/simple.min.css style.css
876cat ${SCRIPT_DIR}/../plugins/apex/resources/styles/add.css >> style.css
877echo "body { background-color: 010409 }" >> style.css
878echo "body > header { background-color: 010409; text-align: left; padding: 0 1rem }" >> style.css
879echo "body > header h1 { font-size: 1rem }" >> style.css
880echo "header > nav ul { place-content: normal }" >> style.css
881echo "header > nav a { margin: 0 .5rem; border: 0 }" >> style.css
882
883echo "# Mermaid" >> apex.md
884echo "" >> apex.md
885echo "Examples of rendering mermaid..." >> apex.md
886echo "" >> apex.md
887echo "## Mermaid flowchart" >> apex.md
888echo "" >> apex.md
889echo "\`\`\`mermaid" >> apex.md
890echo "flowchart LR;" >> apex.md
891echo "ssh-->runtime-->plugin" >> apex.md
892echo "\`\`\`" >> apex.md
893echo "" >> apex.md
894echo "## Mermaid flowchart complexe" >> apex.md
895echo "\`\`\`mermaid" >> apex.md
896echo "flowchart TB" >> apex.md
897echo " subgraph Git" >> apex.md
898echo " A[ssh conn] --> B[plugin manager]" >> apex.md
899echo " end" >> apex.md
900echo " subgraph Runtime" >> apex.md
901echo " C[runtime] --> D[wasm]" >> apex.md
902echo " end" >> apex.md
903echo " subgraph Plugin" >> apex.md
904echo " E[guest] --> F[host]" >> apex.md
905echo " end" >> apex.md
906echo " B --> C" >> apex.md
907echo " D --> E" >> apex.md
908echo "" >> apex.md
909echo "\`\`\`" >> apex.md
910echo "## Mermaid pie" >> apex.md
911echo "\`\`\`mermaid" >> apex.md
912echo "pie title Plugins sdk" >> apex.md
913echo " "Stable" : 20" >> apex.md
914echo " "Need work" : 80" >> apex.md
915echo "\`\`\`" >> apex.md
916echo "## Mermaid sequence" >> apex.md
917echo "\`\`\`mermaid" >> apex.md
918echo "sequenceDiagram" >> apex.md
919echo " Alice ->> Bob: Hello Bob, how are you?" >> apex.md
920echo " Bob-->>John: How about you John?" >> apex.md
921echo " Bob--x Alice: I am good thanks!" >> apex.md
922echo " Bob-x John: I am good thanks!" >> apex.md
923echo " Note right of John: Bob thinks a long<br/>long time, so long<br/>that the text does<br/>not fit on a row." >> apex.md
924echo " Bob-->Alice: Checking with John..." >> apex.md
925echo " Alice->John: Yes... John, how are you?" >> apex.md
926echo "\`\`\`" >> apex.md
927
928quiet_git add .
929quiet_git commit -m "perso style"
930quiet_git push origin main
931
932##### User2 can create repo3
933report "🏁 User2 can create repo3 with master branch"
934
935cd /tmp/${ROOT_REPO_NAME}
936sed -i -e 's/active: false/active: true/g' .gitroot/plugins.yml
937report "🟢 ${ROOT_REPO_NAME} plugins will activate"
938quiet_git add .
939quiet_git commit -m "active all plugins"
940
941push_and_wait origin main
942
943quiet_git pull origin main
944report "🟢 ${ROOT_REPO_NAME} plugins activated"
945
946cd /tmp
947GIT_SSH_COMMAND="ssh -i ${SSH_KEY2} -o IdentitiesOnly=yes" quiet_git clone --quiet "${ROOT_REPO_URL}" ${ROOT_REPO_NAME}_2
948cd ${ROOT_REPO_NAME}_2
949quiet_git checkout -b create_repo3
950init_local_git user2root@gitroot.dev user2 ${SSH_KEY2}.pub ${SSH_KEY2}
951PUB=$(cat ${SSH_KEY2}.pub)
952printf "\n${REPO3_NAME}:\n defaultbranch: master\n owners:\n - ${PUB}" >> .gitroot/repositories.yml
953quiet_git add .
954quiet_git commit -m "create repo3"
955push_and_wait origin create_repo3
956report "🟢 ${ROOT_REPO_NAME}_2 push create_repo3 repo"
957
958cd /tmp/${ROOT_REPO_NAME}
959quiet_git pull --rebase origin main
960quiet_git fetch origin create_repo3
961quiet_git checkout create_repo3
962sed -i -e 's/status: draft/status: merge/g' grafts/create_repo3.md
963quiet_git add .
964quiet_git commit -m "merge create_repo3 graft"
965
966push_and_wait origin create_repo3
967
968cd /tmp
969GIT_SSH_COMMAND="ssh -i ${SSH_KEY2} -o IdentitiesOnly=yes" quiet_git clone --quiet "${REPO3_URL}"
970
971cd ${REPO3_NAME}
972init_local_git user2repo3@gitroot.dev user2 ${SSH_KEY2}.pub ${SSH_KEY2}
973echo "works" > README.md
974quiet_git add .
975quiet_git commit -m "mine readme"
976quiet_git push origin master
977
978##### Shallow
979report "🏁 Shallow"
980
981cd /tmp
982rm -rf repo1_shallow
983GIT_SSH_COMMAND="ssh -i ${SSH_KEY2} -o IdentitiesOnly=yes" quiet_git clone --quiet --depth 1 ssh://git@127.0.0.1:$SERVER_PORT/repo1 repo1_shallow
984cd repo1_shallow
985init_local_git user2repo1Shallow@gitroot.dev user2 ${SSH_KEY2}.pub ${SSH_KEY2}
986
987NB_COMMIT=$(git rev-list HEAD --count)
988if [[ $NB_COMMIT -eq 1 ]]; then
989 report "🟢 repo1_shallow has 1 commit"
990else
991 report "🛑 repo1_shallow has $NB_COMMIT commits"
992 EXIT_CODE=1
993fi
994
995# TODO reactive after go-git v6
996# quiet_git fetch --deepen 1 origin main
997# NB_COMMIT=$(git rev-list HEAD --count)
998# if [[ $NB_COMMIT -eq 2 ]]; then
999# report "🟢 repo1_shallow has 2 commits"
1000# else
1001# report "🛑 repo1_shallow has $NB_COMMIT commits"
1002# EXIT_CODE=1
1003# fi
1004
1005# TODO reactive after go-git v6
1006# quiet_git fetch --shallow-exclude=graft_something origin main
1007# NB_COMMIT=$(git rev-list HEAD --count)
1008# if [[ $NB_COMMIT -eq 11 ]]; then
1009# report "🟢 repo1_shallow has 11 commits"
1010# else
1011# report "🛑 repo1_shallow has $NB_COMMIT commits"
1012# EXIT_CODE=1
1013# fi
1014
1015##### User2 hack repo1
1016report "🏁 User2 hack repo1"
1017
1018cd /tmp/${REPO1_NAME}_2
1019quiet_git checkout main
1020quiet_git pull --rebase origin main
1021
1022NB_NOT_FOUND=$(wget -q http://127.0.0.1:$SERVER_PORT_HTTP/repo1/index2.html -O - | grep "Not found" | wc -l)
1023if [[ $NB_NOT_FOUND -eq 1 ]]; then
1024 report "🟢 index2.html is not found"
1025else
1026 report "🛑 index2.html exist"
1027 EXIT_CODE=1
1028fi
1029
1030quiet_git checkout -b hack
1031
1032#sed -i -e 's/path: branches\/\*\*\/\*/path: "\*\*\/\*"/g' .gitroot/plugins.yml
1033sed -i -e 's/- main/- hack/g' .gitroot/plugins.yml
1034sed -i -e 's/- "!main"/- "!hack"/g' .gitroot/plugins.yml
1035
1036echo "powned!" > index2.md
1037quiet_git add .
1038quiet_git commit -m "hack"
1039push_and_wait origin hack
1040
1041NB_NOT_FOUND=$(wget -q http://127.0.0.1:$SERVER_PORT_HTTP/repo1/index2.html -O - | grep "Not found" | wc -l)
1042if [[ $NB_NOT_FOUND -eq 1 ]]; then
1043 report "🟢 index2.html is not found"
1044else
1045 report "🛑 index2.html exist"
1046 EXIT_CODE=1
1047fi
1048
1049HACK_LINK=$(wget -q http://127.0.0.1:$SERVER_PORT_HTTP/repo1/branches/ -O - | grep "branches/hack.html" | wc -l)
1050if [[ $HACK_LINK -eq 1 ]]; then
1051 report "🟢 hack branch is referenced"
1052else
1053 report "🛑 hack branch is not referenced"
1054 EXIT_CODE=1
1055fi
1056
1057HACK_LINK=$(wget -q http://127.0.0.1:$SERVER_PORT_HTTP/repo1/branches/hack/grafts/hack.html -O - | grep "Not found" | wc -l)
1058if [[ $HACK_LINK -eq 1 ]]; then
1059 report "🛑 hack branch has no graft"
1060 EXIT_CODE=1
1061else
1062 report "🟢 hack branch has graft"
1063fi
1064
1065##### install pollen plugin
1066report "🏁 pollen plugin"
1067
1068cd /tmp/${ROOT_REPO_NAME}
1069quiet_git checkout main
1070quiet_git pull origin main
1071echo "- purl: ${POLLEN_WASM}" >> .gitroot/plugins.yml
1072quiet_git add .
1073quiet_git commit -m "init pollen plugin"
1074push_and_wait origin main
1075wait_ls "${SERVER_DATA_DIR}/data/plugins/gitroot-pollen"
1076mySleep 0.1
1077quiet_git pull origin main
1078report "🟢 ${ROOT_REPO_NAME} pollen plugin installed"
1079
1080cd /tmp/${REPO1_NAME}
1081push_and_wait origin main
1082quiet_git pull origin main
1083sed -i -e 's/active: false/active: true/g' .gitroot/plugins.yml
1084quiet_git add .
1085quiet_git commit -m "active pollen plugin"
1086quiet_git push origin main
1087
1088echo "With rss" > README.md
1089quiet_git add .
1090quiet_git commit -m "with rss"
1091quiet_git push origin main
1092
1093mySleep 4
1094
1095RSS_CONTENT=$(wget -q http://127.0.0.1:$SERVER_PORT_HTTP/repo1/rss/all.xml -O - | grep "with rss" | wc -l)
1096if [[ $RSS_CONTENT -eq 2 ]]; then
1097 report "🟢 rss ok"
1098else
1099 report "🛑 rss ko with $RSS_CONTENT commits"
1100 EXIT_CODE=1
1101fi
1102
1103##### install hop plugin
1104report "🏁 hop plugin"
1105
1106cd /tmp/${ROOT_REPO_NAME}
1107echo "- purl: ${HOP_WASM}" >> .gitroot/plugins.yml
1108quiet_git add .
1109quiet_git commit -m "init hop plugin"
1110push_and_wait origin main
1111wait_ls "${SERVER_DATA_DIR}/data/plugins/gitroot-hop"
1112mySleep 0.1
1113quiet_git pull origin main
1114report "🟢 ${ROOT_REPO_NAME} hop plugin installed"
1115
1116cd /tmp/${REPO1_NAME}
1117push_and_wait origin main
1118quiet_git pull origin main
1119sed -i -e 's/active: false/active: true/g' .gitroot/plugins.yml
1120quiet_git add .
1121quiet_git commit -m "active hop plugin"
1122quiet_git push origin main
1123
1124mySleep 4
1125
1126quiet_git checkout -b testHop
1127echo "Hello from hop" >> README.md
1128quiet_git add .
1129quiet_git commit -m "test hop plugin"
1130push_and_wait origin testHop
1131
1132quiet_git pull origin testHop
1133NB_REPORT=$(grep "❌ No commands executed." grafts/testHop.md | wc -l)
1134if [[ $NB_REPORT -eq 1 ]]; then
1135 report "🟢 report ok"
1136else
1137 report "🛑 report ko with $NB_REPORT reports"
1138 EXIT_CODE=1
1139fi
1140
1141quiet_git checkout main
1142
1143##### verify commit
1144report "🏁 verify commits"
1145
1146cd /tmp/${ROOT_REPO_NAME}
1147quiet_git checkout main
1148quiet_git pull origin main
1149echo "- purl: ${STIGMA_WASM}" >> .gitroot/plugins.yml
1150echo " active: true" >> .gitroot/plugins.yml
1151quiet_git add .
1152quiet_git commit -m "init stigma plugin"
1153push_and_wait origin main
1154wait_ls "${SERVER_DATA_DIR}/data/plugins/gitroot-stigma"
1155push_and_wait origin main
1156quiet_git pull origin main
1157report "🟢 ${ROOT_REPO_NAME} stigma plugin installed"
1158
1159cd /tmp/${ROOT_REPO_NAME}
1160cat .gitroot/allowed_signers >> $MY_LOG
1161git reflog show main | awk '{ print $1 }' | xargs git verify-commit &>> $MY_LOG
1162report "🟢 ${ROOT_REPO_NAME}"
1163
1164cd /tmp/${REPO1_NAME}
1165push_and_wait origin main
1166quiet_git pull origin main
1167sed -i -e 's/active: false/active: true/g' .gitroot/plugins.yml
1168quiet_git add .
1169quiet_git commit -m "active stigma plugin"
1170push_and_wait origin main
1171
1172quiet_git pull origin main
1173cat .gitroot/allowed_signers >> $MY_LOG
1174git reflog show main | awk '{ print $1 }' | xargs git verify-commit &>> $MY_LOG
1175report "🟢 ${REPO1_NAME}"
1176
1177cd /tmp/${REPO2_NAME}
1178push_and_wait origin main
1179quiet_git pull origin main
1180sed -i -e 's/active: false/active: true/g' .gitroot/plugins.yml
1181quiet_git add .
1182quiet_git commit -m "active stigma plugin"
1183quiet_git push origin main
1184mySleep 1
1185quiet_git pull origin main
1186cat .gitroot/allowed_signers >> $MY_LOG
1187# TODO reactive when stigma plugin can add old user
1188# git reflog show main | awk '{ print $1 }' | xargs git verify-commit &>> $MY_LOG
1189# report "🟢 ${REPO2_NAME}"
1190
1191##### Finish
1192report "🏁 Finish"
1193if grep -q -i "level=ERROR" $MY_LOG
1194then
1195 report "🛑 Logs contains error"
1196 EXIT_CODE=1
1197else
1198 report "🟢 Logs no error"
1199fi
1200
1201if grep -q -i "WARNING: DATA RACE" $MY_LOG
1202then
1203 report "🛑 Logs contains data race"
1204 EXIT_CODE=1
1205else
1206 report "🟢 Logs no data race"
1207fi
1208
1209report ""
1210report "✎ Find all logs in $MY_LOG"
1211exit $EXIT_CODE