summaryrefslogtreecommitdiff
path: root/deploy/README.txt
blob: d3494e1c085c57cc605cf295d6c89773780bdc2e (plain)
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
kukuri build & deploy guide
===========================

Artifacts (all land in modules/orgflow-domain/build/distributions/):
  kukuri-desktop-<v>.zip          desktop fat jar + launcher   (bundleDesktop)
  kukuri-wasm-node-<v>.zip        Kotlin/Wasm node build       (bundleWasmNode)
  kukuri-wasm-web-<v>.zip         web app: index.html + orgflow-ui.js + webfont.js (bundleWeb)
  kukuri-native-linuxx64-<v>.zip  linux native executable      (bundleNative)
  kukuri-android-<v>.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-<v>.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":"<sha>"}}'
(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-<v>.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/<BUILD>/steps
  logs of a step:        curl -s http://192.168.3.110:8010/api/v2/steps/<STEPID>/logs
  full step log (raw):   curl -s http://192.168.3.110:8010/api/v2/logs/<LOGID>/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:     <module>/build/reports/tests/jvmTest/index.html
  android tests: <module>/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 <task> 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-<v>.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-<os>-<hash of build scripts>) - 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.