kukuri build & deploy guide =========================== Artifacts (all land in modules/orgflow-domain/build/distributions/): kukuri-desktop-.zip desktop fat jar + launcher (bundleDesktop) kukuri-wasm-node-.zip Kotlin/Wasm node build (bundleWasmNode) kukuri-wasm-web-.zip web app: index.html + orgflow-ui.js + webfont.js (bundleWeb) kukuri-native-linuxx64-.zip linux native executable (bundleNative) kukuri-android-.apk debug-signed android APK (bundleApk) 1. Local build -------------- Requirements: JDK 21, Android SDK (ANDROID_HOME or local.properties), node.js (wasm tests). Build everything: ./gradlew bundleDesktop bundleWasm bundleNative bundleWeb bundleApk Single artifacts: ./gradlew :modules:orgflow-domain:bundleWeb ./gradlew :modules:orgflow-domain:bundleApk Run the desktop shell: ./gradlew :apps:desktop:run Test set (same steps CI runs): ./gradlew :modules:orgflow-domain:detekt assemble jvmTest \ testDebugUnitTest testReleaseUnitTest wasmJsNodeTest linuxX64Test 2. git add -> buildbot (automatic build + deploy) ------------------------------------------------- The buildbot master (http://192.168.3.110:8010) polls http://192.168.3.110/git/kukuri.git (branch main) every 30 seconds. git add -A git commit -m "..." git push origin main # origin pushes to both gitea and github Within ~30s a build starts on the worker: setup-git-auth -> git checkout -> detekt-gate -> assemble -> jvm/android/wasm/native tests -> bundles -> wait-github-ios (blocks until the Actions "ios" run for the same commit finishes; fails the build if it fails) -> fetch-github-ios (downloads the "kukuri-ios" artifact, stages distributions/kukuri-ios-.zip) -> deploy-to-lighttpd (FTP upload of all zips + the apk) Watch progress: http://192.168.3.110:8010 (waterfall / console view) CLI watcher (waits for a build newer than the given number; exit 0 = success): ops/watch-buildbot.sh 32 900 # e.g. wait for build # > 32, up to 15 min Manual trigger for a specific revision: curl -s -X POST http://192.168.3.110:8010/api/v2/forceschedulers/force \ -H 'Content-Type: application/json' \ -d '{"jsonrpc":"2.0","method":"force","id":1,"params":{"revision":""}}' (omit "revision" to build HEAD) Deployed result: http://192.168.3.110/artifact/kukuri/latest/ web app: http://192.168.3.110/artifact/kukuri/latest/web/index.html android: http://192.168.3.110/artifact/kukuri/latest/kukuri-android-.apk zips: http://192.168.3.110/artifact/kukuri/latest/kukuri-*.zip 3. Changing the buildbot pipeline (deploy/buildbot/master/master.cfg) --------------------------------------------------------------------- The repo copy deploy/buildbot/master/master.cfg is the source of truth. The live master on 192.168.3.110 runs from /var/lib/buildbot/masters/default (user "buildbot", system-wide /usr/bin/buildbot - the /opt/kukuri-buildbot dir only keeps a spare copy of the cfg). Apply (SSH password = ketsuban's git password, i.e. the worker's /run/secrets/git_pass; sshpass keeps it one-shot): PW=$(docker exec kukuri-worker cat /run/secrets/git_pass) sshpass -p "$PW" scp deploy/buildbot/master/master.cfg \ root@192.168.3.110:/var/lib/buildbot/masters/default/master.cfg sshpass -p "$PW" ssh root@192.168.3.110 \ "chown buildbot:buildbot /var/lib/buildbot/masters/default/master.cfg && \ buildbot reconfig /var/lib/buildbot/masters/default" "Reconfiguration appears to have completed successfully" = ok, no restart needed. Trigger a build to exercise the new pipeline (section 2). 4. Docker build test (CI parity before pushing) ----------------------------------------------- The buildbot worker runs in a container ("kukuri-worker", built from deploy/buildbot/worker/Dockerfile.worker) that already has JDK, Android SDK, node and the shared gradle cache (GRADLE_USER_HOME=/var/jenkins_home/.gradle). To verify exactly what CI will run before pushing, replay the committed tree inside it: # 1. archive the committed tree (use /root: /tmp of the dev shell is not # visible to docker cp) git archive main | gzip > /root/k.tgz docker cp /root/k.tgz kukuri-worker:/tmp/k.tgz # 2. replace the container's tree and run the full CI task list docker exec kukuri-worker bash -c ' rm -rf /worker/kukuri-build/build && mkdir -p /worker/kukuri-build/build && tar xzf /tmp/k.tgz -C /worker/kukuri-build/build && cd /worker/kukuri-build/build && JAVA_HOME=/opt/java/openjdk GRADLE_USER_HOME=/var/jenkins_home/.gradle \ ./gradlew :modules:orgflow-domain:detekt assemble jvmTest \ testDebugUnitTest testReleaseUnitTest wasmJsNodeTest linuxX64Test \ bundleDesktop bundleWasm bundleNative bundleWeb bundleApk' Notes: - Extracting a fresh archive (rm -rf + tar) guarantees no stale files from deleted sources linger - same as CI's clean checkout. - The gradle caches persist in the container volume, so repeat runs are fast. - For a fresh worker container on any host: deploy/buildbot/worker/run-worker.sh. 5. Error logs & diagnostics --------------------------- buildbot (web UI): http://192.168.3.110:8010 -> builders -> kukuri-build -> click a build Each step shows "stdio"; failed steps show the tail inline (red). buildbot (API, same data as the UI): steps of a build: curl -s http://192.168.3.110:8010/api/v2/builds//steps logs of a step: curl -s http://192.168.3.110:8010/api/v2/steps//logs full step log (raw): curl -s http://192.168.3.110:8010/api/v2/logs//raw (use the step's stepid and the log's logid from the JSON responses) worker-side gradle reports (inside the kukuri-worker container): detekt: modules/orgflow-domain/build/reports/detekt/detekt.txt jvm tests: /build/reports/tests/jvmTest/index.html android tests: /build/reports/tests/testDebugUnitTest/... config cache: build/reports/configuration-cache/<...>/configuration-cache-report.html problems: build/build/reports/problems/problems-report.html e.g.: docker exec kukuri-worker cat \ /worker/kukuri-build/build/modules/orgflow-domain/build/reports/detekt/detekt.txt local docker build test (section 4): when ./gradlew fails there, rerun with the failing task alone and grep around the failure: docker exec kukuri-worker bash -c 'cd /worker/kukuri-build/build && \ JAVA_HOME=/opt/java/openjdk GRADLE_USER_HOME=/var/jenkins_home/.gradle \ ./gradlew --console=plain 2>&1 | grep -B2 -A8 "What went wrong"' github actions (ios): https://github.com/ketsuban152/kukuri/actions -> workflow run -> job step log 6. iOS ------ Two places: - buildbot ships "kukuri-ios-.zip" (frameworks + klibs from the Actions run) to http://192.168.3.110/artifact/kukuri/latest/ together with the other artifacts. - the raw "kukuri-ios" Actions artifact stays on https://github.com/ketsuban152/kukuri/actions ios.yml uses actions/cache for ~/.gradle/caches, ~/.gradle/wrapper and ~/.konan (key: ios--) - the first run after a cache-key change is cold, later runs reuse the Konan toolchain and task outputs. The worker reads /run/secrets/github_token (a repo-scoped PAT) for the artifact download; run-worker.sh mounts it from /root/buildbot/secrets/github_token.