@hed-hog/cli 0.0.60 → 0.0.62
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/package.json +1 -1
- package/dist/src/modules/developer/developer.service.js +39 -1
- package/dist/src/modules/developer/developer.service.js.map +1 -1
- package/dist/src/templates/deployment/k8s.deployment.yaml.ejs +27 -3
- package/dist/src/templates/deployment/workflow.deploy.yml.ejs +37 -79
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -23,6 +23,23 @@ spec:
|
|
|
23
23
|
env:
|
|
24
24
|
- name: NODE_ENV
|
|
25
25
|
value: production
|
|
26
|
+
<% if (app === 'admin') { %>
|
|
27
|
+
- name: INTERNAL_API_URL
|
|
28
|
+
valueFrom:
|
|
29
|
+
configMapKeyRef:
|
|
30
|
+
name: <%= config.appName %>-<%= app %>-config
|
|
31
|
+
key: INTERNAL_API_URL
|
|
32
|
+
- name: NEXT_PUBLIC_API_BASE_URL
|
|
33
|
+
valueFrom:
|
|
34
|
+
configMapKeyRef:
|
|
35
|
+
name: <%= config.appName %>-<%= app %>-config
|
|
36
|
+
key: NEXT_PUBLIC_API_BASE_URL
|
|
37
|
+
- name: NEXT_PUBLIC_API_URL
|
|
38
|
+
valueFrom:
|
|
39
|
+
configMapKeyRef:
|
|
40
|
+
name: <%= config.appName %>-<%= app %>-config
|
|
41
|
+
key: NEXT_PUBLIC_API_URL
|
|
42
|
+
<% } else { %>
|
|
26
43
|
<%
|
|
27
44
|
const secretEnvKeys = new Set(['DATABASE_URL', 'ENCRYPTION_SECRET', 'JWT_SECRET', 'PEPPER']);
|
|
28
45
|
Object.keys(appEnv || {}).sort().filter((key) => key !== 'NODE_ENV').forEach((key) => {
|
|
@@ -37,6 +54,7 @@ Object.keys(appEnv || {}).sort().filter((key) => key !== 'NODE_ENV').forEach((ke
|
|
|
37
54
|
key: <%= key %>
|
|
38
55
|
<% } %>
|
|
39
56
|
<% }); %>
|
|
57
|
+
<% } %>
|
|
40
58
|
resources:
|
|
41
59
|
requests:
|
|
42
60
|
memory: 512Mi
|
|
@@ -46,22 +64,28 @@ Object.keys(appEnv || {}).sort().filter((key) => key !== 'NODE_ENV').forEach((ke
|
|
|
46
64
|
cpu: 500m
|
|
47
65
|
startupProbe:
|
|
48
66
|
httpGet:
|
|
49
|
-
path: <%= app === 'api' ? '/health' : '/' %>
|
|
67
|
+
path: <%= app === 'api' || app === 'admin' ? '/health' : '/' %>
|
|
50
68
|
port: <%= config.appPorts?.[app] ?? (app === 'api' ? 3000 : 80) %>
|
|
51
69
|
initialDelaySeconds: 15
|
|
52
70
|
periodSeconds: 10
|
|
53
71
|
failureThreshold: 12
|
|
72
|
+
<% if (app === 'admin') { %> timeoutSeconds: 5
|
|
73
|
+
<% } %>
|
|
54
74
|
livenessProbe:
|
|
55
75
|
httpGet:
|
|
56
|
-
path: <%= app === 'api' ? '/health' : '/' %>
|
|
76
|
+
path: <%= app === 'api' || app === 'admin' ? '/health' : '/' %>
|
|
57
77
|
port: <%= config.appPorts?.[app] ?? (app === 'api' ? 3000 : 80) %>
|
|
58
78
|
initialDelaySeconds: 0
|
|
59
79
|
periodSeconds: 15
|
|
60
80
|
failureThreshold: 3
|
|
81
|
+
<% if (app === 'admin') { %> timeoutSeconds: 5
|
|
82
|
+
<% } %>
|
|
61
83
|
readinessProbe:
|
|
62
84
|
httpGet:
|
|
63
|
-
path: <%= app === 'api' ? '/health' : '/' %>
|
|
85
|
+
path: <%= app === 'api' || app === 'admin' ? '/health' : '/' %>
|
|
64
86
|
port: <%= config.appPorts?.[app] ?? (app === 'api' ? 3000 : 80) %>
|
|
65
87
|
initialDelaySeconds: 0
|
|
66
88
|
periodSeconds: 10
|
|
67
89
|
failureThreshold: 3
|
|
90
|
+
<% if (app === 'admin') { %> timeoutSeconds: 5
|
|
91
|
+
<% } %>
|
|
@@ -2,20 +2,24 @@ name: Deploy to Kubernetes
|
|
|
2
2
|
on:
|
|
3
3
|
push:
|
|
4
4
|
branches:
|
|
5
|
-
- <%= config.deployBranch
|
|
5
|
+
- <%= config.deployBranch %>
|
|
6
6
|
workflow_dispatch:
|
|
7
7
|
env:
|
|
8
8
|
REGISTRY: <%= config.containerRegistry %>
|
|
9
9
|
NAMESPACE: <%= config.namespace %>
|
|
10
|
-
K8S_CLUSTER_ID: <%= config.
|
|
10
|
+
K8S_CLUSTER_ID: <%= config.clusterName %>
|
|
11
|
+
<% if ((config.apps || []).includes('api')) { %>
|
|
11
12
|
# API environment
|
|
12
|
-
API_FRONTEND_URL: <%= config.
|
|
13
|
+
API_FRONTEND_URL: <%= config.domain ? 'https://' + config.domain : '' %>
|
|
13
14
|
API_JWT_EXPIRES_IN: <%= config.jwtExpiresIn || '7d' %>
|
|
15
|
+
<% } %>
|
|
16
|
+
<% if ((config.apps || []).includes('admin')) { %>
|
|
14
17
|
# Admin environment (runtime-replaced at container startup)
|
|
15
|
-
ADMIN_API_BASE_URL: <%= config.
|
|
16
|
-
ADMIN_API_URL: <%= config.
|
|
17
|
-
ADMIN_INTERNAL_API_URL: http://<%= config.appName %>-api
|
|
18
|
-
FRONTEND_URLS: <%= config.frontendUrls
|
|
18
|
+
ADMIN_API_BASE_URL: <%= config.apiDomain || '' %>
|
|
19
|
+
ADMIN_API_URL: <%= config.apiDomain || '' %>
|
|
20
|
+
ADMIN_INTERNAL_API_URL: http://<%= config.appName %>-api:3100
|
|
21
|
+
FRONTEND_URLS: <%= config.frontendUrls %>
|
|
22
|
+
<% } %>
|
|
19
23
|
jobs:
|
|
20
24
|
apply-cluster-config:
|
|
21
25
|
name: Apply Kubernetes and Helm configs
|
|
@@ -34,12 +38,14 @@ jobs:
|
|
|
34
38
|
kubectl create namespace ${{ env.NAMESPACE }} --dry-run=client -o yaml | kubectl apply -f -
|
|
35
39
|
- name: Apply Kubernetes manifests
|
|
36
40
|
run: |
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
+
<% (config.apps || []).forEach(function(app) { %>
|
|
42
|
+
kubectl apply -f k8s/<%= app %> -n ${{ env.NAMESPACE }}
|
|
43
|
+
<% }); %>
|
|
44
|
+
|
|
41
45
|
|
|
42
|
-
|
|
46
|
+
|
|
47
|
+
<% if ((config.apps || []).includes('api')) { %>
|
|
48
|
+
deploy-api:
|
|
43
49
|
name: Deploy API
|
|
44
50
|
runs-on: ubuntu-latest
|
|
45
51
|
needs: apply-cluster-config
|
|
@@ -77,6 +83,16 @@ jobs:
|
|
|
77
83
|
run: |
|
|
78
84
|
docker build -t ${{ env.REGISTRY }}/<%= config.appName %>-api:${{ github.sha }} \
|
|
79
85
|
-f apps/api/Dockerfile .
|
|
86
|
+
- name: Validate API runtime image
|
|
87
|
+
run: |
|
|
88
|
+
docker run --rm --entrypoint sh \
|
|
89
|
+
${{ env.REGISTRY }}/<%= config.appName %>-api:${{ github.sha }} \
|
|
90
|
+
-c '
|
|
91
|
+
set -eu
|
|
92
|
+
test -f /app/apps/api/dist/apps/api/src/main.js
|
|
93
|
+
node -e "require(\"@prisma/client\")"
|
|
94
|
+
node -e "require(\"/app/apps/api/dist/packages/api-prisma/src/generated-client.js\")"
|
|
95
|
+
'
|
|
80
96
|
- name: Push Docker image (sha)
|
|
81
97
|
run: |
|
|
82
98
|
docker push ${{ env.REGISTRY }}/<%= config.appName %>-api:${{ github.sha }}
|
|
@@ -171,13 +187,15 @@ jobs:
|
|
|
171
187
|
kubectl logs -l app=<%= config.appName %>-api -n ${{ env.NAMESPACE }} --tail=50 --previous 2>/dev/null || true
|
|
172
188
|
exit 1
|
|
173
189
|
)
|
|
174
|
-
|
|
175
|
-
<%
|
|
190
|
+
<% } %>
|
|
191
|
+
<% if ((config.apps || []).includes('admin')) { %>
|
|
192
|
+
deploy-admin:
|
|
176
193
|
name: Deploy ADMIN
|
|
177
194
|
runs-on: ubuntu-latest
|
|
178
195
|
needs:
|
|
179
196
|
- apply-cluster-config
|
|
180
|
-
<% if (config.apps.includes('api')) { %>
|
|
197
|
+
<% if ((config.apps || []).includes('api')) { %>
|
|
198
|
+
- deploy-api
|
|
181
199
|
<% } %>
|
|
182
200
|
steps:
|
|
183
201
|
- name: Checkout code
|
|
@@ -211,7 +229,9 @@ jobs:
|
|
|
211
229
|
docker push ${{ env.REGISTRY }}/ci-auth-probe-admin:${{ github.run_id }}
|
|
212
230
|
- name: Build Docker image
|
|
213
231
|
run: |
|
|
214
|
-
docker build -t ${{ env.REGISTRY }}/<%= config.appName
|
|
232
|
+
docker build -t ${{ env.REGISTRY }}/<%= config.appName %:${{ github.sha }} \
|
|
233
|
+
--build-arg NEXT_PUBLIC_API_BASE_URL=${{ env.ADMIN_API_BASE_URL }} \
|
|
234
|
+
--build-arg NEXT_PUBLIC_API_URL=${{ env.ADMIN_API_URL }} \
|
|
215
235
|
-f apps/admin/Dockerfile .
|
|
216
236
|
- name: Push Docker image (sha)
|
|
217
237
|
run: |
|
|
@@ -254,66 +274,4 @@ jobs:
|
|
|
254
274
|
kubectl logs -l app=<%= config.appName %>-admin -n ${{ env.NAMESPACE }} --tail=50 --previous 2>/dev/null || true
|
|
255
275
|
exit 1
|
|
256
276
|
)
|
|
257
|
-
<% }
|
|
258
|
-
deploy-<%= app %>:
|
|
259
|
-
name: Deploy <%= app.toUpperCase() %>
|
|
260
|
-
runs-on: ubuntu-latest
|
|
261
|
-
needs: apply-cluster-config
|
|
262
|
-
steps:
|
|
263
|
-
- name: Checkout code
|
|
264
|
-
uses: actions/checkout@v4
|
|
265
|
-
- name: Install doctl
|
|
266
|
-
uses: digitalocean/action-doctl@v2
|
|
267
|
-
with:
|
|
268
|
-
token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }}
|
|
269
|
-
- name: Validate DigitalOcean token
|
|
270
|
-
run: |
|
|
271
|
-
doctl auth validate
|
|
272
|
-
doctl account get
|
|
273
|
-
- name: Validate Container Registry access
|
|
274
|
-
run: |
|
|
275
|
-
doctl registry get
|
|
276
|
-
doctl registry repository list >/dev/null 2>&1 && doctl registry repository list || echo "doctl registry repository list not available in this version"
|
|
277
|
-
- name: Log in to Container Registry
|
|
278
|
-
run: doctl registry login --expiry-seconds 1200
|
|
279
|
-
- name: Check Docker auth config
|
|
280
|
-
run: |
|
|
281
|
-
if [ -f "$HOME/.docker/config.json" ]; then
|
|
282
|
-
grep -q 'registry.digitalocean.com' "$HOME/.docker/config.json" && echo "Docker auth entry for registry.digitalocean.com found"
|
|
283
|
-
else
|
|
284
|
-
echo "Docker config not found at $HOME/.docker/config.json"
|
|
285
|
-
exit 1
|
|
286
|
-
fi
|
|
287
|
-
- name: Registry auth probe push
|
|
288
|
-
run: |
|
|
289
|
-
docker pull hello-world
|
|
290
|
-
docker tag hello-world ${{ env.REGISTRY }}/ci-auth-probe-<%= app %>:${{ github.run_id }}
|
|
291
|
-
docker push ${{ env.REGISTRY }}/ci-auth-probe-<%= app %>:${{ github.run_id }}
|
|
292
|
-
- name: Build Docker image
|
|
293
|
-
run: |
|
|
294
|
-
docker build -t ${{ env.REGISTRY }}/<%= config.appName %>-<%= app %>:${{ github.sha }} \
|
|
295
|
-
-f apps/<%= app %>/Dockerfile .
|
|
296
|
-
- name: Push Docker image (sha)
|
|
297
|
-
run: |
|
|
298
|
-
docker push ${{ env.REGISTRY }}/<%= config.appName %>-<%= app %>:${{ github.sha }}
|
|
299
|
-
- name: Push Docker image (latest)
|
|
300
|
-
run: |
|
|
301
|
-
docker tag ${{ env.REGISTRY }}/<%= config.appName %>-<%= app %>:${{ github.sha }} \
|
|
302
|
-
${{ env.REGISTRY }}/<%= config.appName %>-<%= app %>:latest
|
|
303
|
-
docker push ${{ env.REGISTRY }}/<%= config.appName %>-<%= app %>:latest
|
|
304
|
-
- name: Save DigitalOcean kubeconfig
|
|
305
|
-
run: doctl kubernetes cluster kubeconfig save ${{ env.K8S_CLUSTER_ID }}
|
|
306
|
-
- name: Deploy to Kubernetes
|
|
307
|
-
run: |
|
|
308
|
-
kubectl set image deployment/<%= config.appName %>-<%= app %> \
|
|
309
|
-
<%= config.appName %>-<%= app %>=${{ env.REGISTRY }}/<%= config.appName %>-<%= app %>:${{ github.sha }} \
|
|
310
|
-
-n ${{ env.NAMESPACE }}
|
|
311
|
-
kubectl rollout status deployment/<%= config.appName %>-<%= app %> -n ${{ env.NAMESPACE }} --timeout=5m || (
|
|
312
|
-
echo "--- Rollout timed out. Pod status:"
|
|
313
|
-
kubectl get pods -l app=<%= config.appName %>-<%= app %> -n ${{ env.NAMESPACE }}
|
|
314
|
-
echo "--- Recent events:"
|
|
315
|
-
kubectl describe deployment/<%= config.appName %>-<%= app %> -n ${{ env.NAMESPACE }} | tail -20
|
|
316
|
-
kubectl logs -l app=<%= config.appName %>-<%= app %> -n ${{ env.NAMESPACE }} --tail=50 --previous 2>/dev/null || true
|
|
317
|
-
exit 1
|
|
318
|
-
)
|
|
319
|
-
<% }); %>
|
|
277
|
+
<% } %>
|