Repository navigation
Expand file tree
/
Copy pathTaskfile.yml
More file actions
179 lines (163 loc) · 7.93 KB
/
Copy pathTaskfile.yml
File metadata and controls
179 lines (163 loc) · 7.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# Taskfile for the Portal Plugin System local dev environment.
#
# Two tiers (see devenv/README.md and docs/enhancements/portal-plugin-system.md):
# Tier 0 — direct override, no Kubernetes: PORTAL_PLUGINS="sample=http://localhost:7777" npm run dev
# Tier 1 — local plugin registry (this Taskfile): kwok + PortalPlugin CRD + watch/status pipeline
#
# Quick start (Tier 1):
# task devenv:up # kwok cluster + CRD, kubeconfig -> .devenv/kubeconfig
# task plugin:preview # sample plugin (built, proxy-safe) on :7777 (separate terminal)
# task devenv:register # apply the sample PortalPlugin
# task devenv:portal # run the portal against the local registry (separate terminal)
#
# NB: the portal loads plugin assets through its same-origin proxy. Serve the
# plugin with `plugin:preview` (built); the Vite dev server (`plugin:dev`) uses
# host-absolute module URLs that don't survive the proxy — it's for the
# standalone :7777 preview / component HMR only. See devenv/README.md.
#
# Every API call a plugin issues goes through the portal's Milo control-plane
# proxy (including calls to a service's own aggregated apiserver) — there is
# no plugin-declared backend, so no separate backend process to run here.
#
# Requires: task, kubectl, and one of {curl+internet for kwok, docker, kind}.
version: '3'
vars:
DEVENV_DIR: '{{.ROOT_DIR}}/.devenv'
KUBECONFIG_PATH: '{{.ROOT_DIR}}/.devenv/kubeconfig'
CLUSTER_NAME: portal-dev
CRD_NAME: portalplugins.portal.miloapis.com
PLUGIN_DIR: '{{.ROOT_DIR}}/examples/sample-plugin'
PLUGIN_PORT: '7777'
tasks:
default:
desc: List available tasks
cmds:
- task --list
silent: true
# ---------------------------------------------------------------------------
# Tier 1: local plugin registry (kwok)
# ---------------------------------------------------------------------------
devenv:up:
desc: 'Stand up the local plugin registry (kwok cluster + PortalPlugin CRD). Idempotent.'
aliases: [portal:registry]
cmds:
- bash '{{.ROOT_DIR}}/devenv/scripts/ensure-kwok.sh'
- task: crds:apply
- task: _next-steps
devenv:down:
desc: 'Tear down the local plugin registry cluster and remove its kubeconfig.'
cmds:
- |
runtime="$(cat '{{.DEVENV_DIR}}/runtime' 2>/dev/null || echo unknown)"
echo "Tearing down cluster '{{.CLUSTER_NAME}}' (runtime: $runtime)"
case "$runtime" in
kwok-*)
KWOK_WORKDIR='{{.DEVENV_DIR}}/kwok' '{{.DEVENV_DIR}}/bin/kwokctl' delete cluster --name '{{.CLUSTER_NAME}}' || true ;;
kind)
kind delete cluster --name '{{.CLUSTER_NAME}}' || true ;;
*)
KWOK_WORKDIR='{{.DEVENV_DIR}}/kwok' '{{.DEVENV_DIR}}/bin/kwokctl' delete cluster --name '{{.CLUSTER_NAME}}' 2>/dev/null || true
kind delete cluster --name '{{.CLUSTER_NAME}}' 2>/dev/null || true ;;
esac
- rm -f '{{.DEVENV_DIR}}/kubeconfig' '{{.DEVENV_DIR}}/runtime'
crds:apply:
desc: 'Apply the PortalPlugin CRD to the local registry and wait for it to establish.'
cmds:
- kubectl --kubeconfig '{{.KUBECONFIG_PATH}}' apply -f '{{.ROOT_DIR}}/devenv/crds/'
- kubectl --kubeconfig '{{.KUBECONFIG_PATH}}' wait --for=condition=Established --timeout=60s crd/{{.CRD_NAME}}
devenv:register:
desc: 'Apply the sample PortalPlugin (slug "sample", assets http://localhost:7777) to the registry.'
cmds:
- kubectl --kubeconfig '{{.KUBECONFIG_PATH}}' apply -f '{{.ROOT_DIR}}/devenv/manifests/sample-portalplugin.yaml'
- kubectl --kubeconfig '{{.KUBECONFIG_PATH}}' get portalplugins
devenv:unregister:
desc: 'Delete the sample PortalPlugin from the registry (exercises the portal unload-on-delete path).'
cmds:
- kubectl --kubeconfig '{{.KUBECONFIG_PATH}}' delete -f '{{.ROOT_DIR}}/devenv/manifests/sample-portalplugin.yaml' --ignore-not-found
devenv:status:
desc: 'Show the local registry: chosen runtime, cluster nodes, CRD, and registered plugins.'
cmds:
- 'echo "runtime: $(cat ''{{.DEVENV_DIR}}/runtime'' 2>/dev/null || echo none)"'
- kubectl --kubeconfig '{{.KUBECONFIG_PATH}}' get crd {{.CRD_NAME}} 2>/dev/null || echo "CRD not applied"
- kubectl --kubeconfig '{{.KUBECONFIG_PATH}}' get portalplugins 2>/dev/null || echo "no portalplugins"
devenv:portal:
desc: 'Run the portal against the local registry (Tier 1). Serve the plugin with `plugin:preview`. Auth/orgs/projects stay remote.'
cmds:
- PLUGIN_REGISTRY_KUBECONFIG='{{.KUBECONFIG_PATH}}' AUTH_DEV_TOKEN_EXCHANGE=1 npm run dev
devenv:portal:tier0:
desc: 'Run the portal in Tier 0 (direct override, no Kubernetes). Serve the plugin with `plugin:preview`.'
cmds:
- PORTAL_PLUGINS='sample=http://localhost:{{.PLUGIN_PORT}}' AUTH_DEV_TOKEN_EXCHANGE=1 npm run dev
# ---------------------------------------------------------------------------
# Sample plugin (own package.json under examples/sample-plugin)
# ---------------------------------------------------------------------------
plugin:install:
desc: 'Install the sample plugin dependencies (npm, own package.json).'
dir: '{{.PLUGIN_DIR}}'
cmds:
- npm install
status:
- test -d '{{.PLUGIN_DIR}}/node_modules'
plugin:dev:
desc: 'Run the sample plugin: Vite dev server (HMR) on :7777. Humans/standalone; see plugin:preview for proxy/CI.'
dir: '{{.PLUGIN_DIR}}'
deps: [plugin:install]
cmds:
- npm run dev
plugin:build:
desc: 'Build the sample plugin frontend to a static dist/ (remote entry + manifest + chunks).'
dir: '{{.PLUGIN_DIR}}'
deps: [plugin:install]
cmds:
- npm run build
plugin:preview:
desc: 'Build then serve the STATIC plugin on :7777. Proxy-safe — use this for e2e/CI, not plugin:dev.'
dir: '{{.PLUGIN_DIR}}'
deps: [plugin:build]
cmds:
- npm run preview
# ---------------------------------------------------------------------------
# Platform control plane (documented option; NOT used by tests)
# ---------------------------------------------------------------------------
devenv:platform-kubeconfig:
desc: >-
Point the SAME portal registry knob at a REAL platform control plane
instead of kwok. Requires an active `datumctl` session and DATUM_ORG or
DATUM_PROJECT. Writes .devenv/platform-kubeconfig. Never run by tests.
cmds:
- |
set -e
if [ -n "${DATUM_ORG:-}" ]; then
scope="--organization ${DATUM_ORG}"
elif [ -n "${DATUM_PROJECT:-}" ]; then
scope="--project ${DATUM_PROJECT}"
else
echo "Set DATUM_ORG=<org-id> or DATUM_PROJECT=<project-id> first." >&2
echo "This configures kubectl/portal access to a real Datum control plane." >&2
exit 1
fi
datumctl auth update-kubeconfig $scope \
--kubeconfig '{{.DEVENV_DIR}}/platform-kubeconfig' \
--exec-interactive-mode Never
echo ""
echo "Wrote {{.DEVENV_DIR}}/platform-kubeconfig"
echo "Run the portal against it with:"
echo " PLUGIN_REGISTRY_KUBECONFIG={{.DEVENV_DIR}}/platform-kubeconfig AUTH_DEV_TOKEN_EXCHANGE=1 npm run dev"
# ---------------------------------------------------------------------------
# Internal helpers
# ---------------------------------------------------------------------------
_next-steps:
internal: true
silent: true
cmds:
- |
echo ""
echo "Local plugin registry is up (runtime: $(cat '{{.DEVENV_DIR}}/runtime' 2>/dev/null || echo unknown))."
echo " kubeconfig: {{.KUBECONFIG_PATH}}"
echo ""
echo "Next steps:"
echo " task plugin:preview # build + serve the sample plugin on :{{.PLUGIN_PORT}} (separate terminal)"
echo " task devenv:register # register the sample PortalPlugin"
echo " task devenv:portal # run the portal against the local registry (separate terminal)"
echo ""
echo "Inspect with: kubectl --kubeconfig {{.KUBECONFIG_PATH}} get portalplugins"