@hed-hog/cli 0.0.60 → 0.0.61
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 +34 -78
- 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
|
|
@@ -254,66 +272,4 @@ jobs:
|
|
|
254
272
|
kubectl logs -l app=<%= config.appName %>-admin -n ${{ env.NAMESPACE }} --tail=50 --previous 2>/dev/null || true
|
|
255
273
|
exit 1
|
|
256
274
|
)
|
|
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
|
-
<% }); %>
|
|
275
|
+
<% } %>
|