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