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

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 (30) hide show
  1. package/package.json +1 -1
  2. package/src/adsp/adsp-utils.d.ts +10 -0
  3. package/src/adsp/adsp-utils.js +48 -0
  4. package/src/adsp/adsp-utils.js.map +1 -1
  5. package/src/build-assets.spec.ts +62 -0
  6. package/src/generators/deployment/deployment.js +11 -25
  7. package/src/generators/deployment/deployment.js.map +1 -1
  8. package/src/generators/deployment/deployment.spec.ts +5 -2
  9. package/src/generators/deployment/dotnet-files/Dockerfile__tmpl__ +16 -0
  10. package/src/generators/deployment/frontend-files/Dockerfile__tmpl__ +10 -0
  11. package/src/generators/deployment/node-files/Dockerfile__tmpl__ +10 -0
  12. package/src/generators/deployment/node-files/__projectName__.yml__tmpl__ +12 -1
  13. package/src/generators/deployment/schema.d.ts +1 -0
  14. package/src/generators/sandbox/database-files/sandbox-postgres.yml__tmpl__ +3 -1
  15. package/src/generators/sandbox/sandbox.js +151 -35
  16. package/src/generators/sandbox/sandbox.js.map +1 -1
  17. package/src/generators/sandbox/sandbox.spec.ts +139 -2
  18. package/src/generators/sandbox/schema.d.ts +10 -0
  19. package/src/generators/sandbox/schema.json +13 -0
  20. package/src/utils/app-type.d.ts +18 -0
  21. package/src/utils/app-type.js +43 -0
  22. package/src/utils/app-type.js.map +1 -0
  23. package/src/utils/git-utils.js +4 -2
  24. package/src/utils/git-utils.js.map +1 -1
  25. package/src/utils/oc-utils.d.ts +1 -0
  26. package/src/utils/oc-utils.js +21 -0
  27. package/src/utils/oc-utils.js.map +1 -1
  28. package/src/generators/deployment/dotnet-files/Dockerfile.template +0 -10
  29. package/src/generators/deployment/frontend-files/Dockerfile.template +0 -8
  30. package/src/generators/deployment/node-files/Dockerfile.template +0 -8
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abgov/nx-oc",
3
- "version": "13.0.0-beta.1",
3
+ "version": "13.0.0-beta.2",
4
4
  "license": "Apache-2.0",
5
5
  "main": "src/index.js",
6
6
  "description": "Government of Alberta - Nx plugin for OpenShift.",
@@ -15,3 +15,13 @@ export declare function getAdspConfiguration(_host: Tree, options: {
15
15
  tenantRealm?: string;
16
16
  }): Promise<AdspConfiguration>;
17
17
  export declare function isAdspOptions(options: unknown): options is AdspOptions;
18
+ /**
19
+ * Registers redirect URIs (and matching post-logout URIs) on an existing public
20
+ * client so a deployed app can complete browser sign-in/out against its route.
21
+ *
22
+ * Idempotent and best-effort: no-ops without a token, skips if the client isn't
23
+ * found, and logs (never throws) on failure so it can't break generation. The
24
+ * client's `webOrigins` is intentionally left as-is — the default `["+"]`
25
+ * already allows CORS from any redirect-URI origin.
26
+ */
27
+ export declare function addClientRedirectUris(accessServiceUrl: string, realm: string, clientId: string, redirectUris: string[], accessToken: string | undefined): Promise<void>;
@@ -6,6 +6,7 @@ exports.getServiceUrls = getServiceUrls;
6
6
  exports.selectTenant = selectTenant;
7
7
  exports.getAdspConfiguration = getAdspConfiguration;
8
8
  exports.isAdspOptions = isAdspOptions;
9
+ exports.addClientRedirectUris = addClientRedirectUris;
9
10
  const tslib_1 = require("tslib");
10
11
  const devkit_1 = require("@nx/devkit");
11
12
  const axios_1 = require("axios");
@@ -162,4 +163,51 @@ function isAdspOptions(options) {
162
163
  var _a;
163
164
  return !!((_a = options === null || options === void 0 ? void 0 : options.adsp) === null || _a === void 0 ? void 0 : _a.tenantRealm);
164
165
  }
166
+ /**
167
+ * Registers redirect URIs (and matching post-logout URIs) on an existing public
168
+ * client so a deployed app can complete browser sign-in/out against its route.
169
+ *
170
+ * Idempotent and best-effort: no-ops without a token, skips if the client isn't
171
+ * found, and logs (never throws) on failure so it can't break generation. The
172
+ * client's `webOrigins` is intentionally left as-is — the default `["+"]`
173
+ * already allows CORS from any redirect-URI origin.
174
+ */
175
+ function addClientRedirectUris(accessServiceUrl, realm, clientId, redirectUris, accessToken) {
176
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
177
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
178
+ if (!accessToken || redirectUris.length === 0)
179
+ return;
180
+ const base = new URL(`/auth/admin/realms/${realm}/clients`, accessServiceUrl)
181
+ .href;
182
+ const authHeader = { Authorization: `Bearer ${accessToken}` };
183
+ const union = (existing, additions) => Array.from(new Set([...(existing !== null && existing !== void 0 ? existing : []), ...additions]));
184
+ try {
185
+ const { data: clients } = yield axios_1.default.get(base, {
186
+ params: { clientId },
187
+ headers: authHeader,
188
+ });
189
+ const client = clients === null || clients === void 0 ? void 0 : clients[0];
190
+ if (!client) {
191
+ console.log(`[nx-oc] Public client '${clientId}' not found in realm '${realm}' — skipping redirect URI update.`);
192
+ return;
193
+ }
194
+ const existingPostLogout = ((_b = (_a = client.attributes) === null || _a === void 0 ? void 0 : _a['post.logout.redirect.uris']) !== null && _b !== void 0 ? _b : '')
195
+ .split('##')
196
+ .filter(Boolean);
197
+ const nextRedirects = union(client.redirectUris, redirectUris);
198
+ const nextPostLogout = union(existingPostLogout, redirectUris).join('##');
199
+ if (nextRedirects.length === ((_d = (_c = client.redirectUris) === null || _c === void 0 ? void 0 : _c.length) !== null && _d !== void 0 ? _d : 0) &&
200
+ nextPostLogout === ((_f = (_e = client.attributes) === null || _e === void 0 ? void 0 : _e['post.logout.redirect.uris']) !== null && _f !== void 0 ? _f : '')) {
201
+ console.log(`[nx-oc] Client '${clientId}' already allows ${redirectUris.join(', ')}.`);
202
+ return;
203
+ }
204
+ yield axios_1.default.put(`${base}/${client.id}`, Object.assign(Object.assign({}, client), { redirectUris: nextRedirects, attributes: Object.assign(Object.assign({}, client.attributes), { 'post.logout.redirect.uris': nextPostLogout }) }), { headers: authHeader });
205
+ console.log(`[nx-oc] Registered redirect URI(s) on client '${clientId}': ${redirectUris.join(', ')}`);
206
+ }
207
+ catch (err) {
208
+ const detail = (_j = (_h = (_g = err === null || err === void 0 ? void 0 : err.response) === null || _g === void 0 ? void 0 : _g.status) !== null && _h !== void 0 ? _h : err === null || err === void 0 ? void 0 : err.message) !== null && _j !== void 0 ? _j : err;
209
+ console.log(`[nx-oc] Could not update redirect URIs for '${clientId}': ${detail}`);
210
+ }
211
+ });
212
+ }
165
213
  //# sourceMappingURL=adsp-utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"adsp-utils.js","sourceRoot":"","sources":["../../../../../packages/nx-oc/src/adsp/adsp-utils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"adsp-utils.js","sourceRoot":"","sources":["../../../../../packages/nx-oc/src/adsp/adsp-utils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ // minimatch is always present (nx depends on it); used only in this test.
4
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
5
+ import minimatch = require('minimatch');
6
+
7
+ /**
8
+ * Guards the source -> published-package boundary.
9
+ *
10
+ * The build copies non-source files (generator templates, schemas, static
11
+ * assets) into the package via the build target's `assets` globs. Any such file
12
+ * NOT matched by a glob is silently dropped from the published package, so a
13
+ * consumer's generate produces output referencing a file that was never
14
+ * shipped. This is exactly how `Dockerfile__tmpl__` was lost: the rename from
15
+ * `Dockerfile.template` (dotted) to `Dockerfile__tmpl__` (dotless) stopped it
16
+ * matching `**\/*.!(ts)`.
17
+ *
18
+ * Unit tests of the generators can't catch this — they resolve templates from
19
+ * the source tree, never the packaged output. This asserts the invariant
20
+ * directly: every non-TypeScript file under src is covered by an asset glob.
21
+ */
22
+ describe('build assets packaging', () => {
23
+ const srcRoot = __dirname;
24
+ const projectRoot = path.join(srcRoot, '..');
25
+ const repoRoot = path.join(projectRoot, '..', '..');
26
+
27
+ function listFiles(dir: string): string[] {
28
+ return fs.readdirSync(dir, { withFileTypes: true }).flatMap((entry) => {
29
+ const full = path.join(dir, entry.name);
30
+ return entry.isDirectory() ? listFiles(full) : [full];
31
+ });
32
+ }
33
+
34
+ it('matches every non-TypeScript src file with an asset glob', () => {
35
+ const project = JSON.parse(
36
+ fs.readFileSync(path.join(projectRoot, 'project.json'), 'utf-8')
37
+ );
38
+ const assets: unknown[] = project.targets.build.options.assets ?? [];
39
+
40
+ // Globs whose input is this package's src directory.
41
+ const srcGlobs = assets
42
+ .filter(
43
+ (a): a is { input: string; glob: string } =>
44
+ typeof a === 'object' &&
45
+ a !== null &&
46
+ 'input' in a &&
47
+ path.resolve(repoRoot, (a as { input: string }).input) === srcRoot
48
+ )
49
+ .map((a) => a.glob);
50
+
51
+ // Every non-source file under src must ship (tsc only emits .ts -> .js).
52
+ const mustShip = listFiles(srcRoot)
53
+ .filter((f) => !/\.tsx?$/.test(f))
54
+ .map((f) => path.relative(srcRoot, f));
55
+
56
+ const unmatched = mustShip.filter(
57
+ (rel) => !srcGlobs.some((glob) => minimatch(rel, glob, { dot: true }))
58
+ );
59
+
60
+ expect(unmatched).toEqual([]);
61
+ });
62
+ });
@@ -7,51 +7,37 @@ 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) {
53
33
  var _a, _b;
54
- const templateOptions = Object.assign(Object.assign(Object.assign({}, options), options.adsp), { sourceRepositoryUrl: (0, git_utils_1.getGitRemoteUrl)(), database: (_a = options.database) !== null && _a !== void 0 ? _a : 'none', sandbox: (_b = options.sandbox) !== null && _b !== void 0 ? _b : false, tmpl: '' });
34
+ const templateOptions = Object.assign(Object.assign(Object.assign({}, options), options.adsp), {
35
+ // Clean https URL for the image's source label (never the raw remote, which
36
+ // may be an SSH URL or carry a trailing newline).
37
+ sourceRepositoryUrl: (() => {
38
+ const repo = (0, git_utils_1.getGitHubRepo)((0, git_utils_1.getGitRemoteUrl)());
39
+ return repo ? `https://github.com/${repo}` : '';
40
+ })(), database: (_a = options.database) !== null && _a !== void 0 ? _a : 'none', sandbox: (_b = options.sandbox) !== null && _b !== void 0 ? _b : false, tmpl: '' });
55
41
  (0, devkit_1.generateFiles)(host, path.join(__dirname, `${options.appType}-files`), `./.openshift/${options.projectName}`, templateOptions);
56
42
  }
57
43
  function default_1(host, options) {
@@ -1 +1 @@
1
- {"version":3,"file":"deployment.js","sourceRoot":"","sources":["../../../../../../packages/nx-oc/src/generators/deployment/deployment.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"deployment.js","sourceRoot":"","sources":["../../../../../../packages/nx-oc/src/generators/deployment/deployment.ts"],"names":[],"mappings":"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"}
@@ -158,6 +158,10 @@ describe('Deployment Generator', () => {
158
158
  const manifest = host.read('.openshift/test/test.yml').toString();
159
159
  expect(manifest).toContain('readinessProbe');
160
160
  expect(manifest).toContain('livenessProbe');
161
+ // The service authenticates with ADSP using a confidential client secret,
162
+ // injected from the ${APP_NAME}-secrets Secret.
163
+ expect(manifest).toContain('CLIENT_SECRET');
164
+ expect(manifest).toContain('${APP_NAME}-secrets');
161
165
  });
162
166
 
163
167
  it('can generate deployment for dotnet', async () => {
@@ -218,8 +222,7 @@ describe('Deployment Generator', () => {
218
222
  const manifest = host.read('.openshift/test/test.yml').toString();
219
223
  expect(manifest).toContain('DATABASE_URL');
220
224
  expect(manifest).toContain('initContainers');
221
- expect(manifest).toContain('prisma');
222
- expect(manifest).toContain('migrate');
225
+ expect(manifest).toContain('migrate.js');
223
226
  });
224
227
 
225
228
  it('includes MONGODB_URI secretKeyRef without init container for mongo node deployment', async () => {
@@ -0,0 +1,16 @@
1
+ FROM registry.access.redhat.com/ubi8/dotnet-80 AS build
2
+ ARG PROJECT
3
+ WORKDIR /src
4
+ COPY . .
5
+ RUN dotnet publish ${PROJECT} -c Release -o /app/publish
6
+
7
+ FROM registry.access.redhat.com/ubi8/dotnet-80-runtime
8
+ <% if (sourceRepositoryUrl) { %>
9
+ # Provenance: associate the image with its source repo (shown in GHCR).
10
+ LABEL org.opencontainers.image.source=<%= sourceRepositoryUrl %>
11
+ <% } %>
12
+ WORKDIR /app
13
+ COPY --from=build /app/publish .
14
+ ENV ASPNETCORE_URLS=http://+:5000
15
+ EXPOSE 5000
16
+ CMD ["dotnet", "<%= projectName %>.dll"]
@@ -0,0 +1,10 @@
1
+ FROM registry.access.redhat.com/ubi9/nginx-120
2
+ <% if (sourceRepositoryUrl) { %>
3
+ # Provenance: associate the image with its source repo (shown in GHCR).
4
+ LABEL org.opencontainers.image.source=<%= sourceRepositoryUrl %>
5
+ <% } %>
6
+ # Build output path mirrors the workspace layout (from the project's build target).
7
+ COPY ./<%= buildOutputPath %>/nginx.conf "${NGINX_CONF_PATH}"
8
+ COPY ./<%= buildOutputPath %> .
9
+
10
+ CMD nginx -g "daemon off;"
@@ -0,0 +1,10 @@
1
+ FROM registry.access.redhat.com/ubi9/nodejs-24
2
+ <% if (sourceRepositoryUrl) { %>
3
+ # Provenance: associate the image with its source repo (shown in GHCR).
4
+ LABEL org.opencontainers.image.source=<%= sourceRepositoryUrl %>
5
+ <% } %>
6
+ # Build output path mirrors the workspace layout (from the project's build target).
7
+ COPY ./<%= buildOutputPath %> .
8
+ COPY ./node_modules ./node_modules
9
+
10
+ CMD node main.js
@@ -91,7 +91,7 @@ objects:
91
91
  <% } else { %>
92
92
  image: image-registry.openshift-image-registry.svc:5000/${INFRA_PROJECT}/${APP_NAME}:${DEPLOY_TAG}
93
93
  <% } %>
94
- command: ["npx", "prisma", "migrate", "deploy"]
94
+ command: ["node", "migrate.js"]
95
95
  envFrom:
96
96
  - configMapRef:
97
97
  name: ${APP_NAME}
@@ -127,6 +127,17 @@ objects:
127
127
  value: '3333'
128
128
  - name: LOG_LEVEL
129
129
  value: info
130
+ # ADSP confidential-client secret the service uses to authenticate
131
+ # with the access service. Sandbox: created by `nx run <app>:sandbox`
132
+ # from the service's .env.
133
+ <% if (!sandbox) { %>
134
+ # Other envs: oc create secret generic ${APP_NAME}-secrets --from-literal=CLIENT_SECRET=<secret>
135
+ <% } %>
136
+ - name: CLIENT_SECRET
137
+ valueFrom:
138
+ secretKeyRef:
139
+ name: ${APP_NAME}-secrets
140
+ key: CLIENT_SECRET
130
141
  <% if (database === 'postgres') { %>
131
142
  <% if (sandbox) { %>
132
143
  - name: POSTGRES_PASSWORD
@@ -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
  }
@@ -3,7 +3,9 @@
3
3
  # deleted on re-apply, so data persists across deployments.
4
4
  #
5
5
  # Multiple apps in the same namespace share this instance. Each app uses its
6
- # own database (<appName>_sandbox) created automatically by Prisma migrate.
6
+ # own database (<appName>_sandbox): the `nx run <app>:sandbox` target creates it
7
+ # (idempotently) after Postgres is ready, and the app's migrate init container
8
+ # applies the schema on deploy.
7
9
  #
8
10
  # Credentials are stored in the sandbox-postgres-creds Secret, created once
9
11
  # per namespace by `nx run <app>:sandbox` on first use. Subsequent apps read
@@ -6,39 +6,68 @@ 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 oc_utils_1 = require("../../utils/oc-utils");
10
+ const app_type_1 = require("../../utils/app-type");
11
+ const SANDBOX_GENERATOR = '@abgov/nx-oc:sandbox';
12
+ // Resolves the sandbox container registry once per workspace and persists it to
13
+ // nx.json so subsequent sandbox generations reuse it without re-prompting:
14
+ // --registry flag → nx.json → derived from git remote (ghcr.io/<org>) → prompt.
15
+ function resolveRegistry(host, registry, remoteUrl) {
16
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
17
+ var _a, _b, _c;
18
+ if (registry)
19
+ return persistRegistry(host, registry);
20
+ const stored = (_c = (_b = (_a = (0, devkit_1.readNxJson)(host)) === null || _a === void 0 ? void 0 : _a.generators) === null || _b === void 0 ? void 0 : _b[SANDBOX_GENERATOR]) === null || _c === void 0 ? void 0 : _c.registry;
21
+ if (stored)
22
+ return stored;
23
+ const derived = (0, git_utils_1.deriveRegistryFromRemote)(remoteUrl);
24
+ if (derived) {
25
+ console.log(`\n✓ Sandbox registry: ${derived.toLowerCase()} (derived from git remote)\n`);
26
+ return persistRegistry(host, derived);
27
+ }
28
+ const { prompt } = yield Promise.resolve().then(() => require('enquirer'));
29
+ const { registry: answered } = yield prompt({
30
+ type: 'input',
31
+ name: 'registry',
32
+ message: 'What container registry should sandbox images be published to (e.g., ghcr.io/my-org)?',
33
+ });
34
+ return persistRegistry(host, answered);
35
+ });
36
+ }
37
+ // Container registries (GHCR) require lowercase paths, so normalize on store.
38
+ function persistRegistry(host, registry) {
39
+ var _a, _b, _c;
40
+ const value = registry.toLowerCase();
41
+ const nxJson = (_a = (0, devkit_1.readNxJson)(host)) !== null && _a !== void 0 ? _a : {};
42
+ const generators = ((_b = nxJson.generators) !== null && _b !== void 0 ? _b : {});
43
+ generators[SANDBOX_GENERATOR] = Object.assign(Object.assign({}, ((_c = generators[SANDBOX_GENERATOR]) !== null && _c !== void 0 ? _c : {})), { registry: value });
44
+ nxJson.generators = generators;
45
+ (0, devkit_1.updateNxJson)(host, nxJson);
46
+ return value;
47
+ }
9
48
  function normalizeOptions(host, options) {
10
49
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
11
- var _a;
50
+ var _a, _b;
12
51
  const projectName = (0, devkit_1.names)(options.project).fileName;
13
52
  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' }));
53
+ const appType = (_a = options.appType) !== null && _a !== void 0 ? _a : (0, app_type_1.detectApplicationType)(config);
54
+ const adsp = yield (0, adsp_1.getAdspConfiguration)(host, Object.assign(Object.assign({}, options), { env: (_b = options.env) !== null && _b !== void 0 ? _b : 'dev' }));
55
+ const remoteUrl = (0, git_utils_1.getGitRemoteUrl)();
56
+ const registry = (yield resolveRegistry(host, options.registry, remoteUrl)).toLowerCase();
57
+ // Prefix the image with the (per-user) sandbox namespace so images from
58
+ // different experimenters never collide on GHCR's org-global package names.
59
+ const imageName = `${options.sandboxProject}-${projectName}`.toLowerCase();
60
+ const repoSlug = (0, git_utils_1.getGitHubRepo)(remoteUrl);
34
61
  return Object.assign(Object.assign({}, options), { appType,
35
62
  adsp,
36
- projectName });
63
+ projectName, buildOutputPath: (0, app_type_1.getBuildOutputPath)(config), registry, registryHost: registry.split('/')[0], registryOrg: registry.split('/').slice(1).join('/'), imageName, imageRef: `${registry}/${imageName}:sandbox`, sourceRepositoryUrl: repoSlug ? `https://github.com/${repoSlug}` : undefined });
37
64
  });
38
65
  }
39
66
  function addManifestFiles(host, options) {
40
- var _a;
41
- const templateOptions = Object.assign(Object.assign(Object.assign({}, options), options.adsp), { sourceRepositoryUrl: (0, git_utils_1.getGitRemoteUrl)(), database: (_a = options.database) !== null && _a !== void 0 ? _a : 'none', sandbox: true, ocInfraProject: options.sandboxProject, tmpl: '' });
67
+ var _a, _b;
68
+ const templateOptions = Object.assign(Object.assign(Object.assign({}, options), options.adsp), {
69
+ // Clean https URL for the image's source label (provenance / UI connect).
70
+ sourceRepositoryUrl: (_a = options.sourceRepositoryUrl) !== null && _a !== void 0 ? _a : '', database: (_b = options.database) !== null && _b !== void 0 ? _b : 'none', sandbox: true, ocInfraProject: options.sandboxProject, tmpl: '' });
42
71
  (0, devkit_1.generateFiles)(host, path.join(__dirname, `../deployment/${options.appType}-files`), `./.openshift/${options.projectName}`, templateOptions);
43
72
  }
44
73
  function addDatabaseFiles(host, options) {
@@ -47,15 +76,35 @@ function addDatabaseFiles(host, options) {
47
76
  (0, devkit_1.generateFiles)(host, path.join(__dirname, 'database-files'), './.openshift/sandbox', { database: options.database, tmpl: '' });
48
77
  }
49
78
  function addSandboxTarget(host, options) {
79
+ var _a;
50
80
  const config = (0, devkit_1.readProjectConfiguration)(host, options.project);
51
- const { projectName, sandboxProject, database } = options;
81
+ const { projectName, sandboxProject, database, appType, imageRef, registryHost, registryOrg, imageName, } = options;
52
82
  const commands = [];
83
+ // ADSP services authenticate with the access service using a confidential
84
+ // Keycloak client secret. The express-service generator writes it to the
85
+ // service's .env (CLIENT_SECRET=...) at generate time; mirror it into an
86
+ // OpenShift Secret the deployment reads. Upserted from the current .env so
87
+ // re-runs pick up a rotated secret. Non-node app types have no client secret.
88
+ if (appType === 'node') {
89
+ commands.push(`oc create secret generic ${projectName}-secrets ` +
90
+ `--from-literal=CLIENT_SECRET="$(grep -E '^CLIENT_SECRET=' ${config.root}/.env 2>/dev/null | cut -d= -f2-)" ` +
91
+ `-n ${sandboxProject} --dry-run=client -o yaml | oc apply -f -`);
92
+ }
53
93
  if (database === 'postgres') {
54
94
  commands.push(`oc get secret sandbox-postgres-creds -n ${sandboxProject} 2>/dev/null || ` +
55
95
  `oc create secret generic sandbox-postgres-creds ` +
56
96
  `--from-literal=POSTGRESQL_ADMIN_PASSWORD=$(openssl rand -base64 24 | tr -d '/+=') ` +
57
97
  `-n ${sandboxProject}`);
58
98
  commands.push(`oc apply -f .openshift/sandbox/sandbox-postgres.yml -n ${sandboxProject}`);
99
+ // The shared Postgres instance only creates the admin database; each app
100
+ // needs its own <app>_sandbox database created before its migrate init
101
+ // container runs (neither the image nor the ORM creates it). Wait for
102
+ // Postgres to be ready, then create the database idempotently.
103
+ const dbName = `${projectName}_sandbox`;
104
+ commands.push(`oc rollout status deployment/sandbox-postgres -n ${sandboxProject} --timeout=180s && ` +
105
+ `oc exec -n ${sandboxProject} deployment/sandbox-postgres -- ` +
106
+ `bash -lc "psql -U postgres -tc \\"SELECT 1 FROM pg_database WHERE datname='${dbName}'\\" ` +
107
+ `| grep -q 1 || createdb -U postgres ${dbName}"`);
59
108
  }
60
109
  else if (database === 'mongo') {
61
110
  commands.push(`oc get secret sandbox-mongodb-creds -n ${sandboxProject} 2>/dev/null || ` +
@@ -64,32 +113,98 @@ function addSandboxTarget(host, options) {
64
113
  `-n ${sandboxProject}`);
65
114
  commands.push(`oc apply -f .openshift/sandbox/sandbox-mongodb.yml -n ${sandboxProject}`);
66
115
  }
116
+ // Ensure any paired backend Services exist first, so this app's nginx can
117
+ // resolve its proxy_pass upstreams at startup (otherwise the pod crashloops
118
+ // until the Service appears). Create only the Service (all nginx needs for
119
+ // DNS) — not the backend's deployment, which has no image until its own
120
+ // sandbox runs. Idempotent: skipped once the Service exists, so it doesn't
121
+ // slow down repeated frontend iteration. Recorded by the composite generators
122
+ // (pevn/mevn/…) as `adsp:proxy-service:<name>:<port>` project tags.
123
+ const PREFIX = 'adsp:proxy-service:';
124
+ const proxyServices = ((_a = config.tags) !== null && _a !== void 0 ? _a : [])
125
+ .filter((tag) => tag.startsWith(PREFIX))
126
+ .map((tag) => {
127
+ const value = tag.slice(PREFIX.length);
128
+ const lastColon = value.lastIndexOf(':');
129
+ return {
130
+ name: value.slice(0, lastColon),
131
+ port: value.slice(lastColon + 1),
132
+ };
133
+ });
134
+ for (const { name, port } of proxyServices) {
135
+ commands.push(`oc get service ${name} -n ${sandboxProject} >/dev/null 2>&1 || ` +
136
+ `oc create service clusterip ${name} --tcp=${port}:${port} -n ${sandboxProject}`);
137
+ }
138
+ // Build the image locally and push to the container registry, then import it
139
+ // into the namespace's imagestream. reference-policy=local mirrors it into the
140
+ // internal registry so pods pull in-cluster (no per-pod pull secret, no node
141
+ // egress to the registry). This replaces the in-cluster BuildConfig: no
142
+ // full-workspace upload, and local layer caching makes iteration fast.
143
+ commands.push(`npx nx build ${projectName} --configuration production`);
144
+ commands.push(`podman build --platform=linux/amd64 -f .openshift/${projectName}/Dockerfile -t ${imageRef} .`);
145
+ // Prereq: the publishing account is logged in with write:packages. gh supplies
146
+ // the token so no PAT is stored; the same session token backs the pull secret.
147
+ commands.push(`gh auth token | podman login ${registryHost} -u "$(gh api user -q .login)" --password-stdin`);
148
+ commands.push(`podman push ${imageRef}`);
149
+ // Per-deploy pull secret from the gh session (sandbox images are re-imported
150
+ // every run, so a session token is sufficient — no long-lived PAT needed).
151
+ commands.push(`oc create secret docker-registry ghcr-pull ` +
152
+ `--docker-server=${registryHost} --docker-username="$(gh api user -q .login)" --docker-password="$(gh auth token)" ` +
153
+ `-n ${sandboxProject} --dry-run=client -o yaml | oc apply -f -`);
154
+ // oc tag sets/repoints the imagestream tag (import-image refuses to change an
155
+ // existing tag's source); import --confirm then pulls the manifest.
156
+ commands.push(`oc tag ${imageRef} ${projectName}:sandbox --reference-policy=local -n ${sandboxProject}`);
157
+ // oc tag triggers an async imagestream reconcile, so a back-to-back
158
+ // import-image can 409 ("object has been modified"). Retry until it settles.
159
+ commands.push(`n=0; until oc import-image ${projectName}:sandbox --confirm -n ${sandboxProject}; do ` +
160
+ `n=$((n+1)); [ $n -ge 5 ] && exit 1; sleep 3; done`);
67
161
  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
162
  commands.push(`oc rollout restart deployment/${projectName} -n ${sandboxProject}`);
76
- commands.push(`oc rollout status deployment/${projectName} -n ${sandboxProject} --timeout=120s`);
163
+ commands.push(`oc rollout status deployment/${projectName} -n ${sandboxProject} --timeout=180s`);
77
164
  config.targets = Object.assign(Object.assign({}, config.targets), { sandbox: {
78
165
  executor: 'nx:run-commands',
79
166
  options: {
80
167
  commands,
81
- sequential: true,
168
+ parallel: false,
82
169
  },
83
170
  }, 'sandbox-teardown': {
84
171
  executor: 'nx:run-commands',
85
172
  options: {
86
173
  commands: [
87
- `oc delete all,configmap -l app=${projectName} -n ${sandboxProject} --ignore-not-found`,
174
+ `oc delete all,configmap,is -l app=${projectName} -n ${sandboxProject} --ignore-not-found`,
175
+ `oc delete imagestream ${projectName} -n ${sandboxProject} --ignore-not-found`,
176
+ // Remove the sandbox package (needs delete:packages). Best-effort:
177
+ // sandbox packages are the unlinked ones and can also be pruned org-wide
178
+ // via `select(.repository == null)`.
179
+ `gh api --method DELETE /orgs/${registryOrg}/packages/container/${imageName} 2>/dev/null || true`,
88
180
  ],
89
181
  },
90
182
  } });
91
183
  (0, devkit_1.updateProjectConfiguration)(host, options.project, config);
92
184
  }
185
+ // Register the sandbox deployment's Route with the frontend's public client so
186
+ // browser sign-in works against the deployed URL — not just localhost. The
187
+ // Route host is deterministic by convention (<app>-<namespace>.<ingressDomain>),
188
+ // so this happens once at generate time using the token already obtained for
189
+ // ADSP config — no per-deploy login.
190
+ function registerSandboxRedirectUri(options) {
191
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
192
+ if (options.appType !== 'frontend')
193
+ return;
194
+ const { adsp, projectName, sandboxProject } = options;
195
+ if (!(adsp === null || adsp === void 0 ? void 0 : adsp.accessToken))
196
+ return;
197
+ const ingressDomain = (0, oc_utils_1.getClusterIngressDomain)();
198
+ if (!ingressDomain) {
199
+ console.log('[nx-oc] Could not determine the cluster ingress domain; skipping redirect URI registration. ' +
200
+ 'Add the deployment Route to the client manually if browser sign-in fails.');
201
+ return;
202
+ }
203
+ const routeUrl = `https://${projectName}-${sandboxProject}.${ingressDomain}`;
204
+ const clientId = `urn:ads:${adsp.tenant}:${projectName}`;
205
+ yield (0, adsp_1.addClientRedirectUris)(adsp.accessServiceUrl, adsp.tenantRealm, clientId, [`${routeUrl}/*`], adsp.accessToken);
206
+ });
207
+ }
93
208
  function default_1(host, options) {
94
209
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
95
210
  const normalizedOptions = yield normalizeOptions(host, options);
@@ -100,6 +215,7 @@ function default_1(host, options) {
100
215
  addManifestFiles(host, normalizedOptions);
101
216
  addDatabaseFiles(host, normalizedOptions);
102
217
  addSandboxTarget(host, normalizedOptions);
218
+ yield registerSandboxRedirectUri(normalizedOptions);
103
219
  yield (0, devkit_1.formatFiles)(host);
104
220
  });
105
221
  }
@@ -1 +1 @@
1
- {"version":3,"file":"sandbox.js","sourceRoot":"","sources":["../../../../../../packages/nx-oc/src/generators/sandbox/sandbox.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sandbox.js","sourceRoot":"","sources":["../../../../../../packages/nx-oc/src/generators/sandbox/sandbox.ts"],"names":[],"mappings":"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"}
@@ -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',
@@ -84,10 +92,69 @@ describe('Sandbox Generator', () => {
84
92
  const config = readProjectConfiguration(host, 'test');
85
93
  expect(config.targets['sandbox']).toBeTruthy();
86
94
  expect(config.targets['sandbox'].executor).toBe('nx:run-commands');
95
+ // Commands run in order (nx:run-commands has no `sequential` option).
96
+ expect(config.targets['sandbox'].options.parallel).toBe(false);
87
97
  const cmds: string[] = config.targets['sandbox'].options.commands;
88
98
  expect(cmds.some((c) => c.includes('oc rollout restart'))).toBeTruthy();
89
99
  expect(cmds.some((c) => c.includes('oc rollout status'))).toBeTruthy();
90
- expect(cmds.some((c) => c.includes('command -v podman'))).toBeTruthy();
100
+ expect(cmds.some((c) => c.includes('nx build test'))).toBeTruthy();
101
+
102
+ // Local podman build + push to the prescribed registry, with the image name
103
+ // prefixed by the (per-user) sandbox namespace to avoid GHCR's org-global
104
+ // name collisions.
105
+ const imageRef = 'ghcr.io/test-org/test-sandbox-test:sandbox';
106
+ expect(
107
+ cmds.some((c) => c.includes('podman build') && c.includes(imageRef))
108
+ ).toBeTruthy();
109
+ expect(cmds.some((c) => c.includes(`podman push ${imageRef}`))).toBeTruthy();
110
+ expect(cmds.some((c) => c.includes('podman login ghcr.io'))).toBeTruthy();
111
+
112
+ // Import into the namespace imagestream; pods pull from the internal registry.
113
+ expect(
114
+ cmds.some((c) =>
115
+ c.includes(`oc tag ${imageRef} test:sandbox --reference-policy=local`)
116
+ )
117
+ ).toBeTruthy();
118
+ // import-image is retried to absorb the 409 from oc tag's async reconcile.
119
+ expect(
120
+ cmds.some(
121
+ (c) =>
122
+ c.includes('oc import-image test:sandbox --confirm') &&
123
+ c.includes('until')
124
+ )
125
+ ).toBeTruthy();
126
+ // Per-deploy pull secret from the gh session (no stored PAT).
127
+ expect(
128
+ cmds.some((c) => c.includes('oc create secret docker-registry ghcr-pull'))
129
+ ).toBeTruthy();
130
+
131
+ // The in-cluster BuildConfig flow is gone.
132
+ expect(cmds.some((c) => c.includes('oc start-build'))).toBeFalsy();
133
+ expect(host.exists('.openshift/test/sandbox-build.yml')).toBeFalsy();
134
+
135
+ // A node service's ADSP client secret is mirrored from .env into an
136
+ // OpenShift Secret the deployment reads.
137
+ expect(
138
+ cmds.some(
139
+ (c) =>
140
+ c.includes('oc create secret generic test-secrets') &&
141
+ c.includes('CLIENT_SECRET')
142
+ )
143
+ ).toBeTruthy();
144
+ });
145
+
146
+ it('persists the resolved registry to nx.json for reuse', async () => {
147
+ const host = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
148
+ addNodeProject(host);
149
+
150
+ await generator(host, options);
151
+
152
+ const nxJson = readNxJson(host);
153
+ expect(
154
+ (nxJson.generators as Record<string, { registry?: string }>)[
155
+ '@abgov/nx-oc:sandbox'
156
+ ].registry
157
+ ).toBe('ghcr.io/test-org');
91
158
  });
92
159
 
93
160
  it('adds sandbox-teardown nx target', async () => {
@@ -104,6 +171,12 @@ describe('Sandbox Generator', () => {
104
171
  expect(cmds.some((c) => c.includes('test-sandbox'))).toBeTruthy();
105
172
  expect(cmds.some((c) => c.includes('-l app=test'))).toBeTruthy();
106
173
  expect(cmds.some((c) => c.includes('all,configmap'))).toBeTruthy();
174
+ // Teardown also removes the sandbox package (best-effort).
175
+ expect(
176
+ cmds.some((c) =>
177
+ c.includes('packages/container/test-sandbox-test')
178
+ )
179
+ ).toBeTruthy();
107
180
  });
108
181
 
109
182
  it('generates shared postgres manifest with secret-backed DATABASE_URL', async () => {
@@ -125,6 +198,12 @@ describe('Sandbox Generator', () => {
125
198
  const cmds: string[] = config.targets['sandbox'].options.commands;
126
199
  expect(cmds.some((c) => c.includes('sandbox-postgres-creds'))).toBeTruthy();
127
200
  expect(cmds.some((c) => c.includes('sandbox-postgres.yml'))).toBeTruthy();
201
+ // The per-app database is created idempotently before the app deploys.
202
+ expect(cmds.some((c) => c.includes('createdb -U postgres test_sandbox'))).toBeTruthy();
203
+ const createDbIdx = cmds.findIndex((c) => c.includes('createdb'));
204
+ const rolloutIdx = cmds.findIndex((c) => c.includes('rollout status deployment/test'));
205
+ expect(createDbIdx).toBeGreaterThanOrEqual(0);
206
+ expect(createDbIdx).toBeLessThan(rolloutIdx);
128
207
  });
129
208
 
130
209
  it('generates shared mongodb manifest with secret-backed MONGODB_URI', async () => {
@@ -146,4 +225,62 @@ describe('Sandbox Generator', () => {
146
225
  const cmds: string[] = config.targets['sandbox'].options.commands;
147
226
  expect(cmds.some((c) => c.includes('sandbox-mongodb-creds'))).toBeTruthy();
148
227
  });
228
+
229
+ it('ensures paired backend Services from proxy-service tags', async () => {
230
+ const host = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
231
+ addFrontendProject(host, ['adsp:proxy-service:test-service:3333']);
232
+
233
+ await generator(host, options);
234
+
235
+ const config = readProjectConfiguration(host, 'test');
236
+ const cmds: string[] = config.targets['sandbox'].options.commands;
237
+ const guard = cmds.find((c) => c.includes('oc get service test-service'));
238
+ expect(guard).toBeTruthy();
239
+ // idempotent: only creates the Service (for DNS) when it's missing — no
240
+ // backend deployment, which would have no image until its own sandbox runs.
241
+ expect(guard).toContain('||');
242
+ expect(guard).toContain(
243
+ 'oc create service clusterip test-service --tcp=3333:3333'
244
+ );
245
+ expect(guard).not.toContain('test-service.yml');
246
+ });
247
+
248
+ it('adds no paired-service guard when there are no proxy-service tags', async () => {
249
+ const host = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
250
+ addNodeProject(host);
251
+
252
+ await generator(host, options);
253
+
254
+ const config = readProjectConfiguration(host, 'test');
255
+ const cmds: string[] = config.targets['sandbox'].options.commands;
256
+ expect(cmds.some((c) => c.includes('oc get service'))).toBeFalsy();
257
+ });
258
+
259
+ it('registers the deployment Route redirect URI for a frontend client', async () => {
260
+ const host = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
261
+ addFrontendProject(host);
262
+ utilsMock.addClientRedirectUris.mockClear();
263
+
264
+ await generator(host, options);
265
+
266
+ // Route host follows <app>-<namespace>.<ingressDomain>, registered against
267
+ // the public client urn:ads:<tenant>:<app> with the token from ADSP config.
268
+ expect(utilsMock.addClientRedirectUris).toHaveBeenCalledWith(
269
+ environments.test.accessServiceUrl,
270
+ 'test',
271
+ 'urn:ads:test:test',
272
+ ['https://test-test-sandbox.apps.test.example.com/*'],
273
+ 'mock-token'
274
+ );
275
+ });
276
+
277
+ it('does not register redirect URIs for a node service', async () => {
278
+ const host = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
279
+ addNodeProject(host);
280
+ utilsMock.addClientRedirectUris.mockClear();
281
+
282
+ await generator(host, options);
283
+
284
+ expect(utilsMock.addClientRedirectUris).not.toHaveBeenCalled();
285
+ });
149
286
  });
@@ -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,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