@abgov/nx-oc 13.0.0-beta.1 → 13.0.0-beta.3

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.
Files changed (43) hide show
  1. package/executors.json +5 -0
  2. package/migrations.json +10 -0
  3. package/package.json +4 -1
  4. package/src/adsp/adsp-utils.d.ts +10 -0
  5. package/src/adsp/adsp-utils.js +48 -0
  6. package/src/adsp/adsp-utils.js.map +1 -1
  7. package/src/build-assets.spec.ts +62 -0
  8. package/src/executors/sandbox/sandbox.d.ts +5 -0
  9. package/src/executors/sandbox/sandbox.js +183 -0
  10. package/src/executors/sandbox/sandbox.js.map +1 -0
  11. package/src/executors/sandbox/sandbox.spec.ts +186 -0
  12. package/src/executors/sandbox/schema.d.ts +12 -0
  13. package/src/executors/sandbox/schema.json +50 -0
  14. package/src/generators/deployment/deployment.js +11 -25
  15. package/src/generators/deployment/deployment.js.map +1 -1
  16. package/src/generators/deployment/deployment.spec.ts +5 -2
  17. package/src/generators/deployment/dotnet-files/Dockerfile__tmpl__ +16 -0
  18. package/src/generators/deployment/frontend-files/Dockerfile__tmpl__ +10 -0
  19. package/src/generators/deployment/node-files/Dockerfile__tmpl__ +10 -0
  20. package/src/generators/deployment/node-files/__projectName__.yml__tmpl__ +12 -1
  21. package/src/generators/deployment/schema.d.ts +1 -0
  22. package/src/generators/sandbox/database-files/sandbox-postgres.yml__tmpl__ +3 -1
  23. package/src/generators/sandbox/files/SANDBOX.md__tmpl__ +91 -0
  24. package/src/generators/sandbox/sandbox.js +109 -56
  25. package/src/generators/sandbox/sandbox.js.map +1 -1
  26. package/src/generators/sandbox/sandbox.spec.ts +110 -13
  27. package/src/generators/sandbox/schema.d.ts +10 -0
  28. package/src/generators/sandbox/schema.json +13 -0
  29. package/src/migrations/convert-sandbox-target/convert-sandbox-target.d.ts +2 -0
  30. package/src/migrations/convert-sandbox-target/convert-sandbox-target.js +54 -0
  31. package/src/migrations/convert-sandbox-target/convert-sandbox-target.js.map +1 -0
  32. package/src/migrations/convert-sandbox-target/convert-sandbox-target.spec.ts +111 -0
  33. package/src/utils/app-type.d.ts +18 -0
  34. package/src/utils/app-type.js +43 -0
  35. package/src/utils/app-type.js.map +1 -0
  36. package/src/utils/git-utils.js +4 -2
  37. package/src/utils/git-utils.js.map +1 -1
  38. package/src/utils/oc-utils.d.ts +1 -0
  39. package/src/utils/oc-utils.js +21 -0
  40. package/src/utils/oc-utils.js.map +1 -1
  41. package/src/generators/deployment/dotnet-files/Dockerfile.template +0 -10
  42. package/src/generators/deployment/frontend-files/Dockerfile.template +0 -8
  43. package/src/generators/deployment/node-files/Dockerfile.template +0 -8
@@ -1,5 +1,6 @@
1
1
  import {
2
2
  addProjectConfiguration,
3
+ readNxJson,
3
4
  readProjectConfiguration,
4
5
  } from '@nx/devkit';
5
6
  import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
@@ -9,18 +10,24 @@ import generator from './sandbox';
9
10
  import { Schema } from './schema';
10
11
 
11
12
  jest.mock('../../adsp');
13
+ jest.mock('../../utils/oc-utils', () => ({
14
+ ...jest.requireActual('../../utils/oc-utils'),
15
+ getClusterIngressDomain: jest.fn(() => 'apps.test.example.com'),
16
+ }));
12
17
  const utilsMock = utils as jest.Mocked<typeof utils>;
13
18
  utilsMock.getAdspConfiguration.mockResolvedValue({
14
19
  tenant: 'test',
15
20
  tenantRealm: 'test',
16
21
  accessServiceUrl: environments.test.accessServiceUrl,
17
22
  directoryServiceUrl: environments.test.directoryServiceUrl,
23
+ accessToken: 'mock-token',
18
24
  });
19
25
 
20
26
  describe('Sandbox Generator', () => {
21
27
  const options: Schema = {
22
28
  project: 'test',
23
29
  sandboxProject: 'test-sandbox',
30
+ registry: 'ghcr.io/test-org',
24
31
  };
25
32
 
26
33
  function addNodeProject(host) {
@@ -36,10 +43,11 @@ describe('Sandbox Generator', () => {
36
43
  });
37
44
  }
38
45
 
39
- function addFrontendProject(host) {
46
+ function addFrontendProject(host, tags?: string[]) {
40
47
  addProjectConfiguration(host, 'test', {
41
48
  root: 'apps/test',
42
49
  projectType: 'application',
50
+ tags,
43
51
  targets: {
44
52
  build: {
45
53
  executor: '@nx/webpack:webpack',
@@ -75,19 +83,75 @@ describe('Sandbox Generator', () => {
75
83
  expect(manifest).not.toContain('ImageStream');
76
84
  });
77
85
 
78
- it('adds sandbox nx target', async () => {
86
+ it('adds a sandbox target wired to the @abgov/nx-oc:sandbox executor', async () => {
79
87
  const host = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
80
88
  addNodeProject(host);
81
89
 
82
90
  await generator(host, options);
83
91
 
84
92
  const config = readProjectConfiguration(host, 'test');
85
- expect(config.targets['sandbox']).toBeTruthy();
86
- expect(config.targets['sandbox'].executor).toBe('nx:run-commands');
87
- const cmds: string[] = config.targets['sandbox'].options.commands;
88
- expect(cmds.some((c) => c.includes('oc rollout restart'))).toBeTruthy();
89
- expect(cmds.some((c) => c.includes('oc rollout status'))).toBeTruthy();
90
- expect(cmds.some((c) => c.includes('command -v podman'))).toBeTruthy();
93
+ const target = config.targets['sandbox'];
94
+ expect(target).toBeTruthy();
95
+ // Deploy orchestration lives in the executor (versioned in the plugin), so
96
+ // the target is thin config — no baked-in command list.
97
+ expect(target.executor).toBe('@abgov/nx-oc:sandbox');
98
+ expect(target.options).toMatchObject({
99
+ sandboxProject: 'test-sandbox',
100
+ registry: 'ghcr.io/test-org',
101
+ appType: 'node',
102
+ });
103
+ // No database key when the app has no database.
104
+ expect(target.options.database).toBeUndefined();
105
+
106
+ // The in-cluster BuildConfig flow is gone.
107
+ expect(host.exists('.openshift/test/sandbox-build.yml')).toBeFalsy();
108
+ });
109
+
110
+ it('writes a SANDBOX.md deploy/troubleshooting runbook next to the manifests', async () => {
111
+ const host = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
112
+ addNodeProject(host);
113
+
114
+ await generator(host, options);
115
+
116
+ expect(host.exists('.openshift/test/SANDBOX.md')).toBeTruthy();
117
+ const doc = host.read('.openshift/test/SANDBOX.md').toString();
118
+ expect(doc).toContain('nx run test:sandbox');
119
+ // resume flags + the copy-paste manual-completion sequence
120
+ expect(doc).toContain('--skipBuild');
121
+ expect(doc).toContain('oc import-image test:sandbox');
122
+ expect(doc).toContain('ghcr.io/test-org/test-sandbox-test:sandbox');
123
+ // no unrendered EJS tags leaked through
124
+ expect(doc).not.toContain('<%');
125
+ });
126
+
127
+ it('SANDBOX.md is app-type aware (frontend redirect URI; node+db migrate logs)', async () => {
128
+ const fe = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
129
+ addFrontendProject(fe);
130
+ await generator(fe, options);
131
+ const feDoc = fe.read('.openshift/test/SANDBOX.md').toString();
132
+ expect(feDoc).toContain('Invalid redirect_uri');
133
+ expect(feDoc).not.toContain('-migrate');
134
+
135
+ const node = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
136
+ addNodeProject(node);
137
+ await generator(node, { ...options, database: 'postgres' });
138
+ const nodeDoc = node.read('.openshift/test/SANDBOX.md').toString();
139
+ expect(nodeDoc).toContain('test-migrate');
140
+ expect(nodeDoc).not.toContain('Invalid redirect_uri');
141
+ });
142
+
143
+ it('persists the resolved registry to nx.json for reuse', async () => {
144
+ const host = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
145
+ addNodeProject(host);
146
+
147
+ await generator(host, options);
148
+
149
+ const nxJson = readNxJson(host);
150
+ expect(
151
+ (nxJson.generators as Record<string, { registry?: string }>)[
152
+ '@abgov/nx-oc:sandbox'
153
+ ].registry
154
+ ).toBe('ghcr.io/test-org');
91
155
  });
92
156
 
93
157
  it('adds sandbox-teardown nx target', async () => {
@@ -104,6 +168,12 @@ describe('Sandbox Generator', () => {
104
168
  expect(cmds.some((c) => c.includes('test-sandbox'))).toBeTruthy();
105
169
  expect(cmds.some((c) => c.includes('-l app=test'))).toBeTruthy();
106
170
  expect(cmds.some((c) => c.includes('all,configmap'))).toBeTruthy();
171
+ // Teardown also removes the sandbox package (best-effort).
172
+ expect(
173
+ cmds.some((c) =>
174
+ c.includes('packages/container/test-sandbox-test')
175
+ )
176
+ ).toBeTruthy();
107
177
  });
108
178
 
109
179
  it('generates shared postgres manifest with secret-backed DATABASE_URL', async () => {
@@ -121,10 +191,10 @@ describe('Sandbox Generator', () => {
121
191
  expect(appManifest).toContain('sandbox-postgres-creds');
122
192
  expect(appManifest).toContain('$(POSTGRES_PASSWORD)');
123
193
 
194
+ // The database type is passed to the executor, which provisions the shared
195
+ // instance + per-app database at deploy time.
124
196
  const config = readProjectConfiguration(host, 'test');
125
- const cmds: string[] = config.targets['sandbox'].options.commands;
126
- expect(cmds.some((c) => c.includes('sandbox-postgres-creds'))).toBeTruthy();
127
- expect(cmds.some((c) => c.includes('sandbox-postgres.yml'))).toBeTruthy();
197
+ expect(config.targets['sandbox'].options.database).toBe('postgres');
128
198
  });
129
199
 
130
200
  it('generates shared mongodb manifest with secret-backed MONGODB_URI', async () => {
@@ -143,7 +213,34 @@ describe('Sandbox Generator', () => {
143
213
  expect(appManifest).toContain('$(MONGO_PASSWORD)');
144
214
 
145
215
  const config = readProjectConfiguration(host, 'test');
146
- const cmds: string[] = config.targets['sandbox'].options.commands;
147
- expect(cmds.some((c) => c.includes('sandbox-mongodb-creds'))).toBeTruthy();
216
+ expect(config.targets['sandbox'].options.database).toBe('mongo');
217
+ });
218
+
219
+ it('registers the deployment Route redirect URI for a frontend client', async () => {
220
+ const host = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
221
+ addFrontendProject(host);
222
+ utilsMock.addClientRedirectUris.mockClear();
223
+
224
+ await generator(host, options);
225
+
226
+ // Route host follows <app>-<namespace>.<ingressDomain>, registered against
227
+ // the public client urn:ads:<tenant>:<app> with the token from ADSP config.
228
+ expect(utilsMock.addClientRedirectUris).toHaveBeenCalledWith(
229
+ environments.test.accessServiceUrl,
230
+ 'test',
231
+ 'urn:ads:test:test',
232
+ ['https://test-test-sandbox.apps.test.example.com/*'],
233
+ 'mock-token'
234
+ );
235
+ });
236
+
237
+ it('does not register redirect URIs for a node service', async () => {
238
+ const host = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
239
+ addNodeProject(host);
240
+ utilsMock.addClientRedirectUris.mockClear();
241
+
242
+ await generator(host, options);
243
+
244
+ expect(utilsMock.addClientRedirectUris).not.toHaveBeenCalled();
148
245
  });
149
246
  });
@@ -9,10 +9,20 @@ export interface Schema {
9
9
  env?: string;
10
10
  adsp?: AdspConfiguration;
11
11
  accessToken?: string;
12
+ tenant?: string;
13
+ tenantRealm?: string;
14
+ registry?: string;
12
15
  }
13
16
 
14
17
  export interface NormalizedSchema extends Schema {
15
18
  projectName: string;
16
19
  appType: ApplicationType;
17
20
  adsp: AdspConfiguration;
21
+ buildOutputPath: string;
22
+ registry: string;
23
+ registryHost: string;
24
+ registryOrg: string;
25
+ imageName: string;
26
+ imageRef: string;
27
+ sourceRepositoryUrl?: string;
18
28
  }
@@ -43,6 +43,19 @@
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."
54
+ },
55
+ "registry": {
56
+ "type": "string",
57
+ "description": "Container registry to publish the sandbox image to (e.g., ghcr.io/my-org). Defaults to the value stored in nx.json, then derived from the git remote. Persisted to nx.json on first use.",
58
+ "alias": "r"
46
59
  }
47
60
  },
48
61
  "required": ["project", "sandboxProject"],
@@ -0,0 +1,2 @@
1
+ import { Tree } from '@nx/devkit';
2
+ export default function convertSandboxTarget(tree: Tree): Promise<void>;
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = convertSandboxTarget;
4
+ const tslib_1 = require("tslib");
5
+ const devkit_1 = require("@nx/devkit");
6
+ // Converts sandbox targets generated as raw `nx:run-commands` command lists into
7
+ // the `@abgov/nx-oc:sandbox` executor, so the versioned deploy logic (import
8
+ // retry, preflight, resume flags) applies without re-running the generator.
9
+ //
10
+ // sandboxProject and registry are recovered from the old command strings; the
11
+ // app type is left to the executor to detect at run time.
12
+ function convertSandboxTarget(tree) {
13
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
14
+ var _a, _b, _c, _d;
15
+ let converted = 0;
16
+ for (const [name, project] of (0, devkit_1.getProjects)(tree)) {
17
+ const target = (_a = project.targets) === null || _a === void 0 ? void 0 : _a['sandbox'];
18
+ if (!target || target.executor !== 'nx:run-commands')
19
+ continue;
20
+ const commands = Array.isArray((_b = target.options) === null || _b === void 0 ? void 0 : _b.commands)
21
+ ? target.options.commands
22
+ : [];
23
+ const joined = commands.join('\n');
24
+ // Only touch the sandbox target this plugin generated (podman build + import).
25
+ if (!/podman build/.test(joined) || !/oc import-image/.test(joined))
26
+ continue;
27
+ const namespace = (_c = joined.match(/-n\s+(\S+)/)) === null || _c === void 0 ? void 0 : _c[1];
28
+ const imageRef = (_d = joined.match(/podman build[^\n]*?-t\s+(\S+)/)) === null || _d === void 0 ? void 0 : _d[1];
29
+ if (!namespace || !imageRef) {
30
+ devkit_1.logger.warn(`[nx-oc] Could not parse the sandbox target for "${name}"; leaving it as run-commands. Re-run the sandbox generator to migrate it.`);
31
+ continue;
32
+ }
33
+ // imageRef is <registry>/<namespace>-<project>:<tag>; the registry is
34
+ // everything before the final path segment (it contains its own slash,
35
+ // e.g. ghcr.io/org).
36
+ const registry = imageRef.slice(0, imageRef.lastIndexOf('/'));
37
+ const database = /sandbox-postgres/.test(joined)
38
+ ? 'postgres'
39
+ : /sandbox-mongodb/.test(joined)
40
+ ? 'mongo'
41
+ : undefined;
42
+ project.targets['sandbox'] = {
43
+ executor: '@abgov/nx-oc:sandbox',
44
+ options: Object.assign({ sandboxProject: namespace, registry }, (database ? { database } : {})),
45
+ };
46
+ (0, devkit_1.updateProjectConfiguration)(tree, name, project);
47
+ converted++;
48
+ }
49
+ if (converted > 0) {
50
+ devkit_1.logger.info(`[nx-oc] Converted ${converted} sandbox target(s) to the @abgov/nx-oc:sandbox executor.`);
51
+ }
52
+ });
53
+ }
54
+ //# sourceMappingURL=convert-sandbox-target.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"convert-sandbox-target.js","sourceRoot":"","sources":["../../../../../../packages/nx-oc/src/migrations/convert-sandbox-target/convert-sandbox-target.ts"],"names":[],"mappings":";;AAaA,uCAiDC;;AA9DD,uCAKoB;AAEpB,iFAAiF;AACjF,6EAA6E;AAC7E,4EAA4E;AAC5E,EAAE;AACF,8EAA8E;AAC9E,0DAA0D;AAC1D,SAA8B,oBAAoB,CAAC,IAAU;;;QAC3D,IAAI,SAAS,GAAG,CAAC,CAAC;QAElB,KAAK,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,IAAA,oBAAW,EAAC,IAAI,CAAC,EAAE,CAAC;YAChD,MAAM,MAAM,GAAG,MAAA,OAAO,CAAC,OAAO,0CAAG,SAAS,CAAC,CAAC;YAC5C,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,QAAQ,KAAK,iBAAiB;gBAAE,SAAS;YAE/D,MAAM,QAAQ,GAAa,KAAK,CAAC,OAAO,CAAC,MAAA,MAAM,CAAC,OAAO,0CAAE,QAAQ,CAAC;gBAChE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ;gBACzB,CAAC,CAAC,EAAE,CAAC;YACP,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnC,+EAA+E;YAC/E,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC;gBAAE,SAAS;YAE9E,MAAM,SAAS,GAAG,MAAA,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,0CAAG,CAAC,CAAC,CAAC;YAClD,MAAM,QAAQ,GAAG,MAAA,MAAM,CAAC,KAAK,CAAC,+BAA+B,CAAC,0CAAG,CAAC,CAAC,CAAC;YACpE,IAAI,CAAC,SAAS,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAC5B,eAAM,CAAC,IAAI,CACT,mDAAmD,IAAI,4EAA4E,CACpI,CAAC;gBACF,SAAS;YACX,CAAC;YACD,sEAAsE;YACtE,uEAAuE;YACvE,qBAAqB;YACrB,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC;YAC9D,MAAM,QAAQ,GAAG,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC;gBAC9C,CAAC,CAAC,UAAU;gBACZ,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC;oBAChC,CAAC,CAAC,OAAO;oBACT,CAAC,CAAC,SAAS,CAAC;YAEd,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG;gBAC3B,QAAQ,EAAE,sBAAsB;gBAChC,OAAO,kBACL,cAAc,EAAE,SAAS,EACzB,QAAQ,IACL,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAClC;aACF,CAAC;YACF,IAAA,mCAA0B,EAAC,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;YAChD,SAAS,EAAE,CAAC;QACd,CAAC;QAED,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;YAClB,eAAM,CAAC,IAAI,CACT,qBAAqB,SAAS,0DAA0D,CACzF,CAAC;QACJ,CAAC;IACH,CAAC;CAAA"}
@@ -0,0 +1,111 @@
1
+ import {
2
+ addProjectConfiguration,
3
+ readProjectConfiguration,
4
+ Tree,
5
+ } from '@nx/devkit';
6
+ import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
7
+ import migration from './convert-sandbox-target';
8
+
9
+ // A representative slice of the old generated run-commands sandbox target.
10
+ function oldSandboxCommands(ns: string, database?: 'postgres' | 'mongo') {
11
+ const ref = `ghcr.io/test-org/${ns}-app:sandbox`;
12
+ return [
13
+ ...(database === 'postgres'
14
+ ? [`oc apply -f .openshift/sandbox/sandbox-postgres.yml -n ${ns}`]
15
+ : []),
16
+ ...(database === 'mongo'
17
+ ? [`oc apply -f .openshift/sandbox/sandbox-mongodb.yml -n ${ns}`]
18
+ : []),
19
+ `npx nx build app --configuration production`,
20
+ `podman build --platform=linux/amd64 -f .openshift/app/Dockerfile -t ${ref} .`,
21
+ `podman push ${ref}`,
22
+ `oc tag ${ref} app:sandbox --reference-policy=local -n ${ns}`,
23
+ `n=0; until oc import-image app:sandbox --confirm -n ${ns}; do n=$((n+1)); [ $n -ge 5 ] && exit 1; sleep 3; done`,
24
+ ];
25
+ }
26
+
27
+ describe('convert-sandbox-target migration', () => {
28
+ let tree: Tree;
29
+ beforeEach(() => {
30
+ tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
31
+ });
32
+
33
+ it('converts a run-commands sandbox target to the executor', async () => {
34
+ addProjectConfiguration(tree, 'app', {
35
+ root: 'apps/app',
36
+ projectType: 'application',
37
+ targets: {
38
+ sandbox: {
39
+ executor: 'nx:run-commands',
40
+ options: { commands: oldSandboxCommands('my-ns'), parallel: false },
41
+ },
42
+ },
43
+ });
44
+
45
+ await migration(tree);
46
+
47
+ const target = readProjectConfiguration(tree, 'app').targets.sandbox;
48
+ expect(target.executor).toBe('@abgov/nx-oc:sandbox');
49
+ expect(target.options).toEqual({
50
+ sandboxProject: 'my-ns',
51
+ registry: 'ghcr.io/test-org',
52
+ });
53
+ });
54
+
55
+ it('recovers the database type from the old commands', async () => {
56
+ addProjectConfiguration(tree, 'app', {
57
+ root: 'apps/app',
58
+ projectType: 'application',
59
+ targets: {
60
+ sandbox: {
61
+ executor: 'nx:run-commands',
62
+ options: { commands: oldSandboxCommands('my-ns', 'postgres') },
63
+ },
64
+ },
65
+ });
66
+
67
+ await migration(tree);
68
+
69
+ expect(readProjectConfiguration(tree, 'app').targets.sandbox.options).toEqual({
70
+ sandboxProject: 'my-ns',
71
+ registry: 'ghcr.io/test-org',
72
+ database: 'postgres',
73
+ });
74
+ });
75
+
76
+ it('leaves an already-migrated executor target untouched', async () => {
77
+ const executorTarget = {
78
+ executor: '@abgov/nx-oc:sandbox',
79
+ options: { sandboxProject: 'my-ns', registry: 'ghcr.io/test-org' },
80
+ };
81
+ addProjectConfiguration(tree, 'app', {
82
+ root: 'apps/app',
83
+ projectType: 'application',
84
+ targets: { sandbox: executorTarget },
85
+ });
86
+
87
+ await migration(tree);
88
+
89
+ expect(readProjectConfiguration(tree, 'app').targets.sandbox).toEqual(
90
+ executorTarget
91
+ );
92
+ });
93
+
94
+ it('ignores unrelated run-commands targets', async () => {
95
+ const unrelated = {
96
+ executor: 'nx:run-commands',
97
+ options: { commands: ['echo hi'] },
98
+ };
99
+ addProjectConfiguration(tree, 'app', {
100
+ root: 'apps/app',
101
+ projectType: 'application',
102
+ targets: { sandbox: unrelated },
103
+ });
104
+
105
+ await migration(tree);
106
+
107
+ expect(readProjectConfiguration(tree, 'app').targets.sandbox).toEqual(
108
+ unrelated
109
+ );
110
+ });
111
+ });
@@ -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"}
@@ -1,4 +1,5 @@
1
1
  export declare function getOcServerUrl(): string | undefined;
2
+ export declare function getClusterIngressDomain(): string | undefined;
2
3
  export declare function getSaToken(saName: string, namespace: string): string | undefined;
3
4
  export declare function createDockerRegistrySecret(name: string, server: string, username: string, password: string, namespace: string): boolean;
4
5
  export declare function linkSecretToServiceAccount(secretName: string, saName: string, namespace: string): boolean;
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getOcServerUrl = getOcServerUrl;
4
+ exports.getClusterIngressDomain = getClusterIngressDomain;
4
5
  exports.getSaToken = getSaToken;
5
6
  exports.createDockerRegistrySecret = createDockerRegistrySecret;
6
7
  exports.linkSecretToServiceAccount = linkSecretToServiceAccount;
@@ -15,6 +16,26 @@ function getOcServerUrl() {
15
16
  return undefined;
16
17
  }
17
18
  }
19
+ // Derives the cluster's ingress (apps) domain from the console URL, e.g.
20
+ // https://console-openshift-console.apps.example.com -> apps.example.com.
21
+ // Used to predict a deployment's default Route host by convention. Readable by
22
+ // any logged-in user (no cluster-scoped permissions needed).
23
+ function getClusterIngressDomain() {
24
+ try {
25
+ const consoleUrl = (0, child_process_1.execFileSync)('oc', ['whoami', '--show-console'], {
26
+ stdio: 'pipe',
27
+ })
28
+ .toString()
29
+ .trim();
30
+ if (!consoleUrl)
31
+ return undefined;
32
+ const host = new URL(consoleUrl).host;
33
+ return host.replace(/^console-openshift-console\./, '') || undefined;
34
+ }
35
+ catch (_a) {
36
+ return undefined;
37
+ }
38
+ }
18
39
  // Creates a bounded SA token valid for one year (OCP 4.11+ TokenRequest API).
19
40
  // Falls back to the legacy `oc sa get-token` on older clusters.
20
41
  function getSaToken(saName, namespace) {
@@ -1 +1 @@
1
- {"version":3,"file":"oc-utils.js","sourceRoot":"","sources":["../../../../../packages/nx-oc/src/utils/oc-utils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"oc-utils.js","sourceRoot":"","sources":["../../../../../packages/nx-oc/src/utils/oc-utils.ts"],"names":[],"mappings":"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"}
@@ -1,10 +0,0 @@
1
- # This is a minimal Dockerfile for app deployment.
2
- FROM registry.access.redhat.com/ubi8/dotnet-60-runtime
3
-
4
- ARG PROJECT
5
- ARG ASSEMBLY
6
-
7
- COPY ./dist/apps/${PROJECT}/net6.0 .
8
-
9
- ENV ASSEMBLY ${ASSEMBLY}
10
- CMD dotnet ${ASSEMBLY}
@@ -1,8 +0,0 @@
1
- # This is a minimal Dockerfile for app deployment.
2
- FROM registry.access.redhat.com/ubi8/nginx-118
3
-
4
- ARG PROJECT
5
- COPY ./dist/apps/${PROJECT}/nginx.conf "${NGINX_CONF_PATH}"
6
- COPY ./dist/apps/${PROJECT} .
7
-
8
- CMD nginx -g "daemon off;"
@@ -1,8 +0,0 @@
1
- # This is a minimal Dockerfile for app deployment.
2
- FROM registry.access.redhat.com/ubi8/nodejs-18
3
-
4
- ARG PROJECT
5
- COPY ./dist/apps/${PROJECT} .
6
- COPY ./node_modules ./node_modules
7
-
8
- CMD node main.js