@abgov/nx-oc 12.10.0 → 12.12.0

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/generators.json CHANGED
@@ -27,6 +27,11 @@
27
27
  "factory": "./src/generators/sandbox/sandbox",
28
28
  "schema": "./src/generators/sandbox/schema.json",
29
29
  "description": "Generator that creates a sandbox deployment for rapid local iteration (local build, push to OC internal registry)."
30
+ },
31
+ "teardown": {
32
+ "factory": "./src/generators/teardown/teardown",
33
+ "schema": "./src/generators/teardown/schema.json",
34
+ "description": "Adds a teardown target to remove an application's resources from a specific OpenShift environment."
30
35
  }
31
36
  }
32
37
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abgov/nx-oc",
3
- "version": "12.10.0",
3
+ "version": "12.12.0",
4
4
  "license": "Apache-2.0",
5
5
  "main": "src/index.js",
6
6
  "description": "Government of Alberta - Nx plugin for OpenShift.",
@@ -7,46 +7,26 @@ const path = require("path");
7
7
  const yaml = require("yaml");
8
8
  const pipeline_envs_1 = require("../../pipeline-envs");
9
9
  const git_utils_1 = require("../../utils/git-utils");
10
+ const app_type_1 = require("../../utils/app-type");
10
11
  const adsp_1 = require("../../adsp");
11
12
  const infraManifestFile = '.openshift/environments.yml';
12
13
  function normalizeOptions(host, options) {
13
14
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
14
- var _a, _b, _c, _d;
15
+ var _a, _b, _c, _d, _e;
15
16
  const projectName = (0, devkit_1.names)(options.project).fileName;
16
17
  const result = host.read(infraManifestFile).toString();
17
18
  const { items } = yaml.parse(result);
18
19
  const ocInfraProject = ((_b = (_a = items[0]) === null || _a === void 0 ? void 0 : _a.metadata) === null || _b === void 0 ? void 0 : _b.namespace) || '';
19
20
  const SA_PREFIX = 'system:serviceaccounts:';
20
21
  const ocEnvProjects = (_d = (_c = items[0]) === null || _c === void 0 ? void 0 : _c.subjects) === null || _d === void 0 ? void 0 : _d.filter((s) => s.kind === 'Group' && s.name.startsWith(SA_PREFIX)).map((s) => s.name.replace(SA_PREFIX, ''));
21
- // TODO: Find a better way to determine this.
22
22
  const config = (0, devkit_1.readProjectConfiguration)(host, projectName);
23
- let appType = options.appType;
24
- if (!appType) {
25
- switch (config.targets.build.executor) {
26
- case '@nx/web:webpack':
27
- case '@angular-devkit/build-angular:browser':
28
- appType = 'frontend';
29
- break;
30
- case '@nx/node:build':
31
- appType = 'node';
32
- break;
33
- case '@nx-dotnet/core:build':
34
- appType = 'dotnet';
35
- break;
36
- case '@nx/webpack:webpack': {
37
- // More recent version of NX switched to use a generic webpack executor for builds.
38
- appType =
39
- config.targets.build.options.target === 'node' ? 'node' : 'frontend';
40
- break;
41
- }
42
- }
43
- }
23
+ const appType = (_e = options.appType) !== null && _e !== void 0 ? _e : (0, app_type_1.detectApplicationType)(config);
44
24
  const adsp = yield (0, adsp_1.getAdspConfiguration)(host, options);
45
25
  return Object.assign(Object.assign({}, options), { appType,
46
26
  adsp,
47
27
  projectName,
48
28
  ocInfraProject,
49
- ocEnvProjects });
29
+ ocEnvProjects, buildOutputPath: (0, app_type_1.getBuildOutputPath)(config) });
50
30
  });
51
31
  }
52
32
  function addFiles(host, options) {
@@ -1 +1 @@
1
- {"version":3,"file":"deployment.js","sourceRoot":"","sources":["../../../../../../packages/nx-oc/src/generators/deployment/deployment.ts"],"names":[],"mappings":";;AAqFA,4BAqCC;;AA1HD,uCAOoB;AACpB,6BAA6B;AAC7B,6BAA6B;AAC7B,uDAA2D;AAC3D,qDAAwD;AAExD,qCAAkD;AAElD,MAAM,iBAAiB,GAAG,6BAA6B,CAAC;AAExD,SAAe,gBAAgB,CAC7B,IAAU,EACV,OAAe;;;QAEf,MAAM,WAAW,GAAG,IAAA,cAAK,EAAC,OAAO,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC;QAEpD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,QAAQ,EAAE,CAAC;QACvD,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACrC,MAAM,cAAc,GAAG,CAAA,MAAA,MAAA,KAAK,CAAC,CAAC,CAAC,0CAAE,QAAQ,0CAAE,SAAS,KAAI,EAAE,CAAC;QAE3D,MAAM,SAAS,GAAG,yBAAyB,CAAC;QAC5C,MAAM,aAAa,GAAG,MAAA,MAAA,KAAK,CAAC,CAAC,CAAC,0CAAE,QAAQ,0CACpC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EACjE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,CAAC;QAE7C,6CAA6C;QAC7C,MAAM,MAAM,GAAG,IAAA,iCAAwB,EAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAC3D,IAAI,OAAO,GAAoB,OAAO,CAAC,OAAO,CAAC;QAC/C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,QAAQ,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;gBACtC,KAAK,iBAAiB,CAAC;gBACvB,KAAK,uCAAuC;oBAC1C,OAAO,GAAG,UAAU,CAAC;oBACrB,MAAM;gBACR,KAAK,gBAAgB;oBACnB,OAAO,GAAG,MAAM,CAAC;oBACjB,MAAM;gBACR,KAAK,uBAAuB;oBAC1B,OAAO,GAAG,QAAQ,CAAC;oBACnB,MAAM;gBACR,KAAK,qBAAqB,CAAC,CAAC,CAAC;oBAC3B,mFAAmF;oBACnF,OAAO;wBACL,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC;oBACvE,MAAM;gBACR,CAAC;YACH,CAAC;QACH,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,IAAA,2BAAoB,EAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAEvD,uCACK,OAAO,KACV,OAAO;YACP,IAAI;YACJ,WAAW;YACX,cAAc;YACd,aAAa,IACb;IACJ,CAAC;CAAA;AAED,SAAS,QAAQ,CAAC,IAAU,EAAE,OAAyB;;IACrD,MAAM,eAAe,iDAChB,OAAO,GACP,OAAO,CAAC,IAAI,KACf,mBAAmB,EAAE,IAAA,2BAAe,GAAE,EACtC,QAAQ,EAAE,MAAA,OAAO,CAAC,QAAQ,mCAAI,MAAM,EACpC,OAAO,EAAE,MAAA,OAAO,CAAC,OAAO,mCAAI,KAAK,EACjC,IAAI,EAAE,EAAE,GACT,CAAC;IACF,IAAA,sBAAa,EACX,IAAI,EACJ,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,OAAO,CAAC,OAAO,QAAQ,CAAC,EAChD,gBAAgB,OAAO,CAAC,WAAW,EAAE,EACrC,eAAe,CAChB,CAAC;AACJ,CAAC;AAED,mBAA+B,IAAU,EAAE,OAAe;;QACxD,MAAM,MAAM,GAAG,IAAA,iCAAwB,EAAC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;QAC/D,IAAI,MAAM,CAAC,WAAW,KAAK,aAAa,EAAE,CAAC;YACzC,OAAO,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC;YACvD,OAAO;QACT,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,EAAE,CAAC;YACpC,OAAO,CAAC,GAAG,CACT,qEAAqE,CACtE,CAAC;YACF,OAAO;QACT,CAAC;QAED,MAAM,iBAAiB,GAAG,MAAM,gBAAgB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAChE,IAAI,CAAC,iBAAiB,CAAC,OAAO,EAAE,CAAC;YAC/B,OAAO,CAAC,GAAG,CAAC,sDAAsD,CAAC,CAAC;YACpE,OAAO;QACT,CAAC;QAED,MAAM,CAAC,OAAO,mCACT,MAAM,CAAC,OAAO,KACjB,YAAY,EAAE;gBACZ,QAAQ,EAAE,oBAAoB;gBAC9B,OAAO,EAAE;oBACP,SAAS,EAAE,iBAAiB,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,EAAE;;wBAAC,OAAA,CAAC;4BAC9D,OAAO;4BACP,GAAG,EAAE,MAAA,4BAAI,CAAC,CAAC,CAAC,0CAAE,WAAW,EAAE;yBAC5B,CAAC,CAAA;qBAAA,CAAC;iBACJ;aACF,GACF,CAAC;QAEF,IAAA,mCAA0B,EAAC,IAAI,EAAE,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAE1D,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC;QAClC,MAAM,IAAA,oBAAW,EAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;CAAA"}
1
+ {"version":3,"file":"deployment.js","sourceRoot":"","sources":["../../../../../../packages/nx-oc/src/generators/deployment/deployment.ts"],"names":[],"mappings":"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"}
@@ -1,10 +1,10 @@
1
1
  # This is a minimal Dockerfile for app deployment.
2
2
  FROM registry.access.redhat.com/ubi8/dotnet-60-runtime
3
3
 
4
- ARG PROJECT
5
4
  ARG ASSEMBLY
6
5
 
7
- COPY ./dist/apps/${PROJECT}/net6.0 .
6
+ # Build output path mirrors the workspace layout (from the project's build target).
7
+ COPY ./<%= buildOutputPath %>/net6.0 .
8
8
 
9
9
  ENV ASSEMBLY ${ASSEMBLY}
10
10
  CMD dotnet ${ASSEMBLY}
@@ -1,8 +1,8 @@
1
1
  # This is a minimal Dockerfile for app deployment.
2
2
  FROM registry.access.redhat.com/ubi8/nginx-118
3
3
 
4
- ARG PROJECT
5
- COPY ./dist/apps/${PROJECT}/nginx.conf "${NGINX_CONF_PATH}"
6
- COPY ./dist/apps/${PROJECT} .
4
+ # Build output path mirrors the workspace layout (from the project's build target).
5
+ COPY ./<%= buildOutputPath %>/nginx.conf "${NGINX_CONF_PATH}"
6
+ COPY ./<%= buildOutputPath %> .
7
7
 
8
8
  CMD nginx -g "daemon off;"
@@ -1,8 +1,8 @@
1
1
  # This is a minimal Dockerfile for app deployment.
2
2
  FROM registry.access.redhat.com/ubi8/nodejs-18
3
3
 
4
- ARG PROJECT
5
- COPY ./dist/apps/${PROJECT} .
4
+ # Build output path mirrors the workspace layout (from the project's build target).
5
+ COPY ./<%= buildOutputPath %> .
6
6
  COPY ./node_modules ./node_modules
7
7
 
8
8
  CMD node main.js
@@ -19,4 +19,5 @@ export interface NormalizedSchema extends Schema {
19
19
  ocInfraProject: string;
20
20
  ocEnvProjects: string[];
21
21
  adsp: AdspConfiguration;
22
+ buildOutputPath: string;
22
23
  }
@@ -143,7 +143,6 @@ jobs:
143
143
  for app in $AFFECTED_APPS
144
144
  do
145
145
  buildah build \
146
- --build-arg PROJECT=$app \
147
146
  --file .openshift/$app/Dockerfile \
148
147
  --tag <%= registry %>/$app:latest \
149
148
  --tag <%= registry %>/$app:${{ github.sha }} \
@@ -0,0 +1,32 @@
1
+ # Sandbox in-cluster build infrastructure for <%= projectName %>.
2
+ # A binary Docker BuildConfig uploads the local build context (oc start-build
3
+ # --from-dir), builds the image inside the cluster, and pushes it to the
4
+ # ImageStream over the internal registry. This needs no GitHub repo/CI, no
5
+ # externally-exposed registry route, and no local container runtime — unlike
6
+ # the GitHub Actions + GHCR flow used for real environment deployments.
7
+ apiVersion: image.openshift.io/v1
8
+ kind: ImageStream
9
+ metadata:
10
+ name: <%= projectName %>
11
+ labels:
12
+ app: <%= projectName %>
13
+ ---
14
+ apiVersion: build.openshift.io/v1
15
+ kind: BuildConfig
16
+ metadata:
17
+ name: <%= projectName %>
18
+ labels:
19
+ app: <%= projectName %>
20
+ spec:
21
+ runPolicy: Serial
22
+ source:
23
+ type: Binary
24
+ binary: {}
25
+ strategy:
26
+ type: Docker
27
+ dockerStrategy:
28
+ dockerfilePath: .openshift/<%= projectName %>/Dockerfile
29
+ output:
30
+ to:
31
+ kind: ImageStreamTag
32
+ name: <%= projectName %>:sandbox
@@ -6,34 +6,17 @@ const devkit_1 = require("@nx/devkit");
6
6
  const path = require("path");
7
7
  const adsp_1 = require("../../adsp");
8
8
  const git_utils_1 = require("../../utils/git-utils");
9
+ const app_type_1 = require("../../utils/app-type");
9
10
  function normalizeOptions(host, options) {
10
11
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
11
- var _a;
12
+ var _a, _b;
12
13
  const projectName = (0, devkit_1.names)(options.project).fileName;
13
14
  const config = (0, devkit_1.readProjectConfiguration)(host, projectName);
14
- let appType = options.appType;
15
- if (!appType) {
16
- switch (config.targets.build.executor) {
17
- case '@nx/web:webpack':
18
- case '@angular-devkit/build-angular:browser':
19
- appType = 'frontend';
20
- break;
21
- case '@nx/node:build':
22
- appType = 'node';
23
- break;
24
- case '@nx-dotnet/core:build':
25
- appType = 'dotnet';
26
- break;
27
- case '@nx/webpack:webpack':
28
- appType =
29
- config.targets.build.options.target === 'node' ? 'node' : 'frontend';
30
- break;
31
- }
32
- }
33
- const adsp = yield (0, adsp_1.getAdspConfiguration)(host, Object.assign(Object.assign({}, options), { env: (_a = options.env) !== null && _a !== void 0 ? _a : 'dev' }));
15
+ const appType = (_a = options.appType) !== null && _a !== void 0 ? _a : (0, app_type_1.detectApplicationType)(config);
16
+ const adsp = yield (0, adsp_1.getAdspConfiguration)(host, Object.assign(Object.assign({}, options), { env: (_b = options.env) !== null && _b !== void 0 ? _b : 'dev' }));
34
17
  return Object.assign(Object.assign({}, options), { appType,
35
18
  adsp,
36
- projectName });
19
+ projectName, buildOutputPath: (0, app_type_1.getBuildOutputPath)(config) });
37
20
  });
38
21
  }
39
22
  function addManifestFiles(host, options) {
@@ -46,7 +29,18 @@ function addDatabaseFiles(host, options) {
46
29
  return;
47
30
  (0, devkit_1.generateFiles)(host, path.join(__dirname, 'database-files'), './.openshift/sandbox', { database: options.database, tmpl: '' });
48
31
  }
32
+ // In-cluster build infrastructure (ImageStream + binary Docker BuildConfig).
33
+ // The sandbox builds inside the cluster and pushes to the internal registry,
34
+ // so it needs no GitHub repo/CI, no externally-exposed registry route, and no
35
+ // local container runtime.
36
+ function addBuildFiles(host, options) {
37
+ (0, devkit_1.generateFiles)(host, path.join(__dirname, 'build-files'), './.openshift', {
38
+ projectName: options.projectName,
39
+ tmpl: '',
40
+ });
41
+ }
49
42
  function addSandboxTarget(host, options) {
43
+ var _a;
50
44
  const config = (0, devkit_1.readProjectConfiguration)(host, options.project);
51
45
  const { projectName, sandboxProject, database } = options;
52
46
  const commands = [];
@@ -64,21 +58,49 @@ function addSandboxTarget(host, options) {
64
58
  `-n ${sandboxProject}`);
65
59
  commands.push(`oc apply -f .openshift/sandbox/sandbox-mongodb.yml -n ${sandboxProject}`);
66
60
  }
61
+ // Ensure any paired backend Services exist first, so this app's nginx can
62
+ // resolve its proxy_pass upstreams at startup (otherwise the pod crashloops
63
+ // until the Service appears). Create only the Service (all nginx needs for
64
+ // DNS) — not the backend's deployment, which has no image until its own
65
+ // sandbox runs. Idempotent: skipped once the Service exists, so it doesn't
66
+ // slow down repeated frontend iteration. Recorded by the composite generators
67
+ // (pevn/mevn/…) as `adsp:proxy-service:<name>:<port>` project tags.
68
+ const PREFIX = 'adsp:proxy-service:';
69
+ const proxyServices = ((_a = config.tags) !== null && _a !== void 0 ? _a : [])
70
+ .filter((tag) => tag.startsWith(PREFIX))
71
+ .map((tag) => {
72
+ const value = tag.slice(PREFIX.length);
73
+ const lastColon = value.lastIndexOf(':');
74
+ return {
75
+ name: value.slice(0, lastColon),
76
+ port: value.slice(lastColon + 1),
77
+ };
78
+ });
79
+ for (const { name, port } of proxyServices) {
80
+ commands.push(`oc get service ${name} -n ${sandboxProject} >/dev/null 2>&1 || ` +
81
+ `oc create service clusterip ${name} --tcp=${port}:${port} -n ${sandboxProject}`);
82
+ }
83
+ // Ensure the in-cluster build infrastructure (ImageStream + BuildConfig).
84
+ commands.push(`oc apply -f .openshift/${projectName}/sandbox-build.yml -n ${sandboxProject}`);
85
+ // Build locally, then build the image in-cluster from the uploaded context
86
+ // and push to the internal registry — no external registry route required.
87
+ commands.push(`npx nx build ${projectName} --configuration production`);
88
+ commands.push(`oc start-build ${projectName} --from-dir=. --follow --wait -n ${sandboxProject}`);
67
89
  commands.push(`oc process -f .openshift/${projectName}/${projectName}.yml -p PROJECT=${sandboxProject} | oc apply -f -`);
68
- commands.push([
69
- `REGISTRY=$(oc registry info)`,
70
- `CONTAINER_CLI=$(command -v podman || command -v docker)`,
71
- `$CONTAINER_CLI login -u $(oc whoami) -p $(oc whoami -t) $REGISTRY`,
72
- `$CONTAINER_CLI build -t $REGISTRY/${sandboxProject}/${projectName}:sandbox -f .openshift/${projectName}/Dockerfile .`,
73
- `$CONTAINER_CLI push $REGISTRY/${sandboxProject}/${projectName}:sandbox`,
74
- ].join(' && '));
75
90
  commands.push(`oc rollout restart deployment/${projectName} -n ${sandboxProject}`);
76
- commands.push(`oc rollout status deployment/${projectName} -n ${sandboxProject} --timeout=120s`);
91
+ commands.push(`oc rollout status deployment/${projectName} -n ${sandboxProject} --timeout=180s`);
77
92
  config.targets = Object.assign(Object.assign({}, config.targets), { sandbox: {
78
93
  executor: 'nx:run-commands',
79
94
  options: {
80
95
  commands,
81
- sequential: true,
96
+ parallel: false,
97
+ },
98
+ }, 'sandbox-teardown': {
99
+ executor: 'nx:run-commands',
100
+ options: {
101
+ commands: [
102
+ `oc delete all,configmap,bc,is -l app=${projectName} -n ${sandboxProject} --ignore-not-found`,
103
+ ],
82
104
  },
83
105
  } });
84
106
  (0, devkit_1.updateProjectConfiguration)(host, options.project, config);
@@ -91,6 +113,7 @@ function default_1(host, options) {
91
113
  return;
92
114
  }
93
115
  addManifestFiles(host, normalizedOptions);
116
+ addBuildFiles(host, normalizedOptions);
94
117
  addDatabaseFiles(host, normalizedOptions);
95
118
  addSandboxTarget(host, normalizedOptions);
96
119
  yield (0, devkit_1.formatFiles)(host);
@@ -1 +1 @@
1
- {"version":3,"file":"sandbox.js","sourceRoot":"","sources":["../../../../../../packages/nx-oc/src/generators/sandbox/sandbox.ts"],"names":[],"mappings":";;AAiJA,4BAWC;;AA5JD,uCAOoB;AACpB,6BAA6B;AAC7B,qCAAkD;AAClD,qDAAwD;AAIxD,SAAe,gBAAgB,CAC7B,IAAU,EACV,OAAe;;;QAEf,MAAM,WAAW,GAAG,IAAA,cAAK,EAAC,OAAO,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC;QAEpD,MAAM,MAAM,GAAG,IAAA,iCAAwB,EAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAC3D,IAAI,OAAO,GAAoB,OAAO,CAAC,OAAO,CAAC;QAC/C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,QAAQ,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;gBACtC,KAAK,iBAAiB,CAAC;gBACvB,KAAK,uCAAuC;oBAC1C,OAAO,GAAG,UAAU,CAAC;oBACrB,MAAM;gBACR,KAAK,gBAAgB;oBACnB,OAAO,GAAG,MAAM,CAAC;oBACjB,MAAM;gBACR,KAAK,uBAAuB;oBAC1B,OAAO,GAAG,QAAQ,CAAC;oBACnB,MAAM;gBACR,KAAK,qBAAqB;oBACxB,OAAO;wBACL,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC;oBACvE,MAAM;YACV,CAAC;QACH,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,IAAA,2BAAoB,EAAC,IAAI,kCACvC,OAAO,KACV,GAAG,EAAE,MAAC,OAAO,CAAC,GAA+B,mCAAI,KAAK,IACtD,CAAC;QAEH,uCACK,OAAO,KACV,OAAO;YACP,IAAI;YACJ,WAAW,IACX;IACJ,CAAC;CAAA;AAED,SAAS,gBAAgB,CAAC,IAAU,EAAE,OAAyB;;IAC7D,MAAM,eAAe,iDAChB,OAAO,GACP,OAAO,CAAC,IAAI,KACf,mBAAmB,EAAE,IAAA,2BAAe,GAAE,EACtC,QAAQ,EAAE,MAAA,OAAO,CAAC,QAAQ,mCAAI,MAAM,EACpC,OAAO,EAAE,IAAI,EACb,cAAc,EAAE,OAAO,CAAC,cAAc,EACtC,IAAI,EAAE,EAAE,GACT,CAAC;IACF,IAAA,sBAAa,EACX,IAAI,EACJ,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,iBAAiB,OAAO,CAAC,OAAO,QAAQ,CAAC,EAC9D,gBAAgB,OAAO,CAAC,WAAW,EAAE,EACrC,eAAe,CAChB,CAAC;AACJ,CAAC;AAED,SAAS,gBAAgB,CAAC,IAAU,EAAE,OAAyB;IAC7D,IAAI,CAAC,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,QAAQ,KAAK,MAAM;QAAE,OAAO;IAC7D,IAAA,sBAAa,EACX,IAAI,EACJ,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,gBAAgB,CAAC,EACtC,sBAAsB,EACtB,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,EAAE,EAAE,CACzC,CAAC;AACJ,CAAC;AAED,SAAS,gBAAgB,CAAC,IAAU,EAAE,OAAyB;IAC7D,MAAM,MAAM,GAAG,IAAA,iCAAwB,EAAC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/D,MAAM,EAAE,WAAW,EAAE,cAAc,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;IAE1D,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,IAAI,QAAQ,KAAK,UAAU,EAAE,CAAC;QAC5B,QAAQ,CAAC,IAAI,CACX,2CAA2C,cAAc,kBAAkB;YACzE,kDAAkD;YAClD,oFAAoF;YACpF,MAAM,cAAc,EAAE,CACzB,CAAC;QACF,QAAQ,CAAC,IAAI,CACX,0DAA0D,cAAc,EAAE,CAC3E,CAAC;IACJ,CAAC;SAAM,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QAChC,QAAQ,CAAC,IAAI,CACX,0CAA0C,cAAc,kBAAkB;YACxE,iDAAiD;YACjD,iFAAiF;YACjF,MAAM,cAAc,EAAE,CACzB,CAAC;QACF,QAAQ,CAAC,IAAI,CACX,yDAAyD,cAAc,EAAE,CAC1E,CAAC;IACJ,CAAC;IAED,QAAQ,CAAC,IAAI,CACX,4BAA4B,WAAW,IAAI,WAAW,mBAAmB,cAAc,kBAAkB,CAC1G,CAAC;IAEF,QAAQ,CAAC,IAAI,CACX;QACE,8BAA8B;QAC9B,yDAAyD;QACzD,mEAAmE;QACnE,qCAAqC,cAAc,IAAI,WAAW,0BAA0B,WAAW,eAAe;QACtH,iCAAiC,cAAc,IAAI,WAAW,UAAU;KACzE,CAAC,IAAI,CAAC,MAAM,CAAC,CACf,CAAC;IAEF,QAAQ,CAAC,IAAI,CACX,iCAAiC,WAAW,OAAO,cAAc,EAAE,CACpE,CAAC;IACF,QAAQ,CAAC,IAAI,CACX,gCAAgC,WAAW,OAAO,cAAc,iBAAiB,CAClF,CAAC;IAEF,MAAM,CAAC,OAAO,mCACT,MAAM,CAAC,OAAO,KACjB,OAAO,EAAE;YACP,QAAQ,EAAE,iBAAiB;YAC3B,OAAO,EAAE;gBACP,QAAQ;gBACR,UAAU,EAAE,IAAI;aACjB;SACF,GACF,CAAC;IAEF,IAAA,mCAA0B,EAAC,IAAI,EAAE,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;AAC5D,CAAC;AAED,mBAA+B,IAAU,EAAE,OAAe;;QACxD,MAAM,iBAAiB,GAAG,MAAM,gBAAgB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAChE,IAAI,CAAC,iBAAiB,CAAC,OAAO,EAAE,CAAC;YAC/B,OAAO,CAAC,GAAG,CAAC,8DAA8D,CAAC,CAAC;YAC5E,OAAO;QACT,CAAC;QAED,gBAAgB,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC;QAC1C,gBAAgB,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC;QAC1C,gBAAgB,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC;QAC1C,MAAM,IAAA,oBAAW,EAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;CAAA"}
1
+ {"version":3,"file":"sandbox.js","sourceRoot":"","sources":["../../../../../../packages/nx-oc/src/generators/sandbox/sandbox.ts"],"names":[],"mappings":";;AA6KA,4BAYC;;AAzLD,uCAOoB;AACpB,6BAA6B;AAC7B,qCAAkD;AAClD,qDAAwD;AACxD,mDAAiF;AAGjF,SAAe,gBAAgB,CAC7B,IAAU,EACV,OAAe;;;QAEf,MAAM,WAAW,GAAG,IAAA,cAAK,EAAC,OAAO,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC;QAEpD,MAAM,MAAM,GAAG,IAAA,iCAAwB,EAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAC3D,MAAM,OAAO,GAAG,MAAA,OAAO,CAAC,OAAO,mCAAI,IAAA,gCAAqB,EAAC,MAAM,CAAC,CAAC;QAEjE,MAAM,IAAI,GAAG,MAAM,IAAA,2BAAoB,EAAC,IAAI,kCACvC,OAAO,KACV,GAAG,EAAE,MAAC,OAAO,CAAC,GAA+B,mCAAI,KAAK,IACtD,CAAC;QAEH,uCACK,OAAO,KACV,OAAO;YACP,IAAI;YACJ,WAAW,EACX,eAAe,EAAE,IAAA,6BAAkB,EAAC,MAAM,CAAC,IAC3C;IACJ,CAAC;CAAA;AAED,SAAS,gBAAgB,CAAC,IAAU,EAAE,OAAyB;;IAC7D,MAAM,eAAe,iDAChB,OAAO,GACP,OAAO,CAAC,IAAI,KACf,mBAAmB,EAAE,IAAA,2BAAe,GAAE,EACtC,QAAQ,EAAE,MAAA,OAAO,CAAC,QAAQ,mCAAI,MAAM,EACpC,OAAO,EAAE,IAAI,EACb,cAAc,EAAE,OAAO,CAAC,cAAc,EACtC,IAAI,EAAE,EAAE,GACT,CAAC;IACF,IAAA,sBAAa,EACX,IAAI,EACJ,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,iBAAiB,OAAO,CAAC,OAAO,QAAQ,CAAC,EAC9D,gBAAgB,OAAO,CAAC,WAAW,EAAE,EACrC,eAAe,CAChB,CAAC;AACJ,CAAC;AAED,SAAS,gBAAgB,CAAC,IAAU,EAAE,OAAyB;IAC7D,IAAI,CAAC,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,QAAQ,KAAK,MAAM;QAAE,OAAO;IAC7D,IAAA,sBAAa,EACX,IAAI,EACJ,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,gBAAgB,CAAC,EACtC,sBAAsB,EACtB,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,EAAE,EAAE,CACzC,CAAC;AACJ,CAAC;AAED,6EAA6E;AAC7E,6EAA6E;AAC7E,8EAA8E;AAC9E,2BAA2B;AAC3B,SAAS,aAAa,CAAC,IAAU,EAAE,OAAyB;IAC1D,IAAA,sBAAa,EAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC,EAAE,cAAc,EAAE;QACvE,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,IAAI,EAAE,EAAE;KACT,CAAC,CAAC;AACL,CAAC;AAED,SAAS,gBAAgB,CAAC,IAAU,EAAE,OAAyB;;IAC7D,MAAM,MAAM,GAAG,IAAA,iCAAwB,EAAC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/D,MAAM,EAAE,WAAW,EAAE,cAAc,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;IAE1D,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,IAAI,QAAQ,KAAK,UAAU,EAAE,CAAC;QAC5B,QAAQ,CAAC,IAAI,CACX,2CAA2C,cAAc,kBAAkB;YACzE,kDAAkD;YAClD,oFAAoF;YACpF,MAAM,cAAc,EAAE,CACzB,CAAC;QACF,QAAQ,CAAC,IAAI,CACX,0DAA0D,cAAc,EAAE,CAC3E,CAAC;IACJ,CAAC;SAAM,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QAChC,QAAQ,CAAC,IAAI,CACX,0CAA0C,cAAc,kBAAkB;YACxE,iDAAiD;YACjD,iFAAiF;YACjF,MAAM,cAAc,EAAE,CACzB,CAAC;QACF,QAAQ,CAAC,IAAI,CACX,yDAAyD,cAAc,EAAE,CAC1E,CAAC;IACJ,CAAC;IAED,0EAA0E;IAC1E,4EAA4E;IAC5E,2EAA2E;IAC3E,wEAAwE;IACxE,2EAA2E;IAC3E,8EAA8E;IAC9E,oEAAoE;IACpE,MAAM,MAAM,GAAG,qBAAqB,CAAC;IACrC,MAAM,aAAa,GAAG,CAAC,MAAA,MAAM,CAAC,IAAI,mCAAI,EAAE,CAAC;SACtC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;SACvC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QACX,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACvC,MAAM,SAAS,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QACzC,OAAO;YACL,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC;YAC/B,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC;SACjC,CAAC;IACJ,CAAC,CAAC,CAAC;IACL,KAAK,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,aAAa,EAAE,CAAC;QAC3C,QAAQ,CAAC,IAAI,CACX,kBAAkB,IAAI,OAAO,cAAc,sBAAsB;YAC/D,+BAA+B,IAAI,UAAU,IAAI,IAAI,IAAI,OAAO,cAAc,EAAE,CACnF,CAAC;IACJ,CAAC;IAED,0EAA0E;IAC1E,QAAQ,CAAC,IAAI,CACX,0BAA0B,WAAW,yBAAyB,cAAc,EAAE,CAC/E,CAAC;IACF,2EAA2E;IAC3E,2EAA2E;IAC3E,QAAQ,CAAC,IAAI,CAAC,gBAAgB,WAAW,6BAA6B,CAAC,CAAC;IACxE,QAAQ,CAAC,IAAI,CACX,kBAAkB,WAAW,oCAAoC,cAAc,EAAE,CAClF,CAAC;IAEF,QAAQ,CAAC,IAAI,CACX,4BAA4B,WAAW,IAAI,WAAW,mBAAmB,cAAc,kBAAkB,CAC1G,CAAC;IAEF,QAAQ,CAAC,IAAI,CACX,iCAAiC,WAAW,OAAO,cAAc,EAAE,CACpE,CAAC;IACF,QAAQ,CAAC,IAAI,CACX,gCAAgC,WAAW,OAAO,cAAc,iBAAiB,CAClF,CAAC;IAEF,MAAM,CAAC,OAAO,mCACT,MAAM,CAAC,OAAO,KACjB,OAAO,EAAE;YACP,QAAQ,EAAE,iBAAiB;YAC3B,OAAO,EAAE;gBACP,QAAQ;gBACR,QAAQ,EAAE,KAAK;aAChB;SACF,EACD,kBAAkB,EAAE;YAClB,QAAQ,EAAE,iBAAiB;YAC3B,OAAO,EAAE;gBACP,QAAQ,EAAE;oBACR,wCAAwC,WAAW,OAAO,cAAc,qBAAqB;iBAC9F;aACF;SACF,GACF,CAAC;IAEF,IAAA,mCAA0B,EAAC,IAAI,EAAE,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;AAC5D,CAAC;AAED,mBAA+B,IAAU,EAAE,OAAe;;QACxD,MAAM,iBAAiB,GAAG,MAAM,gBAAgB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAChE,IAAI,CAAC,iBAAiB,CAAC,OAAO,EAAE,CAAC;YAC/B,OAAO,CAAC,GAAG,CAAC,8DAA8D,CAAC,CAAC;YAC5E,OAAO;QACT,CAAC;QAED,gBAAgB,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC;QAC1C,aAAa,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC;QACvC,gBAAgB,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC;QAC1C,gBAAgB,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC;QAC1C,MAAM,IAAA,oBAAW,EAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;CAAA"}
@@ -36,10 +36,11 @@ describe('Sandbox Generator', () => {
36
36
  });
37
37
  }
38
38
 
39
- function addFrontendProject(host) {
39
+ function addFrontendProject(host, tags?: string[]) {
40
40
  addProjectConfiguration(host, 'test', {
41
41
  root: 'apps/test',
42
42
  projectType: 'application',
43
+ tags,
43
44
  targets: {
44
45
  build: {
45
46
  executor: '@nx/webpack:webpack',
@@ -84,10 +85,43 @@ describe('Sandbox Generator', () => {
84
85
  const config = readProjectConfiguration(host, 'test');
85
86
  expect(config.targets['sandbox']).toBeTruthy();
86
87
  expect(config.targets['sandbox'].executor).toBe('nx:run-commands');
88
+ // Commands run in order (nx:run-commands has no `sequential` option).
89
+ expect(config.targets['sandbox'].options.parallel).toBe(false);
87
90
  const cmds: string[] = config.targets['sandbox'].options.commands;
88
91
  expect(cmds.some((c) => c.includes('oc rollout restart'))).toBeTruthy();
89
92
  expect(cmds.some((c) => c.includes('oc rollout status'))).toBeTruthy();
90
- expect(cmds.some((c) => c.includes('command -v podman'))).toBeTruthy();
93
+ // In-cluster binary build (no local podman / external registry route).
94
+ expect(cmds.some((c) => c.includes('nx build test'))).toBeTruthy();
95
+ expect(
96
+ cmds.some((c) => c.includes('oc start-build test --from-dir=.'))
97
+ ).toBeTruthy();
98
+ expect(cmds.some((c) => c.includes('sandbox-build.yml'))).toBeTruthy();
99
+ expect(cmds.some((c) => c.includes('podman'))).toBeFalsy();
100
+
101
+ // The ImageStream + BuildConfig manifest is generated.
102
+ expect(host.exists('.openshift/test/sandbox-build.yml')).toBeTruthy();
103
+ const buildManifest = host
104
+ .read('.openshift/test/sandbox-build.yml')
105
+ .toString();
106
+ expect(buildManifest).toContain('kind: BuildConfig');
107
+ expect(buildManifest).toContain('kind: ImageStream');
108
+ expect(buildManifest).toContain('test:sandbox');
109
+ });
110
+
111
+ it('adds sandbox-teardown nx target', async () => {
112
+ const host = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
113
+ addNodeProject(host);
114
+
115
+ await generator(host, options);
116
+
117
+ const config = readProjectConfiguration(host, 'test');
118
+ expect(config.targets['sandbox-teardown']).toBeTruthy();
119
+ const cmds: string[] = config.targets['sandbox-teardown'].options.commands;
120
+ expect(cmds.some((c) => c.includes('oc delete'))).toBeTruthy();
121
+ expect(cmds.some((c) => c.includes('--ignore-not-found'))).toBeTruthy();
122
+ expect(cmds.some((c) => c.includes('test-sandbox'))).toBeTruthy();
123
+ expect(cmds.some((c) => c.includes('-l app=test'))).toBeTruthy();
124
+ expect(cmds.some((c) => c.includes('all,configmap'))).toBeTruthy();
91
125
  });
92
126
 
93
127
  it('generates shared postgres manifest with secret-backed DATABASE_URL', async () => {
@@ -130,4 +164,34 @@ describe('Sandbox Generator', () => {
130
164
  const cmds: string[] = config.targets['sandbox'].options.commands;
131
165
  expect(cmds.some((c) => c.includes('sandbox-mongodb-creds'))).toBeTruthy();
132
166
  });
167
+
168
+ it('ensures paired backend Services from proxy-service tags', async () => {
169
+ const host = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
170
+ addFrontendProject(host, ['adsp:proxy-service:test-service:3333']);
171
+
172
+ await generator(host, options);
173
+
174
+ const config = readProjectConfiguration(host, 'test');
175
+ const cmds: string[] = config.targets['sandbox'].options.commands;
176
+ const guard = cmds.find((c) => c.includes('oc get service test-service'));
177
+ expect(guard).toBeTruthy();
178
+ // idempotent: only creates the Service (for DNS) when it's missing — no
179
+ // backend deployment, which would have no image until its own sandbox runs.
180
+ expect(guard).toContain('||');
181
+ expect(guard).toContain(
182
+ 'oc create service clusterip test-service --tcp=3333:3333'
183
+ );
184
+ expect(guard).not.toContain('test-service.yml');
185
+ });
186
+
187
+ it('adds no paired-service guard when there are no proxy-service tags', async () => {
188
+ const host = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
189
+ addNodeProject(host);
190
+
191
+ await generator(host, options);
192
+
193
+ const config = readProjectConfiguration(host, 'test');
194
+ const cmds: string[] = config.targets['sandbox'].options.commands;
195
+ expect(cmds.some((c) => c.includes('oc get service'))).toBeFalsy();
196
+ });
133
197
  });
@@ -9,10 +9,13 @@ export interface Schema {
9
9
  env?: string;
10
10
  adsp?: AdspConfiguration;
11
11
  accessToken?: string;
12
+ tenant?: string;
13
+ tenantRealm?: string;
12
14
  }
13
15
 
14
16
  export interface NormalizedSchema extends Schema {
15
17
  projectName: string;
16
18
  appType: ApplicationType;
17
19
  adsp: AdspConfiguration;
20
+ buildOutputPath: string;
18
21
  }
@@ -43,6 +43,14 @@
43
43
  "type": "string",
44
44
  "description": "Access token for retrieving configuration from ADSP APIs.",
45
45
  "alias": "at"
46
+ },
47
+ "tenant": {
48
+ "type": "string",
49
+ "description": "ADSP tenant name. Looks up the realm and does a single login, skipping the interactive tenant picker."
50
+ },
51
+ "tenantRealm": {
52
+ "type": "string",
53
+ "description": "Keycloak realm UUID. Optional when --tenant is provided; overrides the realm looked up from the tenant service."
46
54
  }
47
55
  },
48
56
  "required": ["project", "sandboxProject"],
@@ -0,0 +1,10 @@
1
+ export interface Schema {
2
+ project: string;
3
+ env: 'dev' | 'test' | 'prod';
4
+ }
5
+
6
+ export interface NormalizedSchema extends Schema {
7
+ projectName: string;
8
+ envProject: string;
9
+ ocInfraProject: string;
10
+ }
@@ -0,0 +1,33 @@
1
+ {
2
+ "$schema": "http://json-schema.org/schema",
3
+ "id": "NxOcTeardown",
4
+ "title": "OpenShift Environment Teardown",
5
+ "type": "object",
6
+ "properties": {
7
+ "project": {
8
+ "type": "string",
9
+ "description": "Project to add teardown target for.",
10
+ "$default": {
11
+ "$source": "argv",
12
+ "index": 0
13
+ },
14
+ "x-prompt": "Which project to add teardown for?"
15
+ },
16
+ "env": {
17
+ "type": "string",
18
+ "description": "Environment to target for teardown.",
19
+ "$default": {
20
+ "$source": "argv",
21
+ "index": 1
22
+ },
23
+ "alias": "e",
24
+ "x-prompt": {
25
+ "message": "Which environment to target?",
26
+ "type": "list",
27
+ "items": ["dev", "test", "prod"]
28
+ }
29
+ }
30
+ },
31
+ "required": ["project", "env"],
32
+ "additionalProperties": false
33
+ }
@@ -0,0 +1,3 @@
1
+ import { Tree } from '@nx/devkit';
2
+ import { Schema } from './schema';
3
+ export default function (host: Tree, options: Schema): Promise<void>;
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = default_1;
4
+ const tslib_1 = require("tslib");
5
+ const devkit_1 = require("@nx/devkit");
6
+ const yaml = require("yaml");
7
+ const pipeline_envs_1 = require("../../pipeline-envs");
8
+ const infraManifestFile = '.openshift/environments.yml';
9
+ function normalizeOptions(host, options) {
10
+ var _a, _b, _c, _d;
11
+ const projectName = (0, devkit_1.names)(options.project).fileName;
12
+ const result = host.read(infraManifestFile).toString();
13
+ const { items } = yaml.parse(result);
14
+ const ocInfraProject = ((_b = (_a = items[0]) === null || _a === void 0 ? void 0 : _a.metadata) === null || _b === void 0 ? void 0 : _b.namespace) || '';
15
+ const SA_PREFIX = 'system:serviceaccounts:';
16
+ const ocEnvProjects = (_d = (_c = items[0]) === null || _c === void 0 ? void 0 : _c.subjects) === null || _d === void 0 ? void 0 : _d.filter((s) => s.kind === 'Group' && s.name.startsWith(SA_PREFIX)).map((s) => s.name.replace(SA_PREFIX, ''));
17
+ const envIndex = pipeline_envs_1.pipelineEnvs.map((e) => e.toLowerCase()).indexOf(options.env.toLowerCase());
18
+ const envProject = (ocEnvProjects === null || ocEnvProjects === void 0 ? void 0 : ocEnvProjects[envIndex]) || '';
19
+ return Object.assign(Object.assign({}, options), { projectName,
20
+ ocInfraProject,
21
+ envProject });
22
+ }
23
+ function default_1(host, options) {
24
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
25
+ if (!host.exists(infraManifestFile)) {
26
+ console.log(`Cannot generate teardown; run 'nx g @abgov/nx-oc:pipeline' first.`);
27
+ return;
28
+ }
29
+ const normalizedOptions = normalizeOptions(host, options);
30
+ if (!normalizedOptions.envProject) {
31
+ console.log(`Cannot find project for environment '${options.env}'.`);
32
+ return;
33
+ }
34
+ const config = (0, devkit_1.readProjectConfiguration)(host, options.project);
35
+ const { projectName, envProject } = normalizedOptions;
36
+ config.targets = Object.assign(Object.assign({}, config.targets), { [`teardown-${options.env}`]: {
37
+ executor: 'nx:run-commands',
38
+ options: {
39
+ commands: [
40
+ `oc delete all,configmap -l app=${projectName} -n ${envProject} --ignore-not-found`,
41
+ ],
42
+ },
43
+ } });
44
+ (0, devkit_1.updateProjectConfiguration)(host, options.project, config);
45
+ yield (0, devkit_1.formatFiles)(host);
46
+ });
47
+ }
48
+ //# sourceMappingURL=teardown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"teardown.js","sourceRoot":"","sources":["../../../../../../packages/nx-oc/src/generators/teardown/teardown.ts"],"names":[],"mappings":";;AAoCA,4BA6BC;;AAjED,uCAMoB;AACpB,6BAA6B;AAC7B,uDAA2D;AAG3D,MAAM,iBAAiB,GAAG,6BAA6B,CAAC;AAExD,SAAS,gBAAgB,CAAC,IAAU,EAAE,OAAe;;IACnD,MAAM,WAAW,GAAG,IAAA,cAAK,EAAC,OAAO,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC;IAEpD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,QAAQ,EAAE,CAAC;IACvD,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACrC,MAAM,cAAc,GAAG,CAAA,MAAA,MAAA,KAAK,CAAC,CAAC,CAAC,0CAAE,QAAQ,0CAAE,SAAS,KAAI,EAAE,CAAC;IAE3D,MAAM,SAAS,GAAG,yBAAyB,CAAC;IAC5C,MAAM,aAAa,GAAa,MAAA,MAAA,KAAK,CAAC,CAAC,CAAC,0CAAE,QAAQ,0CAC9C,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EACjE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,CAAC;IAE7C,MAAM,QAAQ,GAAG,4BAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;IACrF,MAAM,UAAU,GAAG,CAAA,aAAa,aAAb,aAAa,uBAAb,aAAa,CAAG,QAAQ,CAAC,KAAI,EAAE,CAAC;IAEnD,uCACK,OAAO,KACV,WAAW;QACX,cAAc;QACd,UAAU,IACV;AACJ,CAAC;AAED,mBAA+B,IAAU,EAAE,OAAe;;QACxD,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,EAAE,CAAC;YACpC,OAAO,CAAC,GAAG,CAAC,mEAAmE,CAAC,CAAC;YACjF,OAAO;QACT,CAAC;QAED,MAAM,iBAAiB,GAAG,gBAAgB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC1D,IAAI,CAAC,iBAAiB,CAAC,UAAU,EAAE,CAAC;YAClC,OAAO,CAAC,GAAG,CAAC,wCAAwC,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;YACrE,OAAO;QACT,CAAC;QAED,MAAM,MAAM,GAAG,IAAA,iCAAwB,EAAC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;QAC/D,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,iBAAiB,CAAC;QAEtD,MAAM,CAAC,OAAO,mCACT,MAAM,CAAC,OAAO,KACjB,CAAC,YAAY,OAAO,CAAC,GAAG,EAAE,CAAC,EAAE;gBAC3B,QAAQ,EAAE,iBAAiB;gBAC3B,OAAO,EAAE;oBACP,QAAQ,EAAE;wBACR,kCAAkC,WAAW,OAAO,UAAU,qBAAqB;qBACpF;iBACF;aACF,GACF,CAAC;QAEF,IAAA,mCAA0B,EAAC,IAAI,EAAE,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC1D,MAAM,IAAA,oBAAW,EAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;CAAA"}
@@ -0,0 +1,100 @@
1
+ import {
2
+ addProjectConfiguration,
3
+ readProjectConfiguration,
4
+ } from '@nx/devkit';
5
+ import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
6
+ import pipeline from '../pipeline/pipeline';
7
+ import generator from './teardown';
8
+ import { Schema } from './schema';
9
+
10
+ describe('Teardown Generator', () => {
11
+ const options: Schema = {
12
+ project: 'test',
13
+ env: 'dev',
14
+ };
15
+
16
+ async function setup(host, envs = 'test-dev test-test test-prod') {
17
+ await pipeline(host, {
18
+ pipeline: 'test',
19
+ registry: 'ghcr.io/test-org',
20
+ type: 'jenkins',
21
+ infra: 'test-infra',
22
+ envs,
23
+ });
24
+ addProjectConfiguration(host, 'test', {
25
+ root: 'apps/test',
26
+ projectType: 'application',
27
+ targets: {
28
+ build: { executor: '@nx/webpack:webpack', options: { compiler: 'tsc', target: 'node' } },
29
+ },
30
+ });
31
+ }
32
+
33
+ it('adds teardown-dev target for dev environment', async () => {
34
+ const host = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
35
+ await setup(host);
36
+
37
+ await generator(host, options);
38
+
39
+ const config = readProjectConfiguration(host, 'test');
40
+ expect(config.targets['teardown-dev']).toBeTruthy();
41
+ const cmds: string[] = config.targets['teardown-dev'].options.commands;
42
+ expect(cmds.some((c) => c.includes('oc delete'))).toBeTruthy();
43
+ expect(cmds.some((c) => c.includes('test-dev'))).toBeTruthy();
44
+ expect(cmds.some((c) => c.includes('--ignore-not-found'))).toBeTruthy();
45
+ });
46
+
47
+ it('adds teardown-prod target for prod environment', async () => {
48
+ const host = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
49
+ await setup(host);
50
+
51
+ await generator(host, { ...options, env: 'prod' });
52
+
53
+ const config = readProjectConfiguration(host, 'test');
54
+ expect(config.targets['teardown-prod']).toBeTruthy();
55
+ const cmds: string[] = config.targets['teardown-prod'].options.commands;
56
+ expect(cmds.some((c) => c.includes('test-prod'))).toBeTruthy();
57
+ });
58
+
59
+ it('teardown targets for multiple environments are additive', async () => {
60
+ const host = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
61
+ await setup(host);
62
+
63
+ await generator(host, { ...options, env: 'dev' });
64
+ await generator(host, { ...options, env: 'test' });
65
+ await generator(host, { ...options, env: 'prod' });
66
+
67
+ const config = readProjectConfiguration(host, 'test');
68
+ expect(config.targets['teardown-dev']).toBeTruthy();
69
+ expect(config.targets['teardown-test']).toBeTruthy();
70
+ expect(config.targets['teardown-prod']).toBeTruthy();
71
+ });
72
+
73
+ it('skips gracefully when environments.yml does not exist', async () => {
74
+ const host = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
75
+ addProjectConfiguration(host, 'test', {
76
+ root: 'apps/test',
77
+ projectType: 'application',
78
+ targets: {
79
+ build: { executor: '@nx/webpack:webpack', options: { compiler: 'tsc', target: 'node' } },
80
+ },
81
+ });
82
+
83
+ await generator(host, options);
84
+
85
+ const config = readProjectConfiguration(host, 'test');
86
+ expect(config.targets['teardown-dev']).toBeFalsy();
87
+ });
88
+
89
+ it('uses label selector with project name in delete command', async () => {
90
+ const host = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
91
+ await setup(host);
92
+
93
+ await generator(host, options);
94
+
95
+ const config = readProjectConfiguration(host, 'test');
96
+ const cmds: string[] = config.targets['teardown-dev'].options.commands;
97
+ expect(cmds.some((c) => c.includes('-l app=test'))).toBeTruthy();
98
+ expect(cmds.some((c) => c.includes('all,configmap'))).toBeTruthy();
99
+ });
100
+ });
@@ -0,0 +1,18 @@
1
+ import { ProjectConfiguration } from '@nx/devkit';
2
+ import { ApplicationType } from '../generators/deployment/schema';
3
+ /**
4
+ * Detect the application type from the project's build executor.
5
+ *
6
+ * Shared by the deployment and sandbox generators so they stay in sync as new
7
+ * Nx build executors appear (e.g. Vite/Rspack for frontends).
8
+ */
9
+ export declare function detectApplicationType(config: ProjectConfiguration): ApplicationType | undefined;
10
+ /**
11
+ * The build output directory for a project, relative to the workspace root.
12
+ *
13
+ * Read from the project's `build` target so the generated Dockerfile mirrors
14
+ * the workspace's actual layout (e.g. `dist/apps/<project>` or
15
+ * `packages/<project>/dist`) instead of assuming a fixed path. Falls back to
16
+ * `dist/<projectRoot>`, the Nx default, when the target declares no outputPath.
17
+ */
18
+ export declare function getBuildOutputPath(config: ProjectConfiguration): string;
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.detectApplicationType = detectApplicationType;
4
+ exports.getBuildOutputPath = getBuildOutputPath;
5
+ /**
6
+ * Detect the application type from the project's build executor.
7
+ *
8
+ * Shared by the deployment and sandbox generators so they stay in sync as new
9
+ * Nx build executors appear (e.g. Vite/Rspack for frontends).
10
+ */
11
+ function detectApplicationType(config) {
12
+ var _a, _b;
13
+ const build = (_a = config.targets) === null || _a === void 0 ? void 0 : _a.build;
14
+ switch (build === null || build === void 0 ? void 0 : build.executor) {
15
+ case '@nx/web:webpack':
16
+ case '@angular-devkit/build-angular:browser':
17
+ case '@nx/vite:build':
18
+ case '@nx/rspack:rspack':
19
+ return 'frontend';
20
+ case '@nx/node:build':
21
+ return 'node';
22
+ case '@nx-dotnet/core:build':
23
+ return 'dotnet';
24
+ case '@nx/webpack:webpack':
25
+ // The generic webpack executor builds both node and browser apps.
26
+ return ((_b = build.options) === null || _b === void 0 ? void 0 : _b.target) === 'node' ? 'node' : 'frontend';
27
+ default:
28
+ return undefined;
29
+ }
30
+ }
31
+ /**
32
+ * The build output directory for a project, relative to the workspace root.
33
+ *
34
+ * Read from the project's `build` target so the generated Dockerfile mirrors
35
+ * the workspace's actual layout (e.g. `dist/apps/<project>` or
36
+ * `packages/<project>/dist`) instead of assuming a fixed path. Falls back to
37
+ * `dist/<projectRoot>`, the Nx default, when the target declares no outputPath.
38
+ */
39
+ function getBuildOutputPath(config) {
40
+ var _a, _b, _c, _d;
41
+ return (_d = (_c = (_b = (_a = config.targets) === null || _a === void 0 ? void 0 : _a.build) === null || _b === void 0 ? void 0 : _b.options) === null || _c === void 0 ? void 0 : _c.outputPath) !== null && _d !== void 0 ? _d : `dist/${config.root}`;
42
+ }
43
+ //# sourceMappingURL=app-type.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-type.js","sourceRoot":"","sources":["../../../../../packages/nx-oc/src/utils/app-type.ts"],"names":[],"mappings":";;AASA,sDAoBC;AAUD,gDAEC;AAtCD;;;;;GAKG;AACH,SAAgB,qBAAqB,CACnC,MAA4B;;IAE5B,MAAM,KAAK,GAAG,MAAA,MAAM,CAAC,OAAO,0CAAE,KAAK,CAAC;IACpC,QAAQ,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,QAAQ,EAAE,CAAC;QACxB,KAAK,iBAAiB,CAAC;QACvB,KAAK,uCAAuC,CAAC;QAC7C,KAAK,gBAAgB,CAAC;QACtB,KAAK,mBAAmB;YACtB,OAAO,UAAU,CAAC;QACpB,KAAK,gBAAgB;YACnB,OAAO,MAAM,CAAC;QAChB,KAAK,uBAAuB;YAC1B,OAAO,QAAQ,CAAC;QAClB,KAAK,qBAAqB;YACxB,kEAAkE;YAClE,OAAO,CAAA,MAAA,KAAK,CAAC,OAAO,0CAAE,MAAM,MAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC;QAChE;YACE,OAAO,SAAS,CAAC;IACrB,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,SAAgB,kBAAkB,CAAC,MAA4B;;IAC7D,OAAO,MAAA,MAAA,MAAA,MAAA,MAAM,CAAC,OAAO,0CAAE,KAAK,0CAAE,OAAO,0CAAE,UAAU,mCAAI,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;AAC7E,CAAC"}
@@ -9,8 +9,10 @@ function getGitRemoteUrl() {
9
9
  const stdout = (0, child_process_1.execSync)("git config --get remote.origin.url", { stdio: "pipe" }).toString();
10
10
  return stdout;
11
11
  }
12
- catch (e) {
13
- console.log(`Failed to execute git`, e);
12
+ catch (_a) {
13
+ // No 'origin' remote (e.g. a freshly-created workspace) — not an error;
14
+ // sourceRepositoryUrl is simply left unset.
15
+ return undefined;
14
16
  }
15
17
  }
16
18
  // Parses a GitHub remote URL and returns the ghcr.io registry for the org.
@@ -1 +1 @@
1
- {"version":3,"file":"git-utils.js","sourceRoot":"","sources":["../../../../../packages/nx-oc/src/utils/git-utils.ts"],"names":[],"mappings":";;AAEA,0CAWC;AAKD,4DAOC;AAGD,sCAMC;AAlCD,iDAAwC;AAExC,SAAgB,eAAe;IAC7B,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAA,wBAAQ,EACrB,oCAAoC,EACpC,EAAE,KAAK,EAAE,MAAM,EAAE,CAClB,CAAC,QAAQ,EAAE,CAAA;QAEZ,OAAO,MAAM,CAAA;IACf,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,CAAC,GAAG,CAAC,uBAAuB,EAAE,CAAC,CAAC,CAAA;IACzC,CAAC;AACH,CAAC;AAED,2EAA2E;AAC3E,2DAA2D;AAC3D,6CAA6C;AAC7C,SAAgB,wBAAwB,CAAC,SAAkB;;IACzD,IAAI,CAAC,SAAS;QAAE,OAAO,SAAS,CAAC;IACjC,MAAM,GAAG,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC;IAC7B,MAAM,UAAU,GAAG,GAAG,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;IACjE,MAAM,QAAQ,GAAK,GAAG,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC;IAC1D,MAAM,GAAG,GAAG,MAAA,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAG,CAAC,CAAC,mCAAI,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAG,CAAC,CAAC,CAAC;IAC7C,OAAO,GAAG,CAAC,CAAC,CAAC,WAAW,GAAG,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AAC5C,CAAC;AAED,qEAAqE;AACrE,SAAgB,aAAa,CAAC,SAAkB;;IAC9C,IAAI,CAAC,SAAS;QAAE,OAAO,SAAS,CAAC;IACjC,MAAM,GAAG,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC;IAC7B,MAAM,UAAU,GAAG,GAAG,CAAC,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAC3E,MAAM,QAAQ,GAAK,GAAG,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAC;IACpE,OAAO,MAAA,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAG,CAAC,CAAC,mCAAI,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAG,CAAC,CAAC,CAAC;AAC1C,CAAC"}
1
+ {"version":3,"file":"git-utils.js","sourceRoot":"","sources":["../../../../../packages/nx-oc/src/utils/git-utils.ts"],"names":[],"mappings":";;AAEA,0CAaC;AAKD,4DAOC;AAGD,sCAMC;AApCD,iDAAwC;AAExC,SAAgB,eAAe;IAC7B,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAA,wBAAQ,EACrB,oCAAoC,EACpC,EAAE,KAAK,EAAE,MAAM,EAAE,CAClB,CAAC,QAAQ,EAAE,CAAA;QAEZ,OAAO,MAAM,CAAA;IACf,CAAC;IAAC,WAAM,CAAC;QACP,wEAAwE;QACxE,4CAA4C;QAC5C,OAAO,SAAS,CAAA;IAClB,CAAC;AACH,CAAC;AAED,2EAA2E;AAC3E,2DAA2D;AAC3D,6CAA6C;AAC7C,SAAgB,wBAAwB,CAAC,SAAkB;;IACzD,IAAI,CAAC,SAAS;QAAE,OAAO,SAAS,CAAC;IACjC,MAAM,GAAG,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC;IAC7B,MAAM,UAAU,GAAG,GAAG,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;IACjE,MAAM,QAAQ,GAAK,GAAG,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC;IAC1D,MAAM,GAAG,GAAG,MAAA,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAG,CAAC,CAAC,mCAAI,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAG,CAAC,CAAC,CAAC;IAC7C,OAAO,GAAG,CAAC,CAAC,CAAC,WAAW,GAAG,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AAC5C,CAAC;AAED,qEAAqE;AACrE,SAAgB,aAAa,CAAC,SAAkB;;IAC9C,IAAI,CAAC,SAAS;QAAE,OAAO,SAAS,CAAC;IACjC,MAAM,GAAG,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC;IAC7B,MAAM,UAAU,GAAG,GAAG,CAAC,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAC3E,MAAM,QAAQ,GAAK,GAAG,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAC;IACpE,OAAO,MAAA,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAG,CAAC,CAAC,mCAAI,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAG,CAAC,CAAC,CAAC;AAC1C,CAAC"}