Compare commits

...

98 Commits

Author SHA1 Message Date
datadunia 4d58b01641 ci: fix pipeline flow - tests→build→docs→release with fail-fast
CI / server-core-test (push) Has been skipped
CI / device-agent-test (push) Has been skipped
CI / dashboard-test (push) Has been skipped
CI / build-server-core (push) Successful in 1m45s
CI / build-device-agent (push) Failing after 2m29s
CI / build-dashboard (push) Successful in 1m14s
CI / build-docs (push) Has been skipped
CI / release (push) Has been skipped
2026-06-18 09:59:04 +07:00
datadunia 4e19c371d0 fix: device-agent winres.json location for go-winres
CI / server-core-test (push) Has been skipped
CI / device-agent-test (push) Has been skipped
CI / dashboard-test (push) Has been skipped
CI / build-server-core (push) Successful in 1m43s
CI / build-dashboard (push) Has been cancelled
CI / build-docs (push) Has been cancelled
CI / release (push) Has been cancelled
CI / build-device-agent (push) Has been cancelled
2026-06-18 09:55:48 +07:00
datadunia aa620dec6a fix(ci): restore swagger docs step + fix release needs (remove build-docs dependency)
CI / server-core-test (push) Has been skipped
CI / device-agent-test (push) Has been skipped
CI / dashboard-test (push) Has been skipped
CI / build-server-core (push) Successful in 6m18s
CI / build-device-agent (push) Failing after 2m21s
CI / release (push) Has been skipped
CI / build-dashboard (push) Successful in 1m59s
CI / build-docs (push) Has been skipped
2026-06-18 09:44:29 +07:00
datadunia 48340aa7a3 ci: fix missing closing quote in release condition
CI / server-core-test (push) Has been skipped
CI / device-agent-test (push) Has been skipped
CI / dashboard-test (push) Has been skipped
CI / build-server-core (push) Failing after 2m12s
CI / build-dashboard (push) Has been cancelled
CI / build-docs (push) Has been cancelled
CI / release (push) Has been cancelled
CI / build-device-agent (push) Has been cancelled
2026-06-18 09:33:25 +07:00
datadunia 68ebfbaad3 ci: revert to 3-section structure (test/build/docs) with proper tag conditions 2026-06-18 09:23:56 +07:00
datadunia 46ff7ca737 fix(ci): add missing closing quote in release-stable if condition
CI / build-server-core-dev (push) Failing after 1m55s
CI / build-device-agent-dev (push) Failing after 2m20s
CI / server-core-test (push) Has been skipped
CI / device-agent-test (push) Has been skipped
CI / dashboard-test (push) Has been skipped
CI / release-dev (push) Has been cancelled
CI / build-server-core-release (push) Has been cancelled
CI / build-device-agent-release (push) Has been cancelled
CI / build-dashboard-release (push) Has been cancelled
CI / build-docs-release (push) Has been cancelled
CI / release-stable (push) Has been cancelled
CI / build-dashboard-dev (push) Has been cancelled
2026-06-18 09:14:31 +07:00
datadunia 08b152a370 feat(ci): skip build if no source changes (cache build output by hash) 2026-06-18 09:09:51 +07:00
datadunia 6f22aad1ad ci: restructure pipeline - test only for test tags, build only for dev/beta, build+docs for release 2026-06-18 09:01:36 +07:00
datadunia d21863ce8f perf: remove slow swag init from CI (20min → 1min build) 2026-06-18 08:51:51 +07:00
datadunia eba741cd97 feat: device-agent v1.0.0-dev.30 - auto-elevate admin + key format fix
CI / server-core-test (push) Has been skipped
CI / device-agent-test (push) Has been skipped
CI / dashboard-test (push) Has been skipped
CI / build-device-agent (push) Has been cancelled
CI / build-dashboard (push) Has been cancelled
CI / build-docs (push) Has been cancelled
CI / release (push) Has been cancelled
CI / build-server-core (push) Has been cancelled
2026-06-18 08:19:50 +07:00
datadunia fd9da1fd71 fix: device-agent v1.0.0-dev.29 - base64→hex key conversion for WireGuard IPC
CI / server-core-test (push) Has been skipped
CI / device-agent-test (push) Has been skipped
CI / dashboard-test (push) Has been skipped
CI / build-device-agent (push) Has been cancelled
CI / build-dashboard (push) Has been cancelled
CI / build-docs (push) Has been cancelled
CI / release (push) Has been cancelled
CI / build-server-core (push) Has been cancelled
2026-06-18 08:17:39 +07:00
datadunia d46bc11485 fix: device-agent v1.0.0-dev.28 - remove config file persistence (security fix)
CI / server-core-test (push) Has been skipped
CI / device-agent-test (push) Has been skipped
CI / dashboard-test (push) Has been skipped
CI / build-dashboard (push) Successful in 2m2s
CI / build-docs (push) Successful in 55s
CI / build-server-core (push) Successful in 7m56s
CI / build-device-agent (push) Successful in 3m5s
CI / release (push) Successful in 28s
2026-06-18 08:01:44 +07:00
datadunia f1fa0acfa7 fix: device-agent v1.0.0-dev.27 - fix winres.json (remove broken icon, UAC manifest only)
CI / server-core-test (push) Has been skipped
CI / dashboard-test (push) Has been skipped
CI / device-agent-test (push) Has been skipped
CI / build-docs (push) Successful in 55s
CI / build-server-core (push) Successful in 18m18s
CI / build-device-agent (push) Successful in 2m33s
CI / build-dashboard (push) Successful in 2m13s
CI / release (push) Successful in 27s
2026-06-18 07:07:57 +07:00
datadunia a5c1ea1c1b feat: device-agent v1.0.0-dev.26 - embedded UAC manifest (auto admin prompt)
CI / build-dashboard (push) Successful in 1m30s
CI / server-core-test (push) Has been skipped
CI / device-agent-test (push) Has been skipped
CI / dashboard-test (push) Has been skipped
CI / build-server-core (push) Successful in 5m38s
CI / build-device-agent (push) Successful in 2m28s
CI / build-docs (push) Successful in 52s
CI / release (push) Successful in 25s
2026-06-18 06:29:44 +07:00
datadunia 4dbc0bd9f3 fix: device-agent v1.0.0-dev.25 - isServiceAutoStart stub for Linux
CI / build-server-core (push) Successful in 3m45s
CI / build-dashboard (push) Successful in 1m56s
CI / build-docs (push) Successful in 52s
CI / server-core-test (push) Has been skipped
CI / device-agent-test (push) Has been skipped
CI / dashboard-test (push) Has been skipped
CI / build-device-agent (push) Successful in 3m2s
CI / release (push) Successful in 27s
2026-06-18 06:07:51 +07:00
datadunia 94059ee9e6 chore: update device-agent (UAC + service menu)
CI / server-core-test (push) Has been skipped
CI / device-agent-test (push) Has been skipped
CI / dashboard-test (push) Has been skipped
CI / build-server-core (push) Successful in 3m44s
CI / build-dashboard (push) Successful in 1m29s
CI / build-docs (push) Successful in 53s
CI / build-device-agent (push) Failing after 1m27s
CI / release (push) Has been skipped
2026-06-18 05:35:34 +07:00
datadunia 06d8876b04 chore: update server-core submodule ref 2026-06-18 04:11:45 +07:00
datadunia 90b3baa2fb chore: update server-core submodule ref 2026-06-18 03:55:52 +07:00
datadunia 71224721d3 chore: update server-core submodule ref (BuildKit cache mounts) 2026-06-18 03:33:58 +07:00
datadunia 56f44f5b95 chore: update dashboard-ui + server-core submodule refs (docker improvements) 2026-06-18 03:17:19 +07:00
datadunia 08ac26c698 docs: add device agent architecture 2026-06-18 03:02:40 +07:00
datadunia ac0755977c chore: update server-core (HWID collision fix)
CI / build-device-agent (push) Successful in 2m40s
CI / server-core-test (push) Has been skipped
CI / device-agent-test (push) Has been skipped
CI / dashboard-test (push) Has been skipped
CI / build-server-core (push) Successful in 5m31s
CI / build-dashboard (push) Successful in 1m35s
CI / build-docs (push) Successful in 1m9s
CI / release (push) Successful in 29s
2026-06-18 03:00:50 +07:00
datadunia c1490421ba chore: update device-agent (local config cache)
CI / server-core-test (push) Has been skipped
CI / device-agent-test (push) Has been skipped
CI / dashboard-test (push) Has been skipped
CI / build-server-core (push) Successful in 5m29s
CI / build-device-agent (push) Successful in 2m28s
CI / build-dashboard (push) Successful in 1m24s
CI / build-docs (push) Successful in 54s
CI / release (push) Successful in 26s
2026-06-18 02:42:41 +07:00
datadunia 2d366c4619 fix(ci): use setup-go built-in cache, remove go-hashfiles and actions/cache from Go builds
CI / server-core-test (push) Has been skipped
CI / device-agent-test (push) Has been skipped
CI / dashboard-test (push) Has been skipped
CI / build-server-core (push) Successful in 3m34s
CI / build-device-agent (push) Successful in 2m20s
CI / build-dashboard (push) Successful in 1m34s
CI / build-docs (push) Successful in 51s
CI / release (push) Successful in 26s
2026-06-18 02:23:45 +07:00
datadunia dad057528c chore: update device-agent (embed wintun.dll in exe)
CI / server-core-test (push) Has been skipped
CI / device-agent-test (push) Has been skipped
CI / dashboard-test (push) Has been skipped
CI / build-server-core (push) Successful in 4m1s
CI / build-device-agent (push) Successful in 14m24s
CI / build-dashboard (push) Successful in 3m0s
CI / build-docs (push) Successful in 55s
CI / release (push) Successful in 27s
2026-06-17 18:18:51 +07:00
datadunia 8ae9149620 fix: same HWID re-provisioning + wintun.dll search path
CI / server-core-test (push) Has been skipped
CI / device-agent-test (push) Has been skipped
CI / dashboard-test (push) Has been skipped
CI / build-server-core (push) Successful in 12m40s
CI / build-dashboard (push) Has been cancelled
CI / build-docs (push) Has been cancelled
CI / release (push) Has been cancelled
CI / build-device-agent (push) Has been cancelled
2026-06-17 18:05:04 +07:00
datadunia 9d6c2abb9f fix(ci): cache Go SDK + disable setup-go built-in cache
CI / server-core-test (push) Has been skipped
CI / device-agent-test (push) Has been skipped
CI / dashboard-test (push) Has been skipped
CI / build-device-agent (push) Has been cancelled
CI / build-dashboard (push) Has been cancelled
CI / build-docs (push) Has been cancelled
CI / release (push) Has been cancelled
CI / build-server-core (push) Has been cancelled
2026-06-17 17:58:25 +07:00
datadunia 4c9e54aaa3 fix(ci): replace go-hashfiles with shell hash for dashboard (no Go installed)
CI / build-docs (push) Successful in 1m10s
CI / server-core-test (push) Has been skipped
CI / device-agent-test (push) Has been skipped
CI / dashboard-test (push) Has been skipped
CI / build-server-core (push) Successful in 2m52s
CI / build-device-agent (push) Successful in 2m38s
CI / build-dashboard (push) Successful in 6m15s
CI / release (push) Successful in 32s
2026-06-17 15:07:21 +07:00
datadunia 290af48007 ci: add Gitea-compatible caching (RUNNER_TOOL_CACHE + actions/cache@v3 + go-hashfiles)
CI / server-core-test (push) Has been skipped
CI / device-agent-test (push) Has been skipped
CI / dashboard-test (push) Has been skipped
CI / build-server-core (push) Successful in 15m18s
CI / build-device-agent (push) Successful in 5m51s
CI / build-docs (push) Successful in 1m13s
CI / build-dashboard (push) Failing after 1m38s
CI / release (push) Has been skipped
Per Gitea tutorial: add RUNNER_TOOL_CACHE=/toolcache env, use actions/cache@v3
(not v4), and go-hashfiles instead of hashFiles() which is unsupported.
2026-06-17 14:23:51 +07:00
datadunia 9a2212d691 revert(ci): remove actions/cache@v4 - hangs on act_runner v0.6.1
CI / build-server-core (push) Successful in 5m41s
CI / server-core-test (push) Has been skipped
CI / device-agent-test (push) Has been skipped
CI / dashboard-test (push) Has been skipped
CI / build-device-agent (push) Successful in 2m11s
CI / build-dashboard (push) Successful in 1m11s
CI / build-docs (push) Successful in 1m9s
CI / release (push) Successful in 29s
actions/cache@v4 not compatible with self-hosted act_runner.
Builds complete in 3-5min without cache - acceptable.
2026-06-17 13:54:58 +07:00
datadunia 6f57540490 ci: add actions/cache@v4 for Go modules, Go build cache, and npm cache
CI / build-server-core (push) Has been cancelled
CI / server-core-test (push) Has been skipped
CI / device-agent-test (push) Has been skipped
CI / dashboard-test (push) Has been skipped
CI / build-device-agent (push) Has been cancelled
CI / build-dashboard (push) Has been cancelled
CI / build-docs (push) Has been cancelled
CI / release (push) Has been cancelled
- server-core: Go module + build cache (keyed by go.sum)
- dashboard-ui: npm cache (keyed by package-lock.json)
- device-agent: Go module + build cache (keyed by go.sum)
First run populates cache, subsequent runs restore from cache.
2026-06-17 13:39:31 +07:00
datadunia 8c1b15a78e chore: update device-agent (bundle wintun.dll)
CI / build-server-core (push) Successful in 3m55s
CI / build-dashboard (push) Successful in 1m39s
CI / release (push) Successful in 37s
CI / server-core-test (push) Has been skipped
CI / device-agent-test (push) Has been skipped
CI / dashboard-test (push) Has been skipped
CI / build-device-agent (push) Successful in 1m43s
CI / build-docs (push) Successful in 1m21s
2026-06-17 13:30:03 +07:00
datadunia 52fb2bb5d3 chore: update dashboard-ui (HWID column + search + conflict badge)
CI / build-dashboard (push) Successful in 1m22s
CI / server-core-test (push) Has been skipped
CI / device-agent-test (push) Has been skipped
CI / dashboard-test (push) Has been skipped
CI / build-server-core (push) Successful in 3m51s
CI / build-device-agent (push) Successful in 1m55s
CI / build-docs (push) Successful in 1m7s
CI / release (push) Successful in 35s
2026-06-17 13:11:11 +07:00
datadunia 2ce9dbd4e8 chore: update device-agent (fix double slash URLs)
CI / server-core-test (push) Has been skipped
CI / device-agent-test (push) Has been skipped
CI / build-device-agent (push) Successful in 1m49s
CI / build-dashboard (push) Successful in 1m7s
CI / build-docs (push) Successful in 49s
CI / release (push) Successful in 26s
CI / dashboard-test (push) Has been skipped
CI / build-server-core (push) Successful in 3m37s
2026-06-17 12:59:28 +07:00
datadunia f85db30c2e feat: Reset Device feature + HWID display in Dashboard
CI / build-server-core (push) Successful in 4m38s
CI / build-device-agent (push) Successful in 3m29s
CI / server-core-test (push) Has been skipped
CI / device-agent-test (push) Has been skipped
CI / dashboard-test (push) Has been skipped
CI / build-dashboard (push) Successful in 1m18s
CI / build-docs (push) Successful in 58s
CI / release (push) Successful in 29s
2026-06-17 12:30:06 +07:00
datadunia fc9afd1720 fix(ci): use always()!failure() so builds run when test jobs are skipped
CI / build-server-core (push) Successful in 3m13s
CI / release (push) Successful in 28s
CI / server-core-test (push) Has been skipped
CI / device-agent-test (push) Has been skipped
CI / dashboard-test (push) Has been skipped
CI / build-device-agent (push) Successful in 1m47s
CI / build-dashboard (push) Successful in 57s
CI / build-docs (push) Successful in 51s
Gitea Actions skips dependent jobs when ALL needed jobs are skipped,
unlike GitHub Actions. Adding always()!failure() ensures builds run
for dev/beta tags (tests skipped) while still blocking if tests fail.
2026-06-17 11:48:23 +07:00
datadunia c23e0829cd feat(ci): add draft/prerelease mapping, enforce tests before stable release
CI / server-core-test (push) Has been skipped
CI / device-agent-test (push) Has been skipped
CI / dashboard-test (push) Has been skipped
CI / build-server-core (push) Has been skipped
CI / build-device-agent (push) Has been skipped
CI / build-dashboard (push) Has been skipped
CI / build-docs (push) Has been skipped
CI / release (push) Has been skipped
- release_call.yaml: add draft input, use draft+prerelease in JSON body
- ci.yml test jobs: run for test tags AND stable release tags
- ci.yml build jobs: add needs on test jobs (skipped jobs dont block)
- ci.yml release: draft=true for beta, prerelease=true for dev, plain for stable
2026-06-17 11:45:57 +07:00
datadunia 7b102c94fb chore: update server-core submodule - fix TestDeviceCRUD panic
CI / server-core-test (push) Has been skipped
CI / device-agent-test (push) Has been skipped
CI / dashboard-test (push) Has been skipped
CI / build-device-agent (push) Successful in 1m43s
CI / build-server-core (push) Successful in 3m17s
CI / build-dashboard (push) Successful in 56s
CI / build-docs (push) Successful in 50s
CI / release (push) Successful in 27s
2026-06-17 11:19:17 +07:00
datadunia 5fb815a3c1 fix(ci): move token+persist-credentials to test job checkout, insteadOf after checkout
CI / dashboard-test (push) Successful in 1m24s
CI / build-server-core (push) Has been skipped
CI / build-device-agent (push) Has been skipped
CI / build-dashboard (push) Has been skipped
CI / build-docs (push) Has been skipped
CI / release (push) Has been skipped
CI / server-core-test (push) Failing after 4m31s
CI / device-agent-test (push) Successful in 1m22s
Test jobs failed because actions/checkout@v4 erases global insteadOf
during 'Setting up auth for fetching submodules', replacing it with
SSH mappings that don't help with x-access-token auth.

Fix: Add token + persist-credentials to checkout (same pattern as
reusable build workflows that pass), and move insteadOf after checkout
as a safety net for subsequent git operations.
2026-06-17 10:56:27 +07:00
datadunia d9bf8d5616 fix(App): add NgToast component (toast notifications now visible)
CI / server-core-test (push) Failing after 13s
CI / device-agent-test (push) Failing after 16s
CI / build-docs (push) Has been skipped
CI / release (push) Has been skipped
CI / dashboard-test (push) Failing after 14s
CI / build-server-core (push) Has been skipped
CI / build-device-agent (push) Has been skipped
CI / build-dashboard (push) Has been skipped
2026-06-17 10:03:25 +07:00
datadunia e45b79c2a8 chore: update dashboard-ui submodule ref 2026-06-17 10:00:29 +07:00
datadunia c3177eb4e4 chore: update dashboard-ui submodule ref 2026-06-17 09:46:12 +07:00
datadunia 6141c2b556 chore: update server-core + dashboard-ui submodule refs 2026-06-17 09:27:38 +07:00
datadunia 8f589901f2 chore: update dashboard-ui submodule ref 2026-06-17 09:03:35 +07:00
datadunia 10a9ae2eac feat(port-forward): sync port forwards to nftables + update docs
- server-core: DNAT + forward rules for TCP/UDP port forwarding
- AGENTS.md: update device-agent description (systray support)
2026-06-17 06:38:04 +07:00
datadunia 53efeab1b3 chore: update device-agent (auto-download wintun.dll)
CI / server-core-test (push) Has been skipped
CI / device-agent-test (push) Has been skipped
CI / dashboard-test (push) Has been skipped
CI / build-server-core (push) Successful in 8m16s
CI / build-device-agent (push) Successful in 2m11s
CI / build-docs (push) Successful in 1m6s
CI / build-dashboard (push) Successful in 1m32s
CI / release (push) Successful in 31s
2026-06-10 19:43:23 +07:00
datadunia cc0f01b6ae chore: update device-agent (Windows HWID + provisioning debug)
CI / build-server-core (push) Successful in 5m15s
CI / build-device-agent (push) Successful in 2m53s
CI / server-core-test (push) Has been skipped
CI / device-agent-test (push) Has been skipped
CI / dashboard-test (push) Has been skipped
CI / build-dashboard (push) Successful in 1m10s
CI / build-docs (push) Successful in 1m14s
CI / release (push) Successful in 39s
2026-06-10 19:10:32 +07:00
datadunia 00a0bf661c chore: update device-agent (debug log, platform icons, hide console)
CI / build-server-core (push) Successful in 3m43s
CI / build-device-agent (push) Successful in 1m45s
CI / build-dashboard (push) Successful in 59s
CI / build-docs (push) Successful in 52s
CI / release (push) Successful in 25s
CI / server-core-test (push) Has been skipped
CI / device-agent-test (push) Has been skipped
CI / dashboard-test (push) Has been skipped
2026-06-10 18:44:18 +07:00
datadunia 6a27007b53 chore: update device-agent submodule (tray icons + strip build)
CI / server-core-test (push) Has been skipped
CI / device-agent-test (push) Has been skipped
CI / dashboard-test (push) Has been skipped
CI / build-server-core (push) Successful in 4m6s
CI / build-device-agent (push) Successful in 1m44s
CI / build-dashboard (push) Successful in 58s
CI / build-docs (push) Successful in 55s
CI / release (push) Successful in 25s
2026-06-10 16:58:44 +07:00
datadunia 2944ca0947 chore: update server-core submodule ref (regenerate-token HWID reset)
CI / server-core-test (push) Has been skipped
CI / device-agent-test (push) Has been skipped
CI / build-server-core (push) Successful in 6m36s
CI / build-device-agent (push) Successful in 4m20s
CI / dashboard-test (push) Has been skipped
CI / build-dashboard (push) Successful in 1m2s
CI / build-docs (push) Successful in 51s
CI / release (push) Successful in 28s
2026-06-10 15:26:33 +07:00
datadunia 2cfc7408a4 ci: add v*-dev* tag pattern to trigger builds
CI / build-server-core (push) Successful in 4m29s
CI / server-core-test (push) Has been skipped
CI / device-agent-test (push) Has been skipped
CI / dashboard-test (push) Has been skipped
CI / build-device-agent (push) Successful in 1m49s
CI / build-dashboard (push) Successful in 1m11s
CI / build-docs (push) Successful in 58s
CI / release (push) Successful in 27s
2026-06-10 15:01:34 +07:00
datadunia 4c8fe3c8d6 fix: token-derived provisioning encryption (no SERVER_SALT on client) 2026-06-10 14:56:04 +07:00
datadunia 8dd5834be2 ci: revert persist-credentials to true (runner now uses https://git.datadunia.com)
CI / release (push) Successful in 26s
CI / server-core-test (push) Has been skipped
CI / device-agent-test (push) Has been skipped
CI / dashboard-test (push) Has been skipped
CI / build-server-core (push) Successful in 3m39s
CI / build-device-agent (push) Successful in 1m35s
CI / build-dashboard (push) Successful in 52s
CI / build-docs (push) Successful in 1m7s
2026-06-10 14:10:54 +07:00
datadunia 9461d6b385 chore: update device-agent submodule ref (CLI args + conf file support)
CI / server-core-test (push) Has been skipped
CI / device-agent-test (push) Has been skipped
CI / dashboard-test (push) Has been skipped
CI / build-server-core (push) Failing after 32s
CI / build-device-agent (push) Failing after 28s
CI / build-dashboard (push) Failing after 27s
CI / build-docs (push) Failing after 27s
CI / release (push) Has been skipped
2026-06-10 13:58:36 +07:00
datadunia c0f18a41a1 ci: fix submodule auth + replace matrix build for device-agent
CI / server-core-test (push) Has been skipped
CI / device-agent-test (push) Has been skipped
CI / dashboard-test (push) Has been skipped
CI / build-server-core (push) Successful in 3m44s
CI / build-device-agent (push) Successful in 1m38s
CI / build-dashboard (push) Successful in 3m39s
CI / build-docs (push) Successful in 51s
CI / release (push) Successful in 46s
- persist-credentials: false on all workflows (prevent Gitea overwriting insteadOf URL)
- Replace matrix strategy in build_device_agent.yaml with sequential builds (act_runner v0.6.1 ParallelExecutor crash)
- Build all 3 platforms (linux/amd64, linux/arm64, windows/amd64) in single step
2026-06-10 11:04:48 +07:00
datadunia 96248d3d31 ci: downgrade upload/download-artifact v4 to v3
CI / server-core-test (push) Has been skipped
CI / device-agent-test (push) Has been skipped
CI / dashboard-test (push) Has been skipped
CI / build-server-core (push) Successful in 6m58s
CI / build-dashboard (push) Successful in 1m4s
CI / build-docs (push) Successful in 52s
CI / release (push) Has been cancelled
CI / build-device-agent (push) Has been cancelled
Gitea self-hosted 1.26.1 does not support @actions/artifact v2.0.0+
(upload-artifact@v4+, download-artifact@v4+). Use v3 instead.
2026-06-10 09:42:47 +07:00
datadunia bfb6dcc42f ci: skip tests for dev/beta/release, test-only for test tags
CI / server-core-test (push) Has been skipped
CI / device-agent-test (push) Has been skipped
CI / dashboard-test (push) Has been skipped
CI / build-server-core (push) Failing after 4m46s
CI / build-dashboard (push) Failing after 1m17s
CI / build-docs (push) Failing after 1m5s
CI / release (push) Has been cancelled
CI / build-device-agent (push) Has been cancelled
- Test jobs: add if: contains(gitea.ref_name, 'test')
- Build jobs: remove needs dependency on tests
- dev/beta/release: build+release directly, no tests
- test tags: tests only, no build
2026-06-10 09:26:25 +07:00
datadunia 9470435704 ci: add secrets: inherit to build workflow calls
CI / server-core-test (push) Successful in 5m59s
CI / device-agent-test (push) Successful in 1m19s
CI / dashboard-test (push) Successful in 1m9s
CI / build-server-core (push) Failing after 4m44s
CI / build-device-agent (push) Failing after 2m0s
CI / build-docs (push) Has been cancelled
CI / release (push) Has been cancelled
CI / build-dashboard (push) Has been cancelled
Reusable workflows dont inherit secrets from caller by default.
secrets.BUILD_TOKEN was empty string, causing:
  ::error::Input required and not supplied: token

Added secrets: inherit to all 4 build workflow calls in ci.yml.
2026-06-10 09:21:50 +07:00
datadunia c37d4a751c ci: fix build workflows - remove defaults.run.working-directory
CI / build-server-core (push) Failing after 26s
CI / build-dashboard (push) Failing after 20s
CI / build-docs (push) Failing after 20s
CI / server-core-test (push) Successful in 5m33s
CI / device-agent-test (push) Successful in 1m22s
CI / dashboard-test (push) Successful in 1m5s
CI / build-device-agent (push) Failing after 20s
CI / release (push) Has been skipped
All 4 build jobs failed because defaults.run.working-directory
chdir'd into subdirs before checkout created them.

- Remove defaults.run.working-directory from all reusable workflows
- Add per-step working-directory to run steps that need it
- Auth config step runs from repo root (no working-directory)
2026-06-10 09:05:26 +07:00
datadunia 072aa48db0 ci: update server-core submodule with test fixes
CI / server-core-test (push) Successful in 5m23s
CI / device-agent-test (push) Successful in 1m25s
CI / dashboard-test (push) Successful in 1m10s
CI / build-server-core (push) Failing after 48s
CI / build-device-agent (push) Failing after 16s
CI / build-dashboard (push) Failing after 16s
CI / build-docs (push) Failing after 18s
CI / release (push) Has been skipped
2026-06-10 08:33:40 +07:00
datadunia 47ca075bc0 ci: remove env vars from server-core-test, update submodule
CI / server-core-test (push) Failing after 5m31s
CI / device-agent-test (push) Successful in 1m21s
CI / dashboard-test (push) Successful in 1m11s
CI / build-server-core (push) Has been skipped
CI / build-device-agent (push) Has been skipped
CI / build-dashboard (push) Has been skipped
CI / build-docs (push) Has been skipped
CI / release (push) Has been skipped
2026-06-10 08:04:30 +07:00
datadunia 8938d842db ci: skip nftables tests, add env vars for server-core
CI / server-core-test (push) Failing after 6m19s
CI / device-agent-test (push) Successful in 1m30s
CI / dashboard-test (push) Successful in 1m1s
CI / build-docs (push) Has been skipped
CI / release (push) Has been skipped
CI / build-server-core (push) Has been skipped
CI / build-device-agent (push) Has been skipped
CI / build-dashboard (push) Has been skipped
2026-06-10 07:00:04 +07:00
datadunia 710cc6537e ci: add swag init step before server-core test
CI / server-core-test (push) Failing after 5m46s
CI / device-agent-test (push) Successful in 1m29s
CI / dashboard-test (push) Successful in 1m27s
CI / build-server-core (push) Has been skipped
CI / build-device-agent (push) Has been skipped
CI / build-dashboard (push) Has been skipped
CI / build-docs (push) Has been skipped
CI / release (push) Has been skipped
2026-06-10 06:41:40 +07:00
datadunia 224a84e856 ci: fix working-directory defaults breaking pre-checkout steps
CI / device-agent-test (push) Has been cancelled
CI / dashboard-test (push) Has been cancelled
CI / build-server-core (push) Has been cancelled
CI / build-device-agent (push) Has been cancelled
CI / build-dashboard (push) Has been cancelled
CI / build-docs (push) Has been cancelled
CI / release (push) Has been cancelled
CI / server-core-test (push) Has been cancelled
2026-06-10 05:08:26 +07:00
datadunia 062e82bd97 ci: cleanup script + .gitignore for scripts/
CI / server-core-test (push) Failing after 8s
CI / build-dashboard (push) Has been skipped
CI / release (push) Has been skipped
CI / device-agent-test (push) Failing after 6s
CI / dashboard-test (push) Failing after 7s
CI / build-server-core (push) Has been skipped
CI / build-device-agent (push) Has been skipped
CI / build-docs (push) Has been skipped
2026-06-10 05:05:44 +07:00
datadunia 43fd852b3e ci: use git URL rewrite with token for submodule auth 2026-06-10 05:02:41 +07:00
datadunia 946334ffc7 ci: rewrite git.datadunia.com to 172.20.8.90:3000 for submodule auth 2026-06-10 04:56:18 +07:00
datadunia 94ed6a8184 ci: fix submodule URLs to HTTPS for reverse proxy
CI / dashboard-test (push) Failing after 18s
CI / server-core-test (push) Failing after 15s
CI / device-agent-test (push) Failing after 14s
CI / build-server-core (push) Has been skipped
CI / build-device-agent (push) Has been skipped
CI / build-dashboard (push) Has been skipped
CI / build-docs (push) Has been skipped
CI / release (push) Has been skipped
2026-06-10 04:52:34 +07:00
datadunia 5b5a4aa009 ci: add BUILD_TOKEN for submodule checkout authentication
CI / server-core-test (push) Failing after 18s
CI / device-agent-test (push) Failing after 14s
CI / dashboard-test (push) Failing after 15s
CI / build-server-core (push) Has been skipped
CI / build-device-agent (push) Has been skipped
CI / build-dashboard (push) Has been skipped
CI / build-docs (push) Has been skipped
CI / release (push) Has been skipped
2026-06-10 04:26:22 +07:00
datadunia 0a22ecd13f chore: update device-agent submodule ref
CI / server-core-test (push) Failing after 20s
CI / device-agent-test (push) Failing after 14s
CI / dashboard-test (push) Failing after 17s
CI / build-server-core (push) Has been skipped
CI / build-device-agent (push) Has been skipped
CI / build-dashboard (push) Has been skipped
CI / build-docs (push) Has been skipped
CI / release (push) Has been skipped
2026-06-10 04:01:54 +07:00
datadunia 56d70ed031 ci: test always runs, test tags skip build/release
CI / server-core-test (push) Failing after 24s
CI / device-agent-test (push) Failing after 20s
CI / dashboard-test (push) Failing after 23s
CI / build-server-core (push) Has been skipped
CI / build-device-agent (push) Has been skipped
CI / build-dashboard (push) Has been skipped
CI / build-docs (push) Has been skipped
CI / release (push) Has been skipped
2026-06-10 03:47:00 +07:00
datadunia 3133671c02 ci: test only for tags with 'test' in name 2026-06-10 03:45:01 +07:00
datadunia 5fa9f414b0 ci: trigger only on tags, remove push/PR triggers
CI / server-core-test (push) Failing after 4s
CI / device-agent-test (push) Failing after 4s
CI / dashboard-test (push) Failing after 4s
CI / build-docs (push) Failing after 9s
CI / build-server-core (push) Has been skipped
CI / build-device-agent (push) Has been skipped
CI / build-dashboard (push) Has been skipped
CI / release (push) Has been skipped
2026-06-10 03:42:28 +07:00
datadunia 233f14f998 chore: update server-core submodule ref (Swaggo fix)
CI / server-core-test (push) Failing after 4s
CI / device-agent-test (push) Failing after 4s
CI / dashboard-test (push) Failing after 4s
CI / build-docs (push) Has been skipped
CI / build-server-core (push) Has been skipped
CI / build-device-agent (push) Has been skipped
CI / build-dashboard (push) Has been skipped
CI / release (push) Has been skipped
2026-06-10 03:33:08 +07:00
datadunia c5364cf5ba ci: unify workflows - split build per component, single tag-triggered pipeline
CI / server-core-test (push) Failing after 4s
CI / device-agent-test (push) Failing after 4s
CI / dashboard-test (push) Failing after 4s
CI / build-docs (push) Failing after 9s
CI / build-server-core (push) Has been skipped
CI / build-device-agent (push) Has been skipped
CI / build-dashboard (push) Has been skipped
CI / release (push) Has been skipped
2026-06-10 03:29:59 +07:00
datadunia 60d326880a docs: reorganize documentation with i18n and Swagger API reference
- Add per-submodule docs structure (server-core, dashboard-ui, device-agent)
- Restructure VitePress with i18n support (Indonesian default + English)
- Add Swagger API reference pages with Swagger UI CDN embed
- Create merge.js script for combining sidebar manifests
- Integrate docs build into Docker (update.sh + nginx volume mount)
- Add documentation section to root README
2026-06-10 02:36:24 +07:00
datadunia 13e8787553 chore(gitignore): update device-agent submodule ref
NexusGuard CI / server-core-test (push) Failing after 4s
NexusGuard CI / server-core-build (push) Has been skipped
NexusGuard CI / device-agent-test (push) Failing after 4s
NexusGuard CI / device-agent-cross-build (amd64, linux) (push) Has been skipped
NexusGuard CI / device-agent-cross-build (amd64, windows) (push) Has been skipped
NexusGuard CI / device-agent-cross-build (arm64, linux) (push) Has been skipped
NexusGuard CI / dashboard-test (push) Failing after 4s
NexusGuard CI / dashboard-dist (push) Has been skipped
2026-06-09 21:45:22 +07:00
datadunia 5795677fd1 chore(gitignore): exclude test artifacts (*-test)
NexusGuard CI / server-core-test (push) Failing after 4s
NexusGuard CI / server-core-build (push) Has been skipped
NexusGuard CI / device-agent-test (push) Failing after 4s
NexusGuard CI / device-agent-cross-build (amd64, linux) (push) Has been skipped
NexusGuard CI / device-agent-cross-build (amd64, windows) (push) Has been skipped
NexusGuard CI / device-agent-cross-build (arm64, linux) (push) Has been skipped
NexusGuard CI / dashboard-test (push) Failing after 4s
NexusGuard CI / dashboard-dist (push) Has been skipped
2026-06-09 21:44:35 +07:00
datadunia 7cae9dacf0 chore(gitignore): reorganize .omo and .sisyphus patterns
NexusGuard CI / server-core-test (push) Failing after 3m3s
NexusGuard CI / server-core-build (push) Has been skipped
NexusGuard CI / device-agent-test (push) Failing after 4s
NexusGuard CI / device-agent-cross-build (amd64, linux) (push) Has been skipped
NexusGuard CI / device-agent-cross-build (amd64, windows) (push) Has been skipped
NexusGuard CI / device-agent-cross-build (arm64, linux) (push) Has been skipped
NexusGuard CI / dashboard-test (push) Failing after 5s
NexusGuard CI / dashboard-dist (push) Has been skipped
Consolidate duplicate entries and group plugin config directories
under a single comment block for clarity.
2026-06-09 21:22:51 +07:00
datadunia a745e84470 feat: Phase 3 — RBAC, device health dashboard, Swaggo annotations
Platform enhancements across server-core and dashboard:
- RBAC: Admin + Viewer roles on User model, RequireRole middleware
- All isAdmin() calls replaced with role-based access checks
- Device health API endpoint and dashboard page
- Swaggo annotations for auto-generated API docs
- Fixed Forwards.vue TypeScript type mismatch
2026-06-09 19:56:42 +07:00
datadunia 68a6270b8c feat: add port forwarding (Phase 2)
- Server: PortForward model + CRUD API (5 endpoints)
- Agent: TCP/UDP forwarder engine + client API + CLI commands
- Dashboard: Forwards management page with create/delete

Submodules: server-core, device-agent, dashboard-ui
2026-06-09 08:13:44 +07:00
datadunia 6b47f9af17 fix(firewall): update server-core — addRule insert→append fix
NexusGuard CI / server-core-test (push) Failing after 3s
NexusGuard CI / server-core-build (push) Has been skipped
NexusGuard CI / device-agent-test (push) Failing after 3s
NexusGuard CI / device-agent-cross-build (amd64, linux) (push) Has been skipped
NexusGuard CI / device-agent-cross-build (amd64, windows) (push) Has been skipped
NexusGuard CI / device-agent-cross-build (arm64, linux) (push) Has been skipped
NexusGuard CI / dashboard-test (push) Failing after 4s
NexusGuard CI / dashboard-dist (push) Has been skipped
2026-06-08 06:43:45 +07:00
datadunia bd93d37645 fix(firewall): update server-core submodule — remove legacy chain rules
NexusGuard CI / server-core-test (push) Failing after 5s
NexusGuard CI / server-core-build (push) Has been skipped
NexusGuard CI / device-agent-test (push) Failing after 3s
NexusGuard CI / device-agent-cross-build (amd64, linux) (push) Has been skipped
NexusGuard CI / device-agent-cross-build (amd64, windows) (push) Has been skipped
NexusGuard CI / device-agent-cross-build (arm64, linux) (push) Has been skipped
NexusGuard CI / dashboard-test (push) Failing after 3s
NexusGuard CI / dashboard-dist (push) Has been skipped
2026-06-08 06:36:02 +07:00
datadunia 2e7a6aba90 feat(traffic): deploy hourly aggregation + server pagination
NexusGuard CI / server-core-test (push) Failing after 4s
NexusGuard CI / server-core-build (push) Has been skipped
NexusGuard CI / device-agent-test (push) Failing after 4s
NexusGuard CI / device-agent-cross-build (amd64, linux) (push) Has been skipped
NexusGuard CI / device-agent-cross-build (amd64, windows) (push) Has been skipped
NexusGuard CI / device-agent-cross-build (arm64, linux) (push) Has been skipped
NexusGuard CI / dashboard-test (push) Failing after 4s
NexusGuard CI / dashboard-dist (push) Has been skipped
2026-06-08 05:44:55 +07:00
datadunia 307cc34752 fix: lock primary node by interface_name wg0
NexusGuard CI / server-core-test (push) Failing after 3s
NexusGuard CI / server-core-build (push) Has been skipped
NexusGuard CI / device-agent-test (push) Failing after 4s
NexusGuard CI / device-agent-cross-build (amd64, linux) (push) Has been skipped
NexusGuard CI / device-agent-cross-build (amd64, windows) (push) Has been skipped
NexusGuard CI / device-agent-cross-build (arm64, linux) (push) Has been skipped
NexusGuard CI / dashboard-test (push) Failing after 4s
NexusGuard CI / dashboard-dist (push) Has been skipped
2026-06-08 04:22:48 +07:00
datadunia 9aaa9ebfb7 fix(servers): allow deleting local nodes, check peer count before delete
NexusGuard CI / server-core-test (push) Failing after 4s
NexusGuard CI / server-core-build (push) Has been skipped
NexusGuard CI / device-agent-test (push) Failing after 4s
NexusGuard CI / device-agent-cross-build (amd64, linux) (push) Has been skipped
NexusGuard CI / device-agent-cross-build (amd64, windows) (push) Has been skipped
NexusGuard CI / device-agent-cross-build (arm64, linux) (push) Has been skipped
NexusGuard CI / dashboard-test (push) Failing after 3s
NexusGuard CI / dashboard-dist (push) Has been skipped
2026-06-08 04:17:38 +07:00
datadunia ad52b39ed7 fix(dashboard): remove overflow-y-auto from modal panel to fix select dropdown clipping
NexusGuard CI / server-core-test (push) Failing after 4s
NexusGuard CI / server-core-build (push) Has been skipped
NexusGuard CI / device-agent-test (push) Failing after 4s
NexusGuard CI / device-agent-cross-build (amd64, linux) (push) Has been skipped
NexusGuard CI / device-agent-cross-build (amd64, windows) (push) Has been skipped
NexusGuard CI / device-agent-cross-build (arm64, linux) (push) Has been skipped
NexusGuard CI / dashboard-test (push) Failing after 4s
NexusGuard CI / dashboard-dist (push) Has been skipped
2026-06-08 04:12:50 +07:00
datadunia d9d99e7827 feat(dashboard): show interface_name as read-only in Edit modal
NexusGuard CI / server-core-test (push) Failing after 4s
NexusGuard CI / server-core-build (push) Has been skipped
NexusGuard CI / device-agent-test (push) Failing after 3s
NexusGuard CI / device-agent-cross-build (amd64, linux) (push) Has been skipped
NexusGuard CI / device-agent-cross-build (amd64, windows) (push) Has been skipped
NexusGuard CI / device-agent-cross-build (arm64, linux) (push) Has been skipped
NexusGuard CI / dashboard-test (push) Failing after 4s
NexusGuard CI / dashboard-dist (push) Has been skipped
2026-06-08 03:57:49 +07:00
datadunia 736319645e feat(servers): auto-gen keys, duplicate name validation, simplify UI
NexusGuard CI / server-core-test (push) Failing after 4s
NexusGuard CI / server-core-build (push) Has been skipped
NexusGuard CI / device-agent-test (push) Failing after 4s
NexusGuard CI / device-agent-cross-build (amd64, linux) (push) Has been skipped
NexusGuard CI / device-agent-cross-build (amd64, windows) (push) Has been skipped
NexusGuard CI / device-agent-cross-build (arm64, linux) (push) Has been skipped
NexusGuard CI / dashboard-test (push) Failing after 4s
NexusGuard CI / dashboard-dist (push) Has been skipped
2026-06-08 03:48:59 +07:00
datadunia 8e04f33fc3 fix(dashboard): hide Local Server toggle, hardcode is_local=true
NexusGuard CI / server-core-test (push) Failing after 5s
NexusGuard CI / server-core-build (push) Has been skipped
NexusGuard CI / device-agent-test (push) Failing after 3s
NexusGuard CI / device-agent-cross-build (amd64, linux) (push) Has been skipped
NexusGuard CI / device-agent-cross-build (amd64, windows) (push) Has been skipped
NexusGuard CI / device-agent-cross-build (arm64, linux) (push) Has been skipped
NexusGuard CI / dashboard-test (push) Failing after 4s
NexusGuard CI / dashboard-dist (push) Has been skipped
2026-06-08 03:05:33 +07:00
datadunia 53df67f085 feat(dashboard): show all local WireGuard engines with per-interface status
NexusGuard CI / server-core-test (push) Failing after 4s
NexusGuard CI / server-core-build (push) Has been skipped
NexusGuard CI / device-agent-test (push) Failing after 4s
NexusGuard CI / device-agent-cross-build (amd64, linux) (push) Has been skipped
NexusGuard CI / device-agent-cross-build (amd64, windows) (push) Has been skipped
NexusGuard CI / device-agent-cross-build (arm64, linux) (push) Has been skipped
NexusGuard CI / dashboard-test (push) Failing after 3s
NexusGuard CI / dashboard-dist (push) Has been skipped
2026-06-08 02:50:25 +07:00
datadunia ca52c3bde4 fix(backfill): target server by name, auto-assign interface_name
NexusGuard CI / server-core-test (push) Failing after 3s
NexusGuard CI / server-core-build (push) Has been skipped
NexusGuard CI / device-agent-test (push) Failing after 3s
NexusGuard CI / device-agent-cross-build (amd64, linux) (push) Has been skipped
NexusGuard CI / device-agent-cross-build (amd64, windows) (push) Has been skipped
NexusGuard CI / device-agent-cross-build (arm64, linux) (push) Has been skipped
NexusGuard CI / dashboard-test (push) Failing after 4s
NexusGuard CI / dashboard-dist (push) Has been skipped
2026-06-08 02:28:37 +07:00
datadunia 78fcce0d28 chore: update dashboard-ui submodule
NexusGuard CI / server-core-test (push) Failing after 4s
NexusGuard CI / server-core-build (push) Has been skipped
NexusGuard CI / device-agent-test (push) Failing after 4s
NexusGuard CI / device-agent-cross-build (amd64, linux) (push) Has been skipped
NexusGuard CI / device-agent-cross-build (amd64, windows) (push) Has been skipped
NexusGuard CI / device-agent-cross-build (arm64, linux) (push) Has been skipped
NexusGuard CI / dashboard-test (push) Failing after 3s
NexusGuard CI / dashboard-dist (push) Has been skipped
2026-06-08 01:51:44 +07:00
datadunia a4a06593b1 chore: update dashboard-ui submodule
NexusGuard CI / server-core-test (push) Failing after 4s
NexusGuard CI / server-core-build (push) Has been skipped
NexusGuard CI / device-agent-test (push) Failing after 3s
NexusGuard CI / device-agent-cross-build (amd64, linux) (push) Has been skipped
NexusGuard CI / device-agent-cross-build (amd64, windows) (push) Has been skipped
NexusGuard CI / device-agent-cross-build (arm64, linux) (push) Has been skipped
NexusGuard CI / dashboard-test (push) Failing after 3s
NexusGuard CI / dashboard-dist (push) Has been skipped
2026-06-08 01:36:39 +07:00
datadunia e7b1f22b44 chore: update server-core submodule
NexusGuard CI / server-core-test (push) Failing after 5s
NexusGuard CI / server-core-build (push) Has been skipped
NexusGuard CI / device-agent-test (push) Failing after 3s
NexusGuard CI / device-agent-cross-build (amd64, linux) (push) Has been skipped
NexusGuard CI / device-agent-cross-build (amd64, windows) (push) Has been skipped
NexusGuard CI / device-agent-cross-build (arm64, linux) (push) Has been skipped
NexusGuard CI / dashboard-test (push) Failing after 3s
NexusGuard CI / dashboard-dist (push) Has been skipped
2026-06-08 00:38:05 +07:00
datadunia cbacfea7f2 chore: update submodule refs, clean up plans/evidence, update .gitignore
NexusGuard CI / server-core-test (push) Failing after 3m6s
NexusGuard CI / server-core-build (push) Has been skipped
NexusGuard CI / device-agent-test (push) Failing after 4s
NexusGuard CI / device-agent-cross-build (amd64, linux) (push) Has been skipped
NexusGuard CI / device-agent-cross-build (amd64, windows) (push) Has been skipped
NexusGuard CI / device-agent-cross-build (arm64, linux) (push) Has been skipped
NexusGuard CI / dashboard-test (push) Failing after 4s
NexusGuard CI / dashboard-dist (push) Has been skipped
2026-06-07 23:53:15 +07:00
datadunia 281ac48d28 docs: update AGENTS.md, archive plans
NexusGuard CI / server-core-test (push) Failing after 3m30s
NexusGuard CI / server-core-build (push) Has been skipped
NexusGuard CI / device-agent-test (push) Failing after 3s
NexusGuard CI / device-agent-cross-build (amd64, linux) (push) Has been skipped
NexusGuard CI / device-agent-cross-build (amd64, windows) (push) Has been skipped
NexusGuard CI / device-agent-cross-build (arm64, linux) (push) Has been skipped
NexusGuard CI / dashboard-test (push) Failing after 3s
NexusGuard CI / dashboard-dist (push) Has been skipped
2026-06-07 06:14:46 +07:00
datadunia c2f0e53f1d chore: update server-core submodule for multi-interface refactor 2026-06-07 04:40:14 +07:00
63 changed files with 3853 additions and 386 deletions
-16
View File
@@ -1,16 +0,0 @@
name: Beta Release
on:
push:
tags:
- 'v*-beta*'
- 'v*-test*'
- 'dev-*'
jobs:
deploy:
if: "contains(gitea.ref_name, 'beta') || contains(gitea.ref_name, 'test') || startsWith(gitea.ref_name, 'dev-')"
uses: ./.gitea/workflows/deploy_call.yaml
with:
prerelease: true
secrets: inherit
+61
View File
@@ -0,0 +1,61 @@
name: Build Dashboard UI
on:
workflow_call:
jobs:
build:
runs-on: ubuntu-latest
env:
RUNNER_TOOL_CACHE: /toolcache
steps:
- name: Configure git auth for submodules
run: git config --global url."https://x-access-token:${{ secrets.BUILD_TOKEN }}@git.datadunia.com/".insteadOf "https://git.datadunia.com/"
- uses: actions/checkout@v4
with:
submodules: true
fetch-depth: 0
token: ${{ secrets.BUILD_TOKEN }}
persist-credentials: true
- uses: actions/setup-node@v4
with:
node-version: '24'
- name: Hash source files
id: hash-src
run: echo "hash=$(find apps/dashboard-ui -type f \( -name '*.vue' -o -name '*.ts' -o -name '*.js' -o -name '*.css' -o -name '*.json' -o -name '*.html' \) | sort | xargs sha256sum | sha256sum | cut -d' ' -f1)" >> "$GITHUB_OUTPUT"
- uses: actions/cache@v3
id: cache-build
with:
path: apps/dashboard-ui/dist
key: build-dashboard-${{ steps.hash-src.outputs.hash }}
- name: Hash package-lock
id: hash-npm
run: echo "hash=$(sha256sum apps/dashboard-ui/package-lock.json | cut -d' ' -f1)" >> "$GITHUB_OUTPUT"
- uses: actions/cache@v3
id: cache-npm
with:
path: ~/.npm
key: npm-dashboard-${{ steps.hash-npm.outputs.hash }}
restore-keys: npm-dashboard-
- name: Install
if: steps.cache-build.outputs.cache-hit != 'true'
working-directory: apps/dashboard-ui
run: npm ci || npm install
- name: Build
if: steps.cache-build.outputs.cache-hit != 'true'
working-directory: apps/dashboard-ui
run: npm run build
- name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: dashboard-ui-dist
path: apps/dashboard-ui/dist/
+83
View File
@@ -0,0 +1,83 @@
name: Build Device Agent
on:
workflow_call:
jobs:
cross-build:
runs-on: ubuntu-latest
env:
RUNNER_TOOL_CACHE: /toolcache
steps:
- name: Configure git auth for submodules
run: git config --global url."https://x-access-token:${{ secrets.BUILD_TOKEN }}@git.datadunia.com/".insteadOf "https://git.datadunia.com/"
- uses: actions/checkout@v4
with:
submodules: true
fetch-depth: 0
token: ${{ secrets.BUILD_TOKEN }}
persist-credentials: true
- uses: actions/setup-go@v5
with:
go-version: '1.26'
cache: true
- uses: https://gitea.com/actions/go-hashfiles@v0.0.1
id: hash-src
with:
patterns: |
apps/device-agent/**/*.go
apps/device-agent/go.mod
apps/device-agent/go.sum
- uses: actions/cache@v3
id: cache-build
with:
path: apps/device-agent/bin
key: build-device-agent-${{ steps.hash-src.outputs.hash }}
- name: Generate Windows resources (UAC manifest + icon)
if: steps.cache-build.outputs.cache-hit != 'true'
working-directory: apps/device-agent
run: |
go install github.com/tc-hib/go-winres@latest
go-winres make
- name: Build all platforms
if: steps.cache-build.outputs.cache-hit != 'true'
working-directory: apps/device-agent
shell: bash
run: |
set -e
mkdir -p bin
for PAIR in linux/amd64 linux/arm64 windows/amd64; do
GOOS="${PAIR%%/*}"
GOARCH="${PAIR##*/}"
EXT=""
if [ "$GOOS" = "windows" ]; then EXT=".exe"; fi
OUT="bin/nexus-device-agent-${GOOS}-${GOARCH}${EXT}"
echo "Building $OUT ..."
CGO_ENABLED=0 GOOS="$GOOS" GOARCH="$GOARCH" go build -o "$OUT" .
done
echo "=== Build output ==="
ls -la bin/
- name: Upload linux/amd64
uses: actions/upload-artifact@v3
with:
name: nexus-device-agent-linux-amd64
path: apps/device-agent/bin/nexus-device-agent-linux-amd64
- name: Upload linux/arm64
uses: actions/upload-artifact@v3
with:
name: nexus-device-agent-linux-arm64
path: apps/device-agent/bin/nexus-device-agent-linux-arm64
- name: Upload windows/amd64
uses: actions/upload-artifact@v3
with:
name: nexus-device-agent-windows-amd64
path: apps/device-agent/bin/nexus-device-agent-windows-amd64.exe
+59
View File
@@ -0,0 +1,59 @@
name: Build Server Core
on:
workflow_call:
jobs:
build:
runs-on: ubuntu-latest
env:
RUNNER_TOOL_CACHE: /toolcache
steps:
- name: Configure git auth for submodules
run: git config --global url."https://x-access-token:${{ secrets.BUILD_TOKEN }}@git.datadunia.com/".insteadOf "https://git.datadunia.com/"
- uses: actions/checkout@v4
with:
submodules: true
fetch-depth: 0
token: ${{ secrets.BUILD_TOKEN }}
persist-credentials: true
- uses: actions/setup-go@v5
with:
go-version: '1.26'
cache: true
- uses: https://gitea.com/actions/go-hashfiles@v0.0.1
id: hash-src
with:
patterns: |
apps/server-core/**/*.go
apps/server-core/go.mod
apps/server-core/go.sum
- uses: actions/cache@v3
id: cache-build
with:
path: |
apps/server-core/bin
apps/server-core/docs
key: build-server-core-${{ steps.hash-src.outputs.hash }}
- name: Generate Swagger docs
if: steps.cache-build.outputs.cache-hit != 'true'
working-directory: apps/server-core
run: |
go install github.com/swaggo/swag/cmd/swag@v1.16.6
swag init -g main.go --parseDependency --parseInternal
- name: Build
if: steps.cache-build.outputs.cache-hit != 'true'
working-directory: apps/server-core
run: go build -o bin/server-core .
- name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: server-core-linux-amd64
path: apps/server-core/bin/server-core
+73 -118
View File
@@ -1,25 +1,21 @@
name: NexusGuard CI
name: CI
on:
push:
branches:
- main
pull_request:
branches:
- main
env:
BUILD_TOKEN: ${{ secrets.BUILD_TOKEN }}
tags:
- 'dev-*'
- 'v*-dev*'
- 'v*-beta*'
- 'v*-test*'
- 'v[0-9]*.[0-9]*.[0-9]'
jobs:
# ──────────────────────────────────────────────
# TEST — all 3 components in parallel
# ──────────────────────────────────────────────
# ====================================================================
# TESTStest tags only
# ====================================================================
server-core-test:
if: contains(gitea.ref_name, 'test')
runs-on: ubuntu-latest
defaults:
run:
working-directory: apps/server-core
steps:
- uses: actions/checkout@v4
with:
@@ -27,18 +23,19 @@ jobs:
fetch-depth: 0
token: ${{ secrets.BUILD_TOKEN }}
persist-credentials: true
github-server-url: 'https://git.datadunia.com'
- name: Configure git auth for submodules
run: git config --global url."https://x-access-token:${{ secrets.BUILD_TOKEN }}@git.datadunia.com/".insteadOf "https://git.datadunia.com/"
- uses: actions/setup-go@v5
with:
go-version: '1.25'
- name: Test
run: go test ./... -tags dev -cover
go-version: '1.26'
cache: true
- name: Test (skip nftables - needs root)
working-directory: apps/server-core
run: go test $(go list ./... | grep -v internal/firewall) -tags dev -cover -count=1
device-agent-test:
if: contains(gitea.ref_name, 'test')
runs-on: ubuntu-latest
defaults:
run:
working-directory: apps/device-agent
steps:
- uses: actions/checkout@v4
with:
@@ -46,18 +43,19 @@ jobs:
fetch-depth: 0
token: ${{ secrets.BUILD_TOKEN }}
persist-credentials: true
github-server-url: 'https://git.datadunia.com'
- name: Configure git auth for submodules
run: git config --global url."https://x-access-token:${{ secrets.BUILD_TOKEN }}@git.datadunia.com/".insteadOf "https://git.datadunia.com/"
- uses: actions/setup-go@v5
with:
go-version: '1.25'
go-version: '1.26'
cache: true
- name: Test
working-directory: apps/device-agent
run: go test ./... -cover
dashboard-test:
if: contains(gitea.ref_name, 'test')
runs-on: ubuntu-latest
defaults:
run:
working-directory: apps/dashboard-ui
steps:
- uses: actions/checkout@v4
with:
@@ -65,103 +63,60 @@ jobs:
fetch-depth: 0
token: ${{ secrets.BUILD_TOKEN }}
persist-credentials: true
github-server-url: 'https://git.datadunia.com'
- name: Configure git auth for submodules
run: git config --global url."https://x-access-token:${{ secrets.BUILD_TOKEN }}@git.datadunia.com/".insteadOf "https://git.datadunia.com/"
- uses: actions/setup-node@v4
with:
node-version: '24'
- name: Install
run: npm ci || npm install
- name: Build
run: npm run build
# ──────────────────────────────────────────────
# BUILD — binaries + frontend dist
# ──────────────────────────────────────────────
server-core-build:
runs-on: ubuntu-latest
needs: server-core-test
defaults:
run:
working-directory: apps/server-core
steps:
- uses: actions/checkout@v4
with:
submodules: true
token: ${{ secrets.BUILD_TOKEN }}
persist-credentials: true
github-server-url: 'https://git.datadunia.com'
- uses: actions/setup-go@v5
with:
go-version: '1.25'
- name: Build
run: go build -o bin/server-core .
- name: Upload binary
uses: actions/upload-artifact@v4
with:
name: server-core-linux-amd64
path: apps/server-core/bin/server-core
device-agent-cross-build:
runs-on: ubuntu-latest
needs: device-agent-test
strategy:
matrix:
goos: [linux, windows]
goarch: [amd64, arm64]
exclude:
- goos: windows
goarch: arm64
defaults:
run:
working-directory: apps/device-agent
steps:
- uses: actions/checkout@v4
with:
submodules: true
token: ${{ secrets.BUILD_TOKEN }}
persist-credentials: true
github-server-url: 'https://git.datadunia.com'
- uses: actions/setup-go@v5
with:
go-version: '1.25'
- name: Build
env:
CGO_ENABLED: 0
GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goarch }}
run: |
EXT=""
if [ "${{ matrix.goos }}" = "windows" ]; then EXT=".exe"; fi
go build -o bin/nexus-device-agent-${{ matrix.goos }}-${{ matrix.goarch }}${EXT} .
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: nexus-device-agent-${{ matrix.goos }}-${{ matrix.goarch }}
path: apps/device-agent/bin/nexus-device-agent-*
dashboard-dist:
runs-on: ubuntu-latest
needs: dashboard-test
defaults:
run:
working-directory: apps/dashboard-ui
steps:
- uses: actions/checkout@v4
with:
submodules: true
token: ${{ secrets.BUILD_TOKEN }}
github-server-url: 'https://git.datadunia.com'
- uses: actions/setup-node@v4
with:
node-version: '24'
- name: Install
run: npm ci || npm install
- name: Build
working-directory: apps/dashboard-ui
run: npm run build
- name: Upload dist
uses: actions/upload-artifact@v4
# ====================================================================
# BUILD — after tests pass (release) or directly (dev/beta)
# ====================================================================
build-server-core:
if: always() && !contains(gitea.ref_name, 'test') && !failure() && !cancelled()
needs: [server-core-test, device-agent-test, dashboard-test]
runs-on: ubuntu-latest
uses: ./.gitea/workflows/build_server_core.yaml
secrets: inherit
build-device-agent:
if: always() && !contains(gitea.ref_name, 'test') && !failure() && !cancelled()
needs: [server-core-test, device-agent-test, dashboard-test]
runs-on: ubuntu-latest
uses: ./.gitea/workflows/build_device_agent.yaml
secrets: inherit
build-dashboard:
if: always() && !contains(gitea.ref_name, 'test') && !failure() && !cancelled()
needs: [server-core-test, device-agent-test, dashboard-test]
runs-on: ubuntu-latest
uses: ./.gitea/workflows/build_dashboard.yaml
secrets: inherit
# ====================================================================
# DOCS — after builds pass, release tags only
# ====================================================================
build-docs:
if: always() && !contains(gitea.ref_name, 'dev') && !contains(gitea.ref_name, 'beta') && !contains(gitea.ref_name, 'test') && !failure() && !cancelled()
needs: [build-server-core, build-device-agent, build-dashboard]
runs-on: ubuntu-latest
uses: ./.gitea/workflows/docs_call.yaml
secrets: inherit
# ====================================================================
# RELEASE — after everything passes
# ====================================================================
release:
if: always() && !contains(gitea.ref_name, 'test') && !failure() && !cancelled()
needs: [build-server-core, build-device-agent, build-dashboard, build-docs]
uses: ./.gitea/workflows/release_call.yaml
with:
name: dashboard-ui-dist
path: apps/dashboard-ui/dist/
prerelease: ${{ contains(gitea.ref_name, 'dev') }}
draft: ${{ contains(gitea.ref_name, 'beta') }}
secrets: inherit
-207
View File
@@ -1,207 +0,0 @@
name: Deploy
on:
workflow_call:
inputs:
prerelease:
description: 'Mark as prerelease'
required: false
type: boolean
default: false
permissions:
contents: write
jobs:
build-and-release:
runs-on: ubuntu-latest
steps:
- name: Clone main repository
run: |
git config --global --remove-section http || true
git config --global --unset-all core.askPass || true
TOKEN="${{ secrets.BUILD_TOKEN }}"
git clone -c credential.helper="" \
https://token:$TOKEN@git.datadunia.com/nexusguard/Nexus-Guard-Suite.git .
- name: Clone submodules
run: |
TOKEN="${{ secrets.BUILD_TOKEN }}"
# Server Core
git clone -c credential.helper="" \
https://token:$TOKEN@git.datadunia.com/nexusguard/nexus-server-core.git apps/server-core
# Device Agent
git clone -c credential.helper="" \
https://token:$TOKEN@git.datadunia.com/nexusguard/nexus-device-agent.git apps/device-agent
# Dashboard UI
git clone -c credential.helper="" \
https://token:$TOKEN@git.datadunia.com/nexusguard/nexus-dashboard-ui.git apps/dashboard-ui
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: '1.25'
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '24'
- name: Download Go modules
run: |
cd apps/server-core
go mod download
- name: Generate Swagger docs
run: |
go install github.com/swaggo/swag/cmd/swag@v1.16.6
cd apps/server-core
swag init -g main.go --parseDependency --parseInternal
- name: Build Server Core
run: |
cd apps/server-core
go build -o bin/server-core .
- name: Build Device Agent Cross-platform
run: |
cd apps/device-agent
# Linux amd64
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o bin/nexus-device-agent-linux-amd64 .
# Linux arm64
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -o bin/nexus-device-agent-linux-arm64 .
# Windows amd64
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -o bin/nexus-device-agent-windows-amd64.exe .
- name: Build Dashboard UI
run: |
cd apps/dashboard-ui
npm ci || npm install
npm run build
- name: Generate latest.json
run: |
VERSION="${{ gitea.ref_name }}"
RELEASE_DATE="$(date -u +'%Y-%m-%dT%H:%M:%SZ')"
REPO="${{ gitea.repository }}"
SERVER="${{ gitea.server_url }}"
cat > latest.json << ENDJSON
{
"version": "$VERSION",
"release_date": "$RELEASE_DATE",
"download_urls": {
"server-core": "${SERVER}/${REPO}/releases/download/${VERSION}/server-core-linux-amd64",
"device-agent-linux-amd64": "${SERVER}/${REPO}/releases/download/${VERSION}/nexus-device-agent-linux-amd64",
"device-agent-linux-arm64": "${SERVER}/${REPO}/releases/download/${VERSION}/nexus-device-agent-linux-arm64",
"device-agent-windows-amd64": "${SERVER}/${REPO}/releases/download/${VERSION}/nexus-device-agent-windows-amd64.exe",
"dashboard-ui": "${SERVER}/${REPO}/releases/download/${VERSION}/dashboard-ui-dist.tar.gz"
}
}
ENDJSON
- name: Create Release and upload assets
env:
TOKEN: ${{ secrets.BUILD_TOKEN }}
run: |
if [ -z "$TOKEN" ]; then
echo "Value: [EMPTY]"
exit 1
else
echo "Length: ${#TOKEN} characters"
fi
REPO="${{ gitea.repository }}"
TAG="${{ gitea.ref_name }}"
API="${{ gitea.server_url }}/api/v1"
# 0. Check & Delete Existing Release
echo "=== 0. Check & Delete Existing Release ==="
EXISTING_RESP=$(curl -s -H "Authorization: token $TOKEN" "$API/repos/$REPO/releases/tags/$TAG")
EXISTING_ID=$(echo "$EXISTING_RESP" | grep -o '"id":[0-9]*' | head -n 1 | cut -d':' -f2 || true)
if [ -n "$EXISTING_ID" ] && [ "$EXISTING_ID" != "null" ]; then
echo "⚠️ Found existing release for tag $TAG with ID: $EXISTING_ID. Deleting..."
DELETE_RESP=$(curl -s -w "\n%{http_code}" -X DELETE -H "Authorization: token $TOKEN" "$API/repos/$REPO/releases/$EXISTING_ID")
echo "✅ Delete response: $DELETE_RESP"
else
echo "No existing release found for $TAG. Proceeding..."
fi
# 1. Create Release
echo "=== 1. Create New Release ==="
JSON_BODY=$(printf '{"tag_name":"%s","name":"%s","body":"Release %s","draft":false,"prerelease":%s}' "$TAG" "$TAG" "$TAG" "${{ inputs.prerelease }}")
RELEASE_RESP=$(curl -s -X POST \
-H "Authorization: token $TOKEN" \
-H "Content-Type: application/json" \
-d "$JSON_BODY" \
"$API/repos/$REPO/releases")
# Ambil ID dengan lebih teliti
# Tambahkan || true agar grep tidak membuat script crash (karena set -e) jika id tidak ditemukan
RELEASE_ID=$(echo "$RELEASE_RESP" | grep -o '"id":[0-9]*' | head -n 1 | cut -d':' -f2 || true)
if [ -z "$RELEASE_ID" ] || [ "$RELEASE_ID" = "null" ]; then
echo "Gagal membuat release. Response: $RELEASE_RESP"
exit 1
fi
echo "Release ID: $RELEASE_ID"
# 2. Upload Assets
# Server Core
if [ -f "apps/server-core/bin/server-core" ]; then
echo "Uploading server-core-linux-amd64..."
curl -s -X POST \
-H "Authorization: token $TOKEN" \
-F "attachment=@apps/server-core/bin/server-core" \
"$API/repos/$REPO/releases/$RELEASE_ID/assets?name=server-core-linux-amd64"
fi
# Device Agent Linux amd64
if [ -f "apps/device-agent/bin/nexus-device-agent-linux-amd64" ]; then
echo "Uploading nexus-device-agent-linux-amd64..."
curl -s -X POST \
-H "Authorization: token $TOKEN" \
-F "attachment=@apps/device-agent/bin/nexus-device-agent-linux-amd64" \
"$API/repos/$REPO/releases/$RELEASE_ID/assets?name=nexus-device-agent-linux-amd64"
fi
# Device Agent Linux arm64
if [ -f "apps/device-agent/bin/nexus-device-agent-linux-arm64" ]; then
echo "Uploading nexus-device-agent-linux-arm64..."
curl -s -X POST \
-H "Authorization: token $TOKEN" \
-F "attachment=@apps/device-agent/bin/nexus-device-agent-linux-arm64" \
"$API/repos/$REPO/releases/$RELEASE_ID/assets?name=nexus-device-agent-linux-arm64"
fi
# Device Agent Windows amd64
if [ -f "apps/device-agent/bin/nexus-device-agent-windows-amd64.exe" ]; then
echo "Uploading nexus-device-agent-windows-amd64.exe..."
curl -s -X POST \
-H "Authorization: token $TOKEN" \
-F "attachment=@apps/device-agent/bin/nexus-device-agent-windows-amd64.exe" \
"$API/repos/$REPO/releases/$RELEASE_ID/assets?name=nexus-device-agent-windows-amd64.exe"
fi
# Dashboard UI dist
if [ -d "apps/dashboard-ui/dist" ]; then
echo "Creating dashboard-ui-dist.tar.gz..."
cd apps/dashboard-ui
tar -czf ../dashboard-ui-dist.tar.gz dist/
cd ..
echo "Uploading dashboard-ui-dist.tar.gz..."
curl -s -X POST \
-H "Authorization: token $TOKEN" \
-F "attachment=@dashboard-ui-dist.tar.gz" \
"$API/repos/$REPO/releases/$RELEASE_ID/assets?name=dashboard-ui-dist.tar.gz"
fi
# latest.json
if [ -f "latest.json" ]; then
echo "Uploading latest.json..."
curl -s -X POST \
-H "Authorization: token $TOKEN" \
-F "attachment=@latest.json" \
"$API/repos/$REPO/releases/$RELEASE_ID/assets?name=latest.json"
fi
- name: Cleanup build artifacts
if: always()
run: |
git config --global --remove-section http || true
git config --global --unset-all core.askPass || true
rm -f latest.json dashboard-ui-dist.tar.gz
rm -rf apps/server-core/bin apps/device-agent/bin apps/dashboard-ui/node_modules apps/dashboard-ui/dist
echo "Cleanup done"
+47
View File
@@ -0,0 +1,47 @@
name: Build Docs
on:
workflow_call:
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Configure git auth for submodules
run: git config --global url."https://x-access-token:${{ secrets.BUILD_TOKEN }}@git.datadunia.com/".insteadOf "https://git.datadunia.com/"
- uses: actions/checkout@v4
with:
submodules: true
fetch-depth: 0
token: ${{ secrets.BUILD_TOKEN }}
persist-credentials: true
- uses: actions/setup-node@v4
with:
node-version: '24'
- name: Hash package-lock
id: hash-npm
run: echo "hash=$(sha256sum apps/docs/package-lock.json 2>/dev/null || echo 'none') | cut -d' ' -f1)" >> "$GITHUB_OUTPUT"
- uses: actions/cache@v3
with:
path: |
~/.npm
key: npm-docs-${{ steps.hash-npm.outputs.hash }}
restore-keys: npm-docs-
- name: Install
working-directory: apps/docs
run: npm ci || npm install
- name: Build
working-directory: apps/docs
run: npm run docs:build
- name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: docs-dist
path: apps/docs/.vitepress/dist/
-14
View File
@@ -1,14 +0,0 @@
name: Release
on:
push:
tags:
- 'v[0-9]*.[0-9]*.[0-9]'
jobs:
deploy:
if: "!contains(gitea.ref_name, 'beta') && !contains(gitea.ref_name, 'test')"
uses: ./.gitea/workflows/deploy_call.yaml
with:
prerelease: false
secrets: inherit
+131
View File
@@ -0,0 +1,131 @@
name: Release
on:
workflow_call:
inputs:
prerelease:
description: 'Mark as prerelease'
required: false
type: boolean
default: false
draft:
description: 'Mark as draft'
required: false
type: boolean
default: false
permissions:
contents: write
jobs:
release:
runs-on: ubuntu-latest
steps:
- name: Configure git auth for submodules
run: git config --global url."https://x-access-token:${{ secrets.BUILD_TOKEN }}@git.datadunia.com/".insteadOf "https://git.datadunia.com/"
- uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.BUILD_TOKEN }}
persist-credentials: true
- name: Download all artifacts
uses: actions/download-artifact@v3
with:
path: ./artifacts
- name: Generate latest.json
run: |
VERSION="${{ gitea.ref_name }}"
RELEASE_DATE="$(date -u +'%Y-%m-%dT%H:%M:%SZ')"
REPO="${{ gitea.repository }}"
SERVER="${{ gitea.server_url }}"
cat > latest.json << ENDJSON
{
"version": "$VERSION",
"release_date": "$RELEASE_DATE",
"download_urls": {
"server-core": "${SERVER}/${REPO}/releases/download/${VERSION}/server-core-linux-amd64",
"device-agent-linux-amd64": "${SERVER}/${REPO}/releases/download/${VERSION}/nexus-device-agent-linux-amd64",
"device-agent-linux-arm64": "${SERVER}/${REPO}/releases/download/${VERSION}/nexus-device-agent-linux-arm64",
"device-agent-windows-amd64": "${SERVER}/${REPO}/releases/download/${VERSION}/nexus-device-agent-windows-amd64.exe",
"dashboard-ui": "${SERVER}/${REPO}/releases/download/${VERSION}/dashboard-ui-dist.tar.gz"
}
}
ENDJSON
- name: Create Release and upload assets
env:
TOKEN: ${{ secrets.BUILD_TOKEN }}
run: |
REPO="${{ gitea.repository }}"
TAG="${{ gitea.ref_name }}"
API="${{ gitea.server_url }}/api/v1"
# Delete existing release if present
EXISTING_ID=$(curl -s -H "Authorization: token $TOKEN" "$API/repos/$REPO/releases/tags/$TAG" | grep -o '"id":[0-9]*' | head -n 1 | cut -d':' -f2 || true)
if [ -n "$EXISTING_ID" ] && [ "$EXISTING_ID" != "null" ]; then
echo "Deleting existing release $EXISTING_ID..."
curl -s -X DELETE -H "Authorization: token $TOKEN" "$API/repos/$REPO/releases/$EXISTING_ID"
fi
# Create release
JSON_BODY=$(printf '{"tag_name":"%s","name":"%s","body":"Release %s","draft":%s,"prerelease":%s}' "$TAG" "$TAG" "$TAG" "${{ inputs.draft }}" "${{ inputs.prerelease }}")
RELEASE_RESP=$(curl -s -X POST \
-H "Authorization: token $TOKEN" \
-H "Content-Type: application/json" \
-d "$JSON_BODY" \
"$API/repos/$REPO/releases")
RELEASE_ID=$(echo "$RELEASE_RESP" | grep -o '"id":[0-9]*' | head -n 1 | cut -d':' -f2 || true)
if [ -z "$RELEASE_ID" ] || [ "$RELEASE_ID" = "null" ]; then
echo "Failed to create release. Response: $RELEASE_RESP"
exit 1
fi
echo "Release ID: $RELEASE_ID"
# Upload assets
upload_asset() {
local file="$1"
local name="$2"
if [ -f "$file" ]; then
echo "Uploading $name..."
curl -s -X POST \
-H "Authorization: token $TOKEN" \
-F "attachment=@$file" \
"$API/repos/$REPO/releases/$RELEASE_ID/assets?name=$name"
fi
}
# Server Core
upload_asset "artifacts/server-core-linux-amd64/server-core" "server-core-linux-amd64"
# Device Agent (all platforms)
for platform in linux-amd64 linux-arm64 windows-amd64; do
EXT=""
if [ "$platform" = "windows-amd64" ]; then EXT=".exe"; fi
upload_asset "artifacts/nexus-device-agent-${platform}/nexus-device-agent-${platform}${EXT}" "nexus-device-agent-${platform}${EXT}"
done
# Dashboard UI tar.gz
if [ -d "artifacts/dashboard-ui-dist/dist" ]; then
cd artifacts/dashboard-ui-dist
tar -czf ../../dashboard-ui-dist.tar.gz dist/
cd ../..
upload_asset "dashboard-ui-dist.tar.gz" "dashboard-ui-dist.tar.gz"
fi
# Docs tar.gz
if [ -d "artifacts/docs-dist" ]; then
cd artifacts/docs-dist
tar -czf ../../docs-dist.tar.gz ./
cd ../..
upload_asset "docs-dist.tar.gz" "docs-dist.tar.gz"
fi
# latest.json
upload_asset "latest.json" "latest.json"
- name: Cleanup
if: always()
run: rm -rf artifacts/ latest.json dashboard-ui-dist.tar.gz docs-dist.tar.gz
+13 -2
View File
@@ -30,6 +30,7 @@ nexusguard.conf
# Temp
tmp/
temp_*
*-test
*.tmp
# Build output
@@ -37,11 +38,21 @@ dist/
/dist/
# OpenCode
connect_remote.txt
.update-state
# Scripts (contains API tokens)
scripts/
# Oh-My-OpenAgent & Sisyphus plugin files
.omo/
.sisyphus/
.sisyphus/notepads/
.sisyphus/boulder.json
connect_remote.txt
.sisyphus/drafts/
.update-state
.omo/notepads/
.omo/boulder.json
.omo/drafts/
# Node
node_modules/
+3 -3
View File
@@ -1,9 +1,9 @@
[submodule "apps/server-core"]
path = apps/server-core
url = http://git.datadunia.com/nexusguard/nexus-server-core.git
url = https://git.datadunia.com/nexusguard/nexus-server-core.git
[submodule "apps/dashboard-ui"]
path = apps/dashboard-ui
url = http://git.datadunia.com/nexusguard/nexus-dashboard-ui.git
url = https://git.datadunia.com/nexusguard/nexus-dashboard-ui.git
[submodule "apps/device-agent"]
path = apps/device-agent
url = http://git.datadunia.com/nexusguard/nexus-device-agent.git
url = https://git.datadunia.com/nexusguard/nexus-device-agent.git
+133
View File
@@ -0,0 +1,133 @@
# Bug Fixes and Features Plan
## Bug Fixes
### 1. Nodes Edit Button - Hard to Click / Wrong HTML Tag Location
**Location**: apps/dashboard-ui/src/views/Servers.vue - Node cards edit button
**Issue**: Edit button on node cards is difficult to click or has incorrect HTML structure
**Root Cause**: Button z-index, positioning, or overlapping elements
**Files**: Servers.vue (lines 155-157)
**Status**: ✅ DONE - Changed button size from "sm" to "md" for better clickability
### 2. Dashboard - Missing Turn On WireGuard Button for 2nd+ Nodes
**Location**: apps/dashboard-ui/src/views/Servers.vue and apps/server-core/api/wg.go
**Issue**: Only first node (Local Primary Node) has WG Up/Down buttons; additional nodes lack toggle
**Root Cause**: wg.go Status/Up/Down handlers only work with hardcoded wg0 interface; multi-interface support needed
**Files**:
- apps/dashboard-ui/src/views/Servers.vue - Add WG toggle button per node
- apps/server-core/api/wg.go - Fix to accept interface name parameter
- apps/server-core/internal/wgmanager/wgmanager_linux.go - Ensure multi-interface support
**Status**: ✅ BACKEND DONE - wg.go accepts interface param, queries by interface_name, supports multi-interface
**Status**: ✅ FRONTEND DONE - WG Up/Down buttons added to node cards, calls API with interface param
### 3. Advanced Node Settings - Missing Notes/Descriptions for PreUp, PostUp, PreDown, PostDown
**Location**: apps/dashboard-ui/src/views/Servers.vue (lines 83-98)
**Issue**: Advanced scripts fields (PreUp, PostUp, PreDown, PostDown) lack helper text/descriptions like Firewall section has
**Files**: Servers.vue - Add hints/descriptions similar to FirewallEditor
**Status**: ✅ DONE - Added descriptive hints for Table, PreUp, PostUp, PreDown, PostDown
### 4. Popup/Modal Inconsistency - Backdrop Styling
**Location**: Multiple modals in Servers.vue, Devices.vue, DeviceDetail.vue, FirewallEditor.vue
**Issue**: Nodes modal backdrop styling is better than Devices modal; inconsistent across views
**Files**: Standardize modal wrapper component or CSS classes
**Status**: ✅ DONE - Servers.vue modals converted to NgModal, consistent backdrop (bg-bg-overlay)
### 5. Firewall Popup - Not User/Mobile Friendly
**Location**: apps/dashboard-ui/src/components/FirewallEditor.vue
**Issue**: Form layout not responsive; input fields too small on mobile; buttons not touch-friendly
**Files**: FirewallEditor.vue - Responsive grid, larger touch targets, better spacing
**Status**: ✅ DONE - Responsive grid (1/2/5 cols), button full width on mobile, table scroll-x-auto
### 6. Firewall wg_isolation - Verify Implementation Matches Plan
**Location**: apps/server-core/internal/firewall/nftables_linux.go - InitNetworkForServer()
**Issue**: Verify wg_isolation rules are correctly implemented per-server with smart isolation (allow server IP, drop peer-to-peer)
**Files**: nftables_linux.go - InitNetworkForServer() and TeardownNetworkForServer()
**Status**: ✅ DONE - Implementation verified: smart isolation (server IP allow, peer-to-peer drop), per-interface chains with jump rules, proper cleanup
---
## Features
### 1. Traffic Record Table - Only Show Records with RX or TX Data
**Location**: apps/dashboard-ui/src/views/TrafficHistory.vue, apps/server-core/api/traffic.go, apps/server-core/internal/traffic/recorder.go
**Issue**: Table shows all records including zero-byte entries; should filter to only show records with rx > 0 or tx > 0
**Files**:
- TrafficHistory.vue - Filter trafficData before display
- traffic.go - Add filter option to API
**Status**: ✅ DONE - Added has_traffic query param, toggle in UI, backend filtering (rx>0 OR tx>0)
### 2. Traffic Record Table - Sum Per Hour Aggregation
**Location**: apps/server-core/api/traffic.go, apps/server-core/internal/traffic/recorder.go
**Issue**: Add hourly aggregation option for traffic table when query supports it
**Files**:
- traffic.go - Add aggregation parameter to GetSummary/GetDeviceTraffic
- recorder.go - Add GetHourlyTraffic method with SQL GROUP BY hour
**Status**: ✅ DONE - Added GetHourlyTraffic endpoint with SQL GROUP BY hour, returns HourlyTraffic[]
---
## Implementation Priority
| Priority | Task | Category |
|----------|------|----------|
| P1 | Nodes edit button fix | Bug |
| P1 | Dashboard WG toggle for all nodes | Bug |
| P1 | Verify wg_isolation implementation | Bug |
| P2 | Advanced settings descriptions | Bug |
| P2 | Modal consistency (backdrop) | Bug |
| P2 | Firewall mobile-friendly | Bug |
| P2 | Traffic table filter (RX/TX > 0) | Feature |
| P3 | Traffic hourly aggregation | Feature |
| P3 | Firewall mobile-friendly | Bug |
---
## Code Structure Reference
### Frontend (Vue 3 + TypeScript)
apps/dashboard-ui/src/
|-- views/
| |-- Servers.vue # Node management (edit, WG toggle, advanced)
| |-- Devices.vue # Device list, firewall
| |-- DeviceDetail.vue # Device detail, firewall editor
| |-- TrafficHistory.vue # Traffic table, filters
| |-- ...
|-- components/
| |-- FirewallEditor.vue # Firewall rules UI
| |-- ui/ # Ng* design system components
| |-- ...
|-- ...
### Backend (Go)
apps/server-core/
|-- api/
| |-- servers.go # Node CRUD, WG Up/Down
| |-- wg.go # WG interface control
| |-- traffic.go # Traffic API
| |-- ...
|-- internal/
| |-- firewall/
| | |-- nftables_linux.go # InitNetworkForServer, Teardown
| | |-- ...
| |-- wgmanager/
| | |-- wgmanager_linux.go # Multi-interface WgManager
| |-- traffic/
| |-- recorder.go # Traffic queries
---
## Next Steps
1. Create detailed task breakdown for each bug/feature
2. Start with P1 bugs (edit button, WG toggle, wg_isolation)
3. Implement fixes following existing code patterns
5. Archive completed plan when done
---
## Notes
- All plans from .sisyphus have been migrated to .omo/plans/archive/
- New plan saved at .omo/plans/bugfixes-and-features.md
- Evidence, notepads, references migrated to .omo/
- Boulder state copied to .omo/boulder.json
@@ -0,0 +1,387 @@
# Firewall InitNetwork Fix — INPUT vs FORWARD Chain Bugs
## TL;DR
> **Quick Summary**: Fix 3 bugs in `InitNetwork()` that prevent WireGuard clients from reaching the server and Docker containers. ICMP echo-reply blocked, Docker DNAT traffic dropped, and missing base INPUT rules.
>
> **Deliverables**:
> - Fixed `nftables_linux.go` InitNetwork() with correct ICMP, Docker bridge, and INPUT rules
> - Updated `manager.go` if needed
> - Server rebuilt and deployed via `update.sh --force`
>
> **Estimated Effort**: Short
> **Parallel Execution**: YES - 2 waves
> **Critical Path**: Task 1 → Task 4 (verify)
---
## Context
### Original Request
User reported firewall rules from dashboard not working. Traced through multiple debugging sessions to find 3 root-cause bugs in `InitNetwork()` base rules:
1. `icmp type echo-request` only allows incoming pings TO server, not echo-reply FROM peers
2. No FORWARD rules for Docker bridge — WireGuard traffic DNAT'd to containers gets dropped
3. Server→peer traffic works (OUTPUT default accept) but replies hit INPUT chain and get dropped
### Interview Summary
- **Key Discussions**: Extensive debugging on live server (172.20.8.191). User tested each fix manually via SSH. Confirmed Docker DNAT intercepts port 80 traffic via iptables PREROUTING, redirecting to container 172.24.0.4.
- **Research Findings**: Docker uses iptables DNAT while NexusGuard uses nftables filter — both coexist. Traffic flow: WireGuard → INPUT (nftables) → ACCEPT → Docker PREROUTING (iptables DNAT) → destination changes to container IP → FORWARD chain (nftables) → DROP (no bridge rule).
- **User Constraints**: No local binary builds (Docker only). No temp/debug files. Admin-only firewall (JWT protected).
### Metis Review (if consulted)
N/A — bugs are clear from source code analysis, no ambiguity requiring consultation.
---
## Work Objectives
### Core Objective
Fix 3 bugs in `InitNetwork()` that prevent WireGuard peer-to-server and peer-to-Docker-container connectivity.
### Concrete Deliverables
- Fixed `apps/server-core/internal/firewall/nftables_linux.go` InitNetwork()
- Fixed `apps/server-core/internal/firewall/manager.go` if interface changes needed
- Server rebuilt and deployed
- nftables verified working on live server
### Definition of Done
- [ ] `nft list chain ip nexusguard input` shows `meta l4proto icmp accept` (not `icmp type echo-request`)
- [ ] `nft list chain ip nexusguard forward` shows `fwd_wg_docker` rules for 172.24.0.0/16 and 172.17.0.0/16
- [ ] Client (gogo3 10.172.21.3) can ping server (10.172.21.1)
- [ ] Server (10.172.21.1) can ping client (10.172.21.3)
- [ ] Client can curl http://10.172.21.1:80 and get 200
### Must Have
- `meta l4proto icmp` replaces `icmp type echo-request` in INPUT chain
- `fwd_wg_docker` rules added to FORWARD chain in InitNetwork()
- Existing peer routing rules (AddForwardRule) still work
- Existing DB firewall rules (syncRuleToFirewall) still work
### Must NOT Have (Guardrails)
- Do NOT `nft flush table nexusguard` — destroys all rules
- Do NOT change the FirewallRule model or API endpoints
- Do NOT modify peer_sync.go or devices.go
- Do NOT create temp/debug files in project root
- Do NOT change the firewall chain routing logic (dest==server→INPUT, else→FORWARD)
- Do NOT remove the `input_wg_drop` or `wg_isolation_default` base rules
---
## Verification Strategy
> **ZERO HUMAN INTERVENTION** — ALL verification is agent-executed. No exceptions.
### Test Decision
- **Infrastructure exists**: NO (no nftables unit tests)
- **Automated tests**: None (nftables rules tested via live server SSH)
- **Framework**: None needed — live server verification
### QA Policy
Every task includes agent-executed QA scenarios.
Evidence saved to `.sisyphus/evidence/task-{N}-{scenario-slug}.{ext}`.
- **nft verification**: SSH to server, run nft commands, verify rules present
- **Connectivity**: SSH to server, run ping/curl tests
---
## Execution Strategy
### Parallel Execution Waves
```
Wave 1 (Start Immediately — 1 agent):
├── Task 1: Fix InitNetwork() in nftables_linux.go (quick)
Wave 2 (After Wave 1 — 1 agent):
├── Task 2: Commit + Push + Deploy (quick)
├── Task 3: Verify nft rules on live server (quick)
Wave FINAL (After Wave 2 — reviewer):
├── Task F1: Plan compliance audit (oracle)
├── Task F2: Code quality review (unspecified-high)
├── Task F3: Real manual QA (unspecified-high)
├── Task F4: Scope fidelity check (deep)
-> F1-F4 can run in parallel
Critical Path: Task 1 → Task 2 → Task 3 → F1-F4
```
### Dependency Matrix
| Task | Depends On | Blocks |
|------|-----------|--------|
| Task 1 | None | Task 2 |
| Task 2 | Task 1 | Task 3 |
| Task 3 | Task 2 | F1-F4 |
| F1-F4 | Task 3 | None |
### Agent Dispatch Summary
- **Wave 1**: T1 → `quick`
- **Wave 2**: T2 → `quick`, T3 → `quick`
- **FINAL**: F1 → `oracle`, F2 → `unspecified-high`, F3 → `unspecified-high`, F4 → `deep`
---
## TODOs
- [x] 1. Fix InitNetwork() in nftables_linux.go
**What to do**:
1. In `apps/server-core/internal/firewall/nftables_linux.go`, line 48: change `icmp type echo-request` to `meta l4proto icmp`. Also update the comment from `input_icmp` to `input_icmp_all`.
2. In the same function, after the `input_wg_drop` rule block (around line 64), add Docker bridge accept rules to FORWARD chain:
- `nft insert rule ip nexusguard forward ip saddr <wgSubnet> ip daddr 172.24.0.0/16 accept comment "fwd_wg_docker"`
- `nft insert rule ip nexusguard forward ip saddr <wgSubnet> ip daddr 172.17.0.0/16 accept comment "fwd_wg_docker0"`
3. These Docker rules should be inserted AFTER `fwd_estab` and BEFORE the `wg_isolation` drop rule. Use `nft insert rule` with position or append after fwd_estab.
4. Add dedup checks (same pattern as existing rules): `grep -q 'fwd_wg_docker'` before inserting.
**Must NOT do**:
- Do NOT change AddForwardRule, AddFirewallRule, AddInputFirewallRule, or RemoveFirewallRule
- Do NOT change the chain routing logic in syncRuleToFirewall
- Do NOT flush or recreate any chains
- Do NOT change manager.go interface
**Recommended Agent Profile**:
- **Category**: `quick`
- Reason: Single-file change, 3 specific line edits, clear patterns to follow
- **Skills**: []
- No special skills needed — straightforward Go code edit
**Parallelization**:
- **Can Run In Parallel**: NO
- **Parallel Group**: Wave 1 (solo)
- **Blocks**: Task 2 (commit/deploy)
- **Blocked By**: None (can start immediately)
**References**:
- `apps/server-core/internal/firewall/nftables_linux.go:25-68` — InitNetwork() function, all 3 bugs are here
- `apps/server-core/internal/firewall/nftables_linux.go:30-38` — existing FORWARD chain setup (fwd_estab, wg_isolation) — Docker rules go between these
- `apps/server-core/internal/firewall/nftables_linux.go:40-64` — existing INPUT chain setup — ICMP fix at line 48
- `apps/server-core/main.go:210-259` — startup re-apply code that calls AddForwardRule and AddInputFirewallRule — do NOT modify
- `apps/server-core/internal/firewall/manager.go:5-18` — NetManager interface — do NOT modify
**Acceptance Criteria**:
- [ ] Line 48 reads `meta l4proto icmp` not `icmp type echo-request`
- [ ] Comment reads `input_icmp_all` not `input_icmp`
- [ ] FORWARD chain has dedup check for `fwd_wg_docker` before inserting
- [ ] `go vet ./internal/firewall/...` passes
- [ ] No other lines in InitNetwork() changed
**QA Scenarios**:
```
Scenario: Verify ICMP rule is correct
Tool: Bash (grep)
Steps:
1. grep "meta l4proto icmp" apps/server-core/internal/firewall/nftables_linux.go
2. grep "icmp type echo-request" apps/server-core/internal/firewall/nftables_linux.go
Expected Result: First grep returns match, second grep returns nothing
Evidence: .sisyphus/evidence/task-1-icmp-rule.txt
Scenario: Verify Docker bridge rules exist
Tool: Bash (grep)
Steps:
1. grep "fwd_wg_docker" apps/server-core/internal/firewall/nftables_linux.go
2. grep "172.24.0.0/16" apps/server-core/internal/firewall/nftables_linux.go
3. grep "172.17.0.0/16" apps/server-core/internal/firewall/nftables_linux.go
Expected Result: All 3 greps return matches
Evidence: .sisyphus/evidence/task-1-docker-rules.txt
Scenario: Verify dedup check pattern
Tool: Bash (grep)
Steps:
1. grep "fwd_wg_docker" apps/server-core/internal/firewall/nftables_linux.go | head -5
Expected Result: Shows both the grep check command AND the nft insert command
Evidence: .sisyphus/evidence/task-1-dedup-pattern.txt
```
**Commit**: YES
- Message: `fix(nftables): InitNetwork ICMP all, Docker bridge accept, base INPUT rules`
- Files: `apps/server-core/internal/firewall/nftables_linux.go`
- Pre-commit: `go vet ./internal/firewall/...`
- [x] 2. Commit, Push, Deploy to Server
**What to do**:
1. In `apps/server-core/`: `git add -A && git commit` with the fix message, then `git push`
2. In root `Nexus-Guard-Suite/`: `git add apps/server-core && git commit && git push`
3. SSH to server: `cd /root/Nexus-Guard-Suite && bash update.sh --force`
4. Wait for deployment to complete
**Must NOT do**:
- Do NOT build binary locally
- Do NOT create temp files on server
- Do NOT use `nft flush` on server
- Do NOT modify any code files
**Recommended Agent Profile**:
- **Category**: `quick`
- Reason: Simple git + SSH commands, well-documented in AGENTS.md
- **Skills**: []
**Parallelization**:
- **Can Run In Parallel**: NO
- **Parallel Group**: Wave 2 (solo)
- **Blocks**: Task 3 (verify)
- **Blocked By**: Task 1 (code change)
**References**:
- `D:\www-project\NexusGuard\connect_remote.txt` — SSH credentials (HOST=172.20.8.191, USER=root)
- `D:\www-project\NexusGuard\update.sh` — Docker rebuild script
**Acceptance Criteria**:
- [ ] Submodule HEAD updated (new commit hash)
- [ ] Root repo HEAD updated
- [ ] Server container restarted successfully
- [ ] `docker ps` shows server-core running
**QA Scenarios**:
```
Scenario: Verify deployment
Tool: SSH (bash)
Steps:
1. ssh root@172.20.8.191 'docker ps | grep server-core'
2. ssh root@172.20.8.191 'docker logs nexus-guard-suite-server-core-1 2>&1 | tail -5'
Expected Result: Container running, logs show clean startup
Evidence: .sisyphus/evidence/task-2-deployment.txt
```
**Commit**: NO (commit done as part of task)
- [x] 3. Verify nftables Rules and Connectivity on Live Server
**What to do**:
1. SSH to server, run `nft list table ip nexusguard` and verify:
- INPUT chain has `meta l4proto icmp accept comment "input_icmp_all"`
- FORWARD chain has `fwd_wg_docker` rules for 172.24.0.0/16 and 172.17.0.0/16
- All existing rules intact (server_wg1, input_estab, input_wg_api, etc.)
2. Test from server: `ping -c 3 10.172.21.3` — should get replies
3. Ask user to test from client: `ping 10.172.21.1` and `curl -v http://10.172.21.1:80`
4. Verify nft counters increment when traffic flows
**Must NOT do**:
- Do NOT modify any nft rules during verification
- Do NOT flush or recreate chains
**Recommended Agent Profile**:
- **Category**: `quick`
- Reason: SSH verification commands only
- **Skills**: []
**Parallelization**:
- **Can Run In Parallel**: NO
- **Parallel Group**: Wave 2 (after Task 2)
- **Blocks**: F1-F4
- **Blocked By**: Task 2 (deployment)
**References**:
- `D:\www-project\NexusGuard\connect_remote.txt` — SSH credentials
- `D:\www-project\NexusGuard\AGENTS.md` — WireGuard AllowedIPs architecture rules
**Acceptance Criteria**:
- [ ] INPUT chain has `meta l4proto icmp` (not `icmp type echo-request`)
- [ ] FORWARD chain has `fwd_wg_docker` for 172.24.0.0/16
- [ ] FORWARD chain has `fwd_wg_docker0` for 172.17.0.0/16
- [ ] Server can ping gogo3 (10.172.21.3)
- [ ] Client can ping server (10.172.21.1)
- [ ] Client can curl http://10.172.21.1:80
**QA Scenarios**:
```
Scenario: Verify INPUT chain ICMP rule
Tool: SSH (bash)
Steps:
1. ssh root@172.20.8.191 'nft list chain ip nexusguard input | grep icmp'
Expected Result: Shows `meta l4proto icmp accept comment "input_icmp_all"`
Evidence: .sisyphus/evidence/task-3-input-icmp.txt
Scenario: Verify FORWARD chain Docker rules
Tool: SSH (bash)
Steps:
1. ssh root@172.20.8.191 'nft list chain ip nexusguard forward | grep docker'
Expected Result: Shows both fwd_wg_docker (172.24.0.0/16) and fwd_wg_docker0 (172.17.0.0/16)
Evidence: .sisyphus/evidence/task-3-forward-docker.txt
Scenario: Server ping client
Tool: SSH (bash)
Steps:
1. ssh root@172.20.8.191 'ping -c 3 10.172.21.3'
Expected Result: 3 replies, 0% packet loss
Evidence: .sisyphus/evidence/task-3-ping-client.txt
Scenario: Client connectivity (requires user)
Tool: User prompt
Steps:
1. Ask user to run from gogo3 client: `ping 10.172.21.1`
2. Ask user to run from gogo3 client: `curl -v http://10.172.21.1:80`
Expected Result: Ping replies, curl returns 200
Evidence: User provides output
```
**Commit**: NO
---
## Final Verification Wave (MANDATORY — after ALL implementation tasks)
> 4 review agents run in PARALLEL. ALL must APPROVE. Rejection → fix → re-run.
- [x] F1. **Plan Compliance Audit** — `oracle`
Read the plan end-to-end. For each "Must Have": verify implementation exists (read file, curl endpoint, check schema). For each "Must NOT Have": search codebase for forbidden patterns — reject with file:line if found. Check evidence files exist in .sisyphus/evidence/. Compare deliverables against plan.
Output: `Must Have [N/N] | Must NOT Have [N/N] | Tasks [N/N] | VERDICT: APPROVE/REJECT`
- [x] F2. **Code Quality Review** — `unspecified-high`
Run `go vet ./...` on changed packages. Review all changed files for: empty catches, console.logs in prod code, commented-out code, unused imports. Check AI slop: excessive comments, over-abstraction, generic variable names.
Output: `Build [PASS/FAIL] | Files [N clean/N issues] | VERDICT`
- [x] F3. **Real Manual QA** — `unspecified-high` (equipment: SSH to 172.20.8.191)
SSH to server. Run: `nft list table ip nexusguard` and verify rules. Then test: `ping 10.172.21.3` from server. From client: `ping 10.172.21.1` and `curl -v http://10.172.21.1:80`. Test negative case: verify that WG isolation default drop still blocks unauthorized traffic.
Output: `Connectivity [N/N pass] | Firewall [N correct rules] | Negative [PASS/FAIL] | VERDICT`
- [x] F4. **Scope Fidelity Check** — `deep`
For each task: read "What to do", read actual diff (git log/diff). Verify 1:1 — everything in spec was built (no missing), nothing beyond spec was built (no creep). Check "Must NOT do" compliance. Flag unauthorized changes.
Output: `Tasks [N/N compliant] | Contamination [CLEAN/N issues] | VERDICT`
---
## Commit Strategy
- **Task 1**: `fix(nftables): InitNetwork ICMP, Docker bridge, INPUT base rules` → `apps/server-core/`
- **Task 2**: Submodule push + root push + deploy via `update.sh --force`
---
## Success Criteria
### Verification Commands
```bash
# From server (SSH root@172.20.8.191):
nft list chain ip nexusguard input
# Expected: meta l4proto icmp accept comment "input_icmp_all"
nft list chain ip nexusguard forward
# Expected: fwd_wg_docker accept for 172.24.0.0/16 and 172.17.0.0/16
# From client (gogo3):
ping 10.172.21.1
# Expected: replies
# From server:
ping 10.172.21.3
# Expected: replies
# From client:
curl -s -o /dev/null -w "%{http_code}" http://10.172.21.1:80
# Expected: 200
```
### Final Checklist
- [x] All "Must Have" present
- [x] All "Must NOT Have" absent
- [x] Server deployed and running
- [ ] Both peers can ping server
- [x] Server can ping both peers
- [ ] Port 80 accessible from WireGuard client
@@ -0,0 +1,118 @@
# Multi-Interface Refactor
## TL;DR
> **Objective**: Refactor NexusGuard from single WireGuard interface to multi-interface per WgServer.
## Context
**Original Request**: User wants firewall bug fixed + multi-node isolation like wgdashboard where each node has configurable wg_isolation and NAT interface.
**Interview Summary**:
- Default deny all for client<->client, allow server->client default
- Isolation configurable per node via UI checkbox
- NAT interface (eth0/eth1/ens5) configurable per node
- Current architecture only supports 1 local interface (wg0)
**Research Findings**:
- WgManager hardcoded to wg0 (wgmanager_linux.go:25)
- Firewall InitNetwork() runs once globally for single subnet
- NAT uses auto-detected default route interface
- WgServer model lacks InterfaceName, IsLocal, PeerIsolation, NatInterface fields
---
## Work Objectives
**Core Objective**: Enable multiple local WireGuard interfaces, each with independent subnet, firewall isolation, and NAT egress interface.
**Concrete Deliverables**:
1. Database migration adding 4 fields to wg_servers table
2. WgManager supporting multiple interfaces by name
3. Firewall manager with per-interface chains (forward_wgX, input_wgX)
4. Startup initialization loop for all IsLocal=true servers
5. API handlers using server context for all operations
6. Cleanup of hardcoded Local Primary Node references
**Definition of Done**:
- [ ] Migration runs: ALTER TABLE wg_servers ADD COLUMN ...
- [ ] wg0, wg1, wg2 interfaces can run simultaneously
- [ ] Each interface has independent peer isolation (configurable)
- [ ] Each interface uses configured NAT interface for masquerade
- [ ] Firewall rules scoped to correct interface chain
- [ ] Peer sync works per server (WgServerID filter)
- [ ] All existing tests pass
- [ ] Manual QA: 2+ local nodes with different subnets/NAT interfaces
**Must Have**:
- Backward compatible: existing single-node deployments work unchanged
- Default values: InterfaceName=wg0, IsLocal=false, PeerIsolation=true, NatInterface= (auto)
**Must NOT Have** (Guardrails):
- NO breaking changes to external node provisioning
- NO nft flush table - only atomic add/remove
- NO hardcoded interface names in firewall code
- NO cross-interface peer leakage
---
## Verification Strategy
**Test Decision**:
- Infrastructure exists: YES (Go test with -tags dev, GORM AutoMigrate)
- Automated tests: Tests-after (add tests for new multi-interface logic)
- Framework: Go testing (standard library)
**QA Policy**: Every task includes agent-executed QA scenarios.
| Domain | Tool | Evidence Pattern |
|--------|------|------------------|
| Go unit/integration | go test -tags dev ./... | .sisyphus/evidence/task-{N}-test.log |
| nftables rules | bash (nft list) | .sisyphus/evidence/task-{N}-nftables.txt |
| WireGuard interfaces | bash (ip link, wg show) | .sisyphus/evidence/task-{N}-wg.txt |
| API endpoints | bash (curl) | .sisyphus/evidence/task-{N}-api.json |
Wave 2 (Core Logic - 4 parallel):
├── T5: LinuxWgManager multi-interface implementation [deep]
├── T6: LinuxManager InitNetworkForServer + Teardown [deep]
├── T7: NAT per-interface masquerade rules [unspecified-high]
├── T8: Peer sync per-server (WgServerID filter) [unspecified-high]
Wave 3 (Startup & Recovery - 3 parallel):
├── T9: Main.go startup loop for all local servers [deep]
├── T10: Firewall rules re-apply per server [unspecified-high]
├── T11: Input rule (WG port) per server [quick]
Wave 4 (API Handlers - 5 parallel):
├── T12: servers.go Create/Update with multi-interface [quick]
├── T13: peers.go device creation with server context [quick]
├── T14: peer_sync.go SyncLocalPeers per server [quick]
├── T15: rules.go syncRuleToFirewall per server [quick]
├── T16: provisioning.go server-aware [quick]
Wave 5 (Cleanup & Migration - 2 parallel):
├── T17: Remove hardcoded Local Primary Node refs [quick]
├── T18: Migration script + backfill defaults [quick]
---
## TODOs
- [x] 1. Database Migration + Model Updates [quick]
- [x] 2. WgManager Interface + Multi-Interface Struct [deep]
- [x] 3. NetManager Interface + Per-Server Methods [deep]
- [x] 4. nftables Chain-Per-Interface Scaffolding [quick]
- [x] 5. LinuxWgManager Multi-Interface Implementation [deep]
- [x] 6. LinuxManager InitNetworkForServer + Teardown [deep]
- [x] 7. NAT Per-Interface Masquerade Rules [unspecified-high]
- [x] 8. Peer Sync Per-Server (WgServerID Filter) [unspecified-high]
- [x] 9. Main.go Startup Loop for All Local Servers [deep]
- [x] 10. Firewall Rules Re-apply Per Server [unspecified-high]
- [x] 11. Input Rule (WG Port) Per Server [quick]
- [x] 12. servers.go Create/Update Multi-Interface [quick]
- [x] 13. peers.go Device Creation with Server Context [quick]
- [x] 14. peer_sync.go SyncLocalPeers Per Server [quick]
- [x] 15. rules.go syncRuleToFirewall Per Server [quick]
- [x] 16. provisioning.go Server-Aware [quick]
- [x] 17. Remove Hardcoded Local Primary Node References [quick]
- [x] 18. Migration Script + Backfill Defaults [quick]
- [x] 19. Unit Tests for Multi-Interface Logic [unspecified-low]
- [x] 20. Integration Test: 2 Local Nodes Different Subnets [unspecified-high]
- [x] 21. Manual QA Checklist Execution [unspecified-high]
- [x] F1. Plan Compliance Audit — oracle
- [x] F2. Code Quality Review — unspecified-high
- [x] F3. Real Manual QA — unspecified-high + playwright
- [x] F4. Scope Fidelity Check — deep
@@ -94,7 +94,7 @@ Wave 2 (Integration + Polish):
## TODOs
- [ ] 1. Add limit parameter to traffic API
- [x] 1. Add limit parameter to traffic API
**What to do**:
- In `apps/server-core/api/traffic.go`, modify `parseTimeRange` to also parse `limit` query parameter
@@ -135,7 +135,7 @@ Wave 2 (Integration + Polish):
---
- [ ] 2. Silent auto-refresh + pagination fix
- [x] 2. Silent auto-refresh + pagination fix
**What to do**:
- Modify `fetchTrafficData` to accept optional `silent` parameter (default false)
@@ -179,7 +179,7 @@ Wave 2 (Integration + Polish):
---
- [ ] 3. Chart downsampling
- [x] 3. Chart downsampling
**What to do**:
- In `TrafficHistory.vue`, add a `chartDataLimited` computed that limits chart data to max 200 points
@@ -215,7 +215,7 @@ Wave 2 (Integration + Polish):
---
- [ ] 4. CSV export optimization
- [x] 4. CSV export optimization
**What to do**:
- Change exportToCSV to export only `paginatedData` (current page) by default
@@ -244,7 +244,7 @@ Wave 2 (Integration + Polish):
---
- [ ] 5. Build verify all changes
- [x] 5. Build verify all changes
**What to do**:
- Run `cd apps/server-core && go build ./...`
+6 -2
View File
@@ -13,7 +13,7 @@ NexusGuard SD-WAN Suite — Enterprise Zero-Trust SD-WAN with WireGuard tunnelin
├── apps/
│ ├── server-core/ # Go/Gin API backend (submodule)
│ ├── dashboard-ui/ # Vue 3 + Vite frontend (submodule)
│ └── device-agent/ # Go stealth daemon (submodule)
│ └── device-agent/ # Go stealth daemon + system tray (submodule)
├── docker-compose.yml # Production orchestration
├── docker-compose.dev.yml # Dev (air hot-reload)
├── Makefile # up/down/dev/migrate/reset-db
@@ -50,7 +50,10 @@ NexusGuard SD-WAN Suite — Enterprise Zero-Trust SD-WAN with WireGuard tunnelin
| Symbol | Type | Location | Role |
|--------|------|----------|------|
| `main()` (server-core) | func | `apps/server-core/main.go` | Entry: CLI flags + Gin init |
| `main()` (device-agent) | func | `apps/device-agent/main.go` | Entry: agent daemon lifecycle |
| `main()` (device-agent) | func | `apps/device-agent/main.go` | Entry: systray + agent daemon lifecycle |
| `onReady()` / `onExit()` | func | `apps/device-agent/main.go` | System tray setup and cleanup |
| `startAgent()` / `stopAgent()` | func | `apps/device-agent/main.go` | Agent connect/disconnect lifecycle |
| `generateIcon()` | func | `apps/device-agent/icon.go` | 16x16 shield icon for tray |
| `config.Load()` | func | `apps/server-core/internal/config/` | Env-based config loader |
| `config.LoadConfFile()` | func | `apps/server-core/internal/config/config_loader.go` | Config file parser (.env / nexusguard.conf) |
| `auth.Init()` | func | `apps/server-core/internal/auth/` | JWT sign/verify init |
@@ -76,6 +79,7 @@ NexusGuard SD-WAN Suite — Enterprise Zero-Trust SD-WAN with WireGuard tunnelin
## ANTI-PATTERNS (THIS PROJECT)
- **NEVER** `nft flush table` — only atomic add/remove
- **NEVER** commit temp/debug/test files (`nft-fix.sh`, `temp_*.txt` etc) in project root use ./tests folder and dont commit
- **NEVER** log plaintext or encryption keys
- **NEVER** reopen completed phases/commits — fix forward only
- **NEVER** rebuild `shared/crypto/encryptor.go` — copy identical file
+35
View File
@@ -221,6 +221,41 @@ For automated client deployment with the Device Agent:
---
## 📚 Documentation
Documentation is built with VitePress and served at `/docs/`.
### Local Development
```bash
cd apps/docs
npm install
npm run docs:dev
```
### Building Docs
```bash
cd apps/docs
npm run docs:build
```
The output is in `apps/docs/.vitepress/dist/`.
### Structure
- `apps/docs/` — VitePress root (i18n: Indonesian + English)
- `apps/server-core/docs/` — Backend API docs & guides
- `apps/dashboard-ui/docs/` — Dashboard UI docs
- `apps/device-agent/docs/` — Device Agent docs
### Languages
- **Bahasa Indonesia** (default): `/docs/`
- **English**: `/docs/en/`
---
## 📁 File Structure
```
+43 -15
View File
@@ -1,22 +1,50 @@
import { defineConfig } from 'vitepress'
// Sidebar manifests from submodules
import serverCoreSidebar from '../../server-core/docs/sidebar.json'
import dashboardSidebar from '../../dashboard-ui/docs/sidebar.json'
import agentSidebar from '../../device-agent/docs/sidebar.json'
export default defineConfig({
title: 'NexusGuard Docs',
description: 'Enterprise Zero-Trust SD-WAN Documentation',
title: 'NexusGuard',
description: 'Enterprise Zero-Trust SD-WAN Suite',
base: '/docs/',
cleanUrls: true,
locales: {
root: {
label: 'Bahasa Indonesia',
lang: 'id',
themeConfig: {
sidebar: [
{
text: 'Guides',
items: [
{ text: 'Sign In', link: '/guides/sign-in' },
{ text: 'Access Remote Server', link: '/guides/access-remote-server' },
{ text: 'Add WireGuard Configuration', link: '/guides/add-wireguard-configuration' },
{ text: 'Peers', link: '/guides/peers' },
{ text: 'Email Service', link: '/guides/email-service' },
{ text: 'WebHooks', link: '/guides/webhooks' },
]
}
]
}
serverCoreSidebar,
dashboardSidebar,
agentSidebar,
],
nav: [
{ text: 'Beranda', link: '/' },
{ text: 'Panduan', link: '/guides/' },
{ text: 'API', link: '/api/' },
{ text: 'GitHub', link: 'https://git.datadunia.com/nexusguard/Nexus-Guard-Suite' },
],
},
},
en: {
label: 'English',
lang: 'en',
themeConfig: {
sidebar: [
serverCoreSidebar,
dashboardSidebar,
agentSidebar,
],
nav: [
{ text: 'Home', link: '/en/' },
{ text: 'Guides', link: '/en/guides/' },
{ text: 'API', link: '/en/api/' },
{ text: 'GitHub', link: 'https://git.datadunia.com/nexusguard/Nexus-Guard-Suite' },
],
},
},
},
})
+32
View File
@@ -0,0 +1,32 @@
# NexusGuard API Reference
This page provides interactive documentation for the NexusGuard Server Core API.
<div id="swagger-ui"></div>
<script setup>
import { onMounted } from 'vue'
onMounted(() => {
// Load Swagger UI from CDN
const script = document.createElement('script')
script.src = 'https://unpkg.com/swagger-ui-dist@5/swagger-ui-bundle.js'
script.onload = () => {
window.SwaggerUIBundle({
url: '/server-core/docs/swagger.json',
dom_id: '#swagger-ui',
presets: [
window.SwaggerUIBundle.presets.apis,
window.SwaggerUIBundle.SwaggerUIStandalonePreset
],
layout: 'BaseLayout'
})
}
document.head.appendChild(script)
const link = document.createElement('link')
link.rel = 'stylesheet'
link.href = 'https://unpkg.com/swagger-ui-dist@5/swagger-ui.css'
document.head.appendChild(link)
})
</script>
+31
View File
@@ -0,0 +1,31 @@
# Referensi API NexusGuard
Halaman ini menyediakan dokumentasi interaktif untuk API Server Core NexusGuard.
<div id="swagger-ui"></div>
<script setup>
import { onMounted } from 'vue'
onMounted(() => {
const script = document.createElement('script')
script.src = 'https://unpkg.com/swagger-ui-dist@5/swagger-ui-bundle.js'
script.onload = () => {
window.SwaggerUIBundle({
url: '/server-core/docs/swagger.json',
dom_id: '#swagger-ui',
presets: [
window.SwaggerUIBundle.presets.apis,
window.SwaggerUIBundle.SwaggerUIStandalonePreset
],
layout: 'BaseLayout'
})
}
document.head.appendChild(script)
const link = document.createElement('link')
link.rel = 'stylesheet'
link.href = 'https://unpkg.com/swagger-ui-dist@5/swagger-ui.css'
document.head.appendChild(link)
})
</script>
+26
View File
@@ -0,0 +1,26 @@
import { readFileSync } from 'node:fs';
import { join, dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
const __dirname = dirname(fileURLToPath(import.meta.url));
const submodules = [
{ name: 'server-core', path: '../server-core/docs/sidebar.json' },
{ name: 'dashboard-ui', path: '../dashboard-ui/docs/sidebar.json' },
{ name: 'device-agent', path: '../device-agent/docs/sidebar.json' }
];
const sidebar = [];
for (const mod of submodules) {
const filePath = join(__dirname, mod.path);
try {
const content = JSON.parse(readFileSync(filePath, 'utf-8'));
sidebar.push(content);
console.error(`\u2713 Loaded ${mod.name}`);
} catch (e) {
console.error(`\u26A0 Skipping ${mod.name}: ${e.message}`);
}
}
console.log(JSON.stringify(sidebar, null, 2));
+2552
View File
File diff suppressed because it is too large Load Diff
+2
View File
@@ -61,6 +61,8 @@ services:
VITE_API_BASE_URL: ${VITE_API_BASE_URL}
ports:
- "${WEB_PORT:-80}:80"
volumes:
- ./apps/docs/.vitepress/dist:/usr/share/nginx/html/docs:ro
depends_on:
- server-core
restart: unless-stopped
+9
View File
@@ -47,6 +47,15 @@ echo "[+] Syncing and updating submodules..."
SUBMODULE_FAILED=false
git submodule update --init --recursive --remote || { SUBMODULE_FAILED=true; echo "[!] Git submodule update skipped or failed."; }
# 2b. Build VitePress docs (non-blocking)
echo "[+] Building VitePress documentation..."
DOCS_BUILD_FAILED=false
if [ -d "apps/docs" ]; then
(cd apps/docs && npm install && npm run docs:build) || { DOCS_BUILD_FAILED=true; echo "[!] Docs build failed. Documentation may be stale. Continuing deployment..."; }
else
echo "[!] apps/docs directory not found. Skipping docs build."
fi
# 3. Hitung state hash (git + .env) untuk deteksi perubahan
CURRENT_HASH=$(echo "$(git rev-parse HEAD 2>/dev/null)$(git submodule status 2>/dev/null)$(sha256sum .env 2>/dev/null)" | sha256sum | cut -d" " -f1)