├── docs
├── assets
│ └── .gitkeep
├── .ruby-version
├── .gitignore
├── favicon.ico
├── nx-oc
│ └── nx-oc.md
├── nx-release
│ └── nx-release.md
├── index.md
├── nx-adsp
│ └── nx-adsp.md
├── 404.html
├── Gemfile
└── _config.yml
├── .eslintignore
├── packages
├── nx-adsp
│ ├── src
│ │ ├── index.ts
│ │ ├── generators
│ │ │ ├── angular-app
│ │ │ │ ├── files
│ │ │ │ │ ├── src
│ │ │ │ │ │ ├── app
│ │ │ │ │ │ │ ├── protected
│ │ │ │ │ │ │ │ ├── protected.component.css__tmpl__
│ │ │ │ │ │ │ │ ├── protected.component.html__tmpl__
│ │ │ │ │ │ │ │ ├── protected.component.ts__tmpl__
│ │ │ │ │ │ │ │ └── protected.component.spec.ts__tmpl__
│ │ │ │ │ │ │ ├── logout
│ │ │ │ │ │ │ │ ├── logout.component.html__tmpl__
│ │ │ │ │ │ │ │ └── logout.component.ts__tmpl__
│ │ │ │ │ │ │ ├── home
│ │ │ │ │ │ │ │ ├── home.component.html__tmpl__
│ │ │ │ │ │ │ │ └── home.component.ts__tmpl__
│ │ │ │ │ │ │ ├── auth-callback
│ │ │ │ │ │ │ │ ├── auth-callback.component.css__tmpl__
│ │ │ │ │ │ │ │ ├── auth-callback.component.html__tmpl__
│ │ │ │ │ │ │ │ ├── auth-callback.component.spec.ts__tmpl__
│ │ │ │ │ │ │ │ └── auth-callback.component.ts__tmpl__
│ │ │ │ │ │ │ ├── services
│ │ │ │ │ │ │ │ ├── auth-guard.service.ts__tmpl__
│ │ │ │ │ │ │ │ └── auth.service.ts__tmpl__
│ │ │ │ │ │ │ ├── tenant.service.ts__tmpl__
│ │ │ │ │ │ │ ├── app.component.ts__tmpl__
│ │ │ │ │ │ │ ├── auth.interceptor.ts__tmpl__
│ │ │ │ │ │ │ ├── app.routes.ts__tmpl__
│ │ │ │ │ │ │ ├── app.component.css__tmpl__
│ │ │ │ │ │ │ ├── app.module.ts__tmpl__
│ │ │ │ │ │ │ ├── app.component.spec.ts__tmpl__
│ │ │ │ │ │ │ └── app.component.html__tmpl__
│ │ │ │ │ │ ├── favicon.ico
│ │ │ │ │ │ ├── assets
│ │ │ │ │ │ │ ├── banner.jpg
│ │ │ │ │ │ │ └── github-1.svg
│ │ │ │ │ │ ├── styles.css__tmpl__
│ │ │ │ │ │ ├── test-setup.ts__tmpl__
│ │ │ │ │ │ ├── main.ts__tmpl__
│ │ │ │ │ │ ├── environments
│ │ │ │ │ │ │ ├── environment.ts__tmpl__
│ │ │ │ │ │ │ └── config.ts__tmpl__
│ │ │ │ │ │ └── index.html__tmpl__
│ │ │ │ │ └── nginx.conf__tmpl__
│ │ │ │ ├── schema.d.ts
│ │ │ │ └── schema.json
│ │ │ ├── react-app
│ │ │ │ ├── files
│ │ │ │ │ ├── src
│ │ │ │ │ │ ├── renew.html__tmpl__
│ │ │ │ │ │ ├── renew.ts__tmpl__
│ │ │ │ │ │ ├── favicon.ico
│ │ │ │ │ │ ├── assets
│ │ │ │ │ │ │ └── banner.jpg
│ │ │ │ │ │ ├── react-oidc.d.ts__tmpl__
│ │ │ │ │ │ ├── environments
│ │ │ │ │ │ │ └── environment.ts__tmpl__
│ │ │ │ │ │ ├── index.html__tmpl__
│ │ │ │ │ │ ├── access.ts__tmpl__
│ │ │ │ │ │ ├── store.ts__tmpl__
│ │ │ │ │ │ ├── app
│ │ │ │ │ │ │ ├── app.spec.tsx__tmpl__
│ │ │ │ │ │ │ ├── app.module.css__tmpl__
│ │ │ │ │ │ │ └── config.slice.ts__tmpl__
│ │ │ │ │ │ └── main.tsx__tmpl__
│ │ │ │ │ ├── webpack.config.js__tmpl__
│ │ │ │ │ └── nginx.conf__tmpl__
│ │ │ │ ├── schema.d.ts
│ │ │ │ └── schema.json
│ │ │ ├── dotnet-service
│ │ │ │ ├── files
│ │ │ │ │ ├── Examples
│ │ │ │ │ │ ├── ServiceRoles.cs__tmpl__
│ │ │ │ │ │ ├── HelloWorldConfiguration.cs__tmpl__
│ │ │ │ │ │ └── HelloWorldEvent.cs__tmpl__
│ │ │ │ │ ├── appsettings.Development.json__tmpl__
│ │ │ │ │ ├── appsettings.json__tmpl__
│ │ │ │ │ └── Program.cs__tmpl__
│ │ │ │ ├── schema.d.ts
│ │ │ │ ├── schema.json
│ │ │ │ ├── dotnet-service.spec.ts
│ │ │ │ └── dotnet-service.ts
│ │ │ ├── express-service
│ │ │ │ ├── schema.d.ts
│ │ │ │ ├── files
│ │ │ │ │ └── src
│ │ │ │ │ │ ├── environments
│ │ │ │ │ │ ├── environment.prod.ts__tmpl__
│ │ │ │ │ │ └── environment.ts__tmpl__
│ │ │ │ │ │ └── main.ts__tmpl__
│ │ │ │ ├── schema.json
│ │ │ │ ├── express-service.spec.ts
│ │ │ │ └── express-service.ts
│ │ │ ├── react-form
│ │ │ │ ├── schema.d.ts
│ │ │ │ ├── files
│ │ │ │ │ └── __fileName__
│ │ │ │ │ │ ├── __fileName__.slice.spec.ts__tmpl__
│ │ │ │ │ │ └── __fileName__.module.css__tmpl__
│ │ │ │ └── schema.json
│ │ │ ├── react-task-list
│ │ │ │ ├── schema.d.ts
│ │ │ │ ├── files
│ │ │ │ │ └── __fileName__
│ │ │ │ │ │ ├── task.d.ts__tmpl__
│ │ │ │ │ │ ├── __fileName__.slice.spec.ts__tmpl__
│ │ │ │ │ │ └── __fileName__.module.css__tmpl__
│ │ │ │ ├── schema.json
│ │ │ │ └── react-task-list.spec.ts
│ │ │ ├── mern
│ │ │ │ ├── schema.d.ts
│ │ │ │ ├── schema.json
│ │ │ │ ├── mern.spec.ts
│ │ │ │ └── mern.ts
│ │ │ └── react-dotnet
│ │ │ │ ├── schema.d.ts
│ │ │ │ ├── schema.json
│ │ │ │ ├── react-dotnet.spec.ts
│ │ │ │ └── react-dotnet.ts
│ │ └── utils
│ │ │ ├── nginx.d.ts
│ │ │ ├── task.d.ts
│ │ │ ├── form.ts
│ │ │ └── form.spec.ts
│ ├── .babelrc
│ ├── tsconfig.json
│ ├── tsconfig.lib.json
│ ├── tsconfig.spec.json
│ ├── .releaserc.json
│ ├── jest.config.ts
│ ├── .eslintrc.json
│ ├── package.json
│ ├── README.md
│ ├── project.json
│ └── generators.json
├── nx-oc
│ ├── .babelrc
│ ├── src
│ │ ├── pipeline-envs.ts
│ │ ├── adsp
│ │ │ ├── index.ts
│ │ │ ├── adsp.d.ts
│ │ │ └── environments.ts
│ │ ├── index.ts
│ │ ├── generators
│ │ │ ├── apply-infra
│ │ │ │ ├── schema.json
│ │ │ │ ├── apply-infra.ts
│ │ │ │ └── apply-infra.spec.ts
│ │ │ ├── index.ts
│ │ │ ├── deployment
│ │ │ │ ├── node-files
│ │ │ │ │ └── Dockerfile.template
│ │ │ │ ├── frontend-files
│ │ │ │ │ └── Dockerfile.template
│ │ │ │ ├── dotnet-files
│ │ │ │ │ └── Dockerfile.template
│ │ │ │ ├── schema.d.ts
│ │ │ │ └── schema.json
│ │ │ └── pipeline
│ │ │ │ ├── actions
│ │ │ │ └── openshift
│ │ │ │ │ ├── environment.infra.yml__tmpl__
│ │ │ │ │ └── environments.yml__tmpl__
│ │ │ │ ├── schema.d.ts
│ │ │ │ ├── jenkins
│ │ │ │ ├── environments.yml__tmpl__
│ │ │ │ └── environment.infra.yml__tmpl__
│ │ │ │ ├── schema.json
│ │ │ │ ├── pipeline.ts
│ │ │ │ └── pipeline.spec.ts
│ │ ├── executors
│ │ │ └── apply
│ │ │ │ ├── schema.d.ts
│ │ │ │ ├── schema.json
│ │ │ │ ├── apply.spec.ts
│ │ │ │ └── apply.ts
│ │ └── utils
│ │ │ ├── git-utils.ts
│ │ │ └── oc-utils.ts
│ ├── tsconfig.json
│ ├── tsconfig.lib.json
│ ├── executors.json
│ ├── .eslintrc.json
│ ├── jest.config.ts
│ ├── tsconfig.spec.json
│ ├── .releaserc.json
│ ├── README.md
│ ├── package.json
│ ├── generators.json
│ └── project.json
├── nx-release
│ ├── .babelrc
│ ├── src
│ │ ├── index.ts
│ │ ├── generators
│ │ │ └── lib
│ │ │ │ ├── schema.d.ts
│ │ │ │ ├── root-files
│ │ │ │ └── .releaserc.json__tmpl__
│ │ │ │ ├── files
│ │ │ │ └── .releaserc.json__tmpl__
│ │ │ │ ├── schema.json
│ │ │ │ ├── lib.spec.ts
│ │ │ │ └── lib.ts
│ │ └── release-plugin
│ │ │ ├── index.ts
│ │ │ ├── git-utils.ts
│ │ │ ├── git-utils.spec.ts
│ │ │ ├── types.d.ts
│ │ │ ├── nx-utils.spec.ts
│ │ │ ├── nx-util.ts
│ │ │ ├── wrap-plugin.ts
│ │ │ └── wrap-plugin.spec.ts
│ ├── tsconfig.json
│ ├── generators.json
│ ├── tsconfig.lib.json
│ ├── .eslintrc.json
│ ├── jest.config.ts
│ ├── tsconfig.spec.json
│ ├── .releaserc.json
│ ├── package.json
│ ├── README.md
│ └── project.json
└── semantic-release-nuget
│ ├── .babelrc
│ ├── src
│ ├── index.ts
│ ├── types.d.ts
│ └── plugin
│ │ ├── config.ts
│ │ ├── prepare.ts
│ │ └── publish.ts
│ ├── tsconfig.json
│ ├── tsconfig.lib.json
│ ├── .eslintrc.json
│ ├── package.json
│ ├── tsconfig.spec.json
│ ├── jest.config.ts
│ ├── .releaserc.json
│ ├── README.md
│ └── project.json
├── .prettierrc
├── .prettierignore
├── .vscode
├── extensions.json
└── settings.json
├── e2e
├── nx-adsp-e2e
│ ├── tsconfig.json
│ ├── tsconfig.spec.json
│ ├── jest.config.js
│ ├── project.json
│ └── tests
│ │ └── nx-adsp.spec.ts
├── nx-oc-e2e
│ ├── tsconfig.spec.json
│ ├── tsconfig.json
│ ├── jest.config.js
│ ├── project.json
│ └── tests
│ │ └── nx-oc.spec.ts
└── nx-release-e2e
│ ├── tsconfig.spec.json
│ ├── tsconfig.json
│ ├── jest.config.js
│ ├── project.json
│ └── tests
│ └── nx-release.spec.ts
├── .env
├── .releaserc.json
├── jest.config.ts
├── .editorconfig
├── tools
└── tsconfig.tools.json
├── .gitignore
├── jest.preset.js
├── tsconfig.base.json
├── README.md
├── .eslintrc.json
├── nx.json
├── .github
└── workflows
│ ├── pull-request.yml
│ ├── release-ci.yml
│ └── codeql-analysis.yml
└── package.json
/docs/assets/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docs/.ruby-version:
--------------------------------------------------------------------------------
1 | 2.6.6
2 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules
2 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/index.ts:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true
3 | }
--------------------------------------------------------------------------------
/docs/.gitignore:
--------------------------------------------------------------------------------
1 | _site
2 | .sass-cache
3 | .jekyll-metadata
4 |
--------------------------------------------------------------------------------
/packages/nx-adsp/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["@nx/web/babel"]
3 | }
4 |
--------------------------------------------------------------------------------
/packages/nx-oc/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["@nx/web/babel"]
3 | }
4 |
--------------------------------------------------------------------------------
/packages/nx-release/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["@nx/web/babel"]
3 | }
4 |
--------------------------------------------------------------------------------
/packages/nx-release/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './release-plugin/index.js';
2 |
--------------------------------------------------------------------------------
/docs/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GovAlta/nx-tools/HEAD/docs/favicon.ico
--------------------------------------------------------------------------------
/packages/semantic-release-nuget/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["@nx/web/babel"]
3 | }
4 |
--------------------------------------------------------------------------------
/packages/nx-oc/src/pipeline-envs.ts:
--------------------------------------------------------------------------------
1 | export const pipelineEnvs = ['Dev', 'Test', 'Prod'];
2 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/angular-app/files/src/app/protected/protected.component.css__tmpl__:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docs/nx-oc/nx-oc.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | title: NX OpenShift plugin
4 | nav_order: 3
5 | has_children: true
6 | ---
7 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/angular-app/files/src/app/logout/logout.component.html__tmpl__:
--------------------------------------------------------------------------------
1 |
Logged Out !!
2 |
--------------------------------------------------------------------------------
/docs/nx-release/nx-release.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | title: NX Release plugin
4 | nav_order: 4
5 | has_children: true
6 | ---
7 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/utils/nginx.d.ts:
--------------------------------------------------------------------------------
1 | export interface NginxProxyConfiguration {
2 | location: string;
3 | proxyPass: string;
4 | }
5 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | # Add files here to ignore them from prettier formatting
2 |
3 | /dist
4 | /coverage
5 |
6 | /.nx/cache
7 | /.nx/workspace-data
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/react-app/files/src/renew.html__tmpl__:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/react-app/files/src/renew.ts__tmpl__:
--------------------------------------------------------------------------------
1 | import { processSilentRenew } from 'redux-oidc';
2 |
3 | processSilentRenew();
4 |
--------------------------------------------------------------------------------
/packages/nx-oc/src/adsp/index.ts:
--------------------------------------------------------------------------------
1 | export type { AdspConfiguration, AdspOptions } from './adsp';
2 | export * from './adsp-utils';
3 | export * from './environments';
4 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/react-app/files/src/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GovAlta/nx-tools/HEAD/packages/nx-adsp/src/generators/react-app/files/src/favicon.ico
--------------------------------------------------------------------------------
/packages/nx-oc/src/index.ts:
--------------------------------------------------------------------------------
1 | export { default as deploymentGenerator } from './generators/deployment/deployment';
2 | export * from './adsp';
3 | export * from './generators';
4 |
--------------------------------------------------------------------------------
/packages/semantic-release-nuget/src/index.ts:
--------------------------------------------------------------------------------
1 | import { prepare } from './plugin/prepare';
2 | import { publish } from './plugin/publish';
3 |
4 | export { prepare, publish };
5 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/angular-app/files/src/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GovAlta/nx-tools/HEAD/packages/nx-adsp/src/generators/angular-app/files/src/favicon.ico
--------------------------------------------------------------------------------
/packages/nx-adsp/src/utils/task.d.ts:
--------------------------------------------------------------------------------
1 | export interface QueueDefinition {
2 | namespace: string;
3 | name: string;
4 | assignerRoles: string[];
5 | workerRoles: string[];
6 | }
7 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/react-app/files/src/assets/banner.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GovAlta/nx-tools/HEAD/packages/nx-adsp/src/generators/react-app/files/src/assets/banner.jpg
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "ms-vscode.vscode-typescript-tslint-plugin",
4 | "esbenp.prettier-vscode",
5 | "firsttris.vscode-jest-runner"
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/angular-app/files/src/assets/banner.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GovAlta/nx-tools/HEAD/packages/nx-adsp/src/generators/angular-app/files/src/assets/banner.jpg
--------------------------------------------------------------------------------
/docs/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | # Feel free to add content and custom Front Matter to this file.
3 | # To modify the layout, see https://jekyllrb.com/docs/themes/#overriding-theme-defaults
4 |
5 | layout: home
6 | ---
7 |
8 |
--------------------------------------------------------------------------------
/e2e/nx-adsp-e2e/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.base.json",
3 | "files": [],
4 | "include": [],
5 | "references": [
6 | {
7 | "path": "./tsconfig.spec.json"
8 | }
9 | ]
10 | }
11 |
--------------------------------------------------------------------------------
/.env:
--------------------------------------------------------------------------------
1 | # Nx 18 enables using plugins to infer targets by default
2 | # This is disabled for existing workspaces to maintain compatibility
3 | # For more info, see: https://nx.dev/concepts/inferred-tasks
4 | NX_ADD_PLUGINS=false
5 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/dotnet-service/files/Examples/ServiceRoles.cs__tmpl__:
--------------------------------------------------------------------------------
1 | namespace Adsp.Sdk.Examples;
2 |
3 | public static class ServiceRoles
4 | {
5 | public const string HelloWorlder = "hello-worlder";
6 | }
7 |
--------------------------------------------------------------------------------
/packages/nx-oc/src/generators/apply-infra/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://json-schema.org/schema",
3 | "id": "NxOcApplyInfra",
4 | "title": "",
5 | "type": "object",
6 | "properties": {},
7 | "required": []
8 | }
9 |
--------------------------------------------------------------------------------
/packages/nx-release/src/generators/lib/schema.d.ts:
--------------------------------------------------------------------------------
1 | export interface Schema {
2 | project: string;
3 | }
4 |
5 | export interface NormalizedSchema extends Schema {
6 | projectRoot: string;
7 | projectDist: string;
8 | }
9 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/angular-app/files/src/app/home/home.component.html__tmpl__:
--------------------------------------------------------------------------------
1 |
2 | Public Area
3 | Making a Public API call to uptime endpoint
4 | Uptime of API in seconds: {{uptime}}
5 |
6 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/angular-app/files/src/styles.css__tmpl__:
--------------------------------------------------------------------------------
1 | /* You can add global styles to this file, and also import other style files */
2 | @import "@abgov/web-components/index.css";
3 |
4 | body {
5 | margin: 0px;
6 | }
7 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/angular-app/files/src/app/protected/protected.component.html__tmpl__:
--------------------------------------------------------------------------------
1 |
2 | Admin Area
3 | Making a Protected API call to tenant endpoint using access token
4 | Tenant Name: {{tenant.name}}
5 |
--------------------------------------------------------------------------------
/packages/nx-release/src/generators/lib/root-files/.releaserc.json__tmpl__:
--------------------------------------------------------------------------------
1 | {
2 | "branches": [
3 | "+([0-9])?(.{+([0-9]),x}).x",
4 | "main",
5 | {"name": "beta", "prerelease": true},
6 | {"name": "alpha", "prerelease": true}
7 | ]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/nx-oc/src/generators/index.ts:
--------------------------------------------------------------------------------
1 | export { default as applyInfraGenerator } from './apply-infra/apply-infra';
2 | export { default as deploymentGenerator } from './deployment/deployment';
3 | export { default as pipelineGenerator } from './pipeline/pipeline';
4 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/angular-app/files/src/test-setup.ts__tmpl__:
--------------------------------------------------------------------------------
1 | import 'zone.js';
2 | import 'zone.js/dist/zone-testing';
3 | import 'jest-preset-angular';
4 | //https://github.com/thymikee/jest-preset-angular/issues/347
5 | import '@angular/localize/init';
6 |
--------------------------------------------------------------------------------
/.releaserc.json:
--------------------------------------------------------------------------------
1 | {
2 | "repositoryUrl": "git@github.com:GovAlta/nx-tools.git",
3 | "branches": [
4 | "+([0-9])?(.{+([0-9]),x}).x",
5 | "main",
6 | {"name": "beta", "prerelease": true},
7 | {"name": "alpha", "prerelease": true}
8 | ]
9 | }
10 |
--------------------------------------------------------------------------------
/e2e/nx-oc-e2e/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../../dist/out-tsc",
5 | "module": "commonjs",
6 | "types": ["jest", "node"]
7 | },
8 | "include": ["**/*.spec.ts", "**/*.d.ts"]
9 | }
10 |
--------------------------------------------------------------------------------
/e2e/nx-adsp-e2e/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../../dist/out-tsc",
5 | "module": "commonjs",
6 | "types": ["jest", "node"]
7 | },
8 | "include": ["**/*.spec.ts", "**/*.d.ts"]
9 | }
10 |
--------------------------------------------------------------------------------
/e2e/nx-release-e2e/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../../dist/out-tsc",
5 | "module": "commonjs",
6 | "types": ["jest", "node"]
7 | },
8 | "include": ["**/*.spec.ts", "**/*.d.ts"]
9 | }
10 |
--------------------------------------------------------------------------------
/jest.config.ts:
--------------------------------------------------------------------------------
1 | const { getJestProjects } = require('@nx/jest');
2 |
3 | export default {
4 | projects: [
5 | ...getJestProjects(),
6 | '/e2e/nx-adsp-e2e',
7 | '/e2e/nx-oc-e2e',
8 | '/e2e/nx-release-e2e',
9 | ],
10 | };
11 |
--------------------------------------------------------------------------------
/packages/nx-oc/src/adsp/adsp.d.ts:
--------------------------------------------------------------------------------
1 | export interface AdspConfiguration {
2 | tenant: string;
3 | tenantRealm: string;
4 | accessServiceUrl: string;
5 | directoryServiceUrl: string;
6 | }
7 |
8 | export type AdspOptions = {
9 | adsp: AdspConfiguration;
10 | };
11 |
--------------------------------------------------------------------------------
/e2e/nx-oc-e2e/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.base.json",
3 | "files": [],
4 | "include": [],
5 | "references": [
6 | {
7 | "path": "./tsconfig.e2e.json"
8 | },
9 | {
10 | "path": "./tsconfig.spec.json"
11 | }
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/packages/nx-adsp/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.base.json",
3 | "files": [],
4 | "include": [],
5 | "references": [
6 | {
7 | "path": "./tsconfig.lib.json"
8 | },
9 | {
10 | "path": "./tsconfig.spec.json"
11 | }
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/packages/nx-oc/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.base.json",
3 | "files": [],
4 | "include": [],
5 | "references": [
6 | {
7 | "path": "./tsconfig.lib.json"
8 | },
9 | {
10 | "path": "./tsconfig.spec.json"
11 | }
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/docs/nx-adsp/nx-adsp.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | title: NX ADSP plugin
4 | nav_order: 2
5 | has_children: true
6 | ---
7 |
8 | # NX ADSP plugin
9 |
10 | ## Overview
11 |
12 | [Alberta Digital Service Platform (ADSP)](https://adsp.alberta.ca)
13 |
14 | `npm i -D @abgov/nx-adsp`
15 |
--------------------------------------------------------------------------------
/e2e/nx-release-e2e/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.base.json",
3 | "files": [],
4 | "include": [],
5 | "references": [
6 | {
7 | "path": "./tsconfig.e2e.json"
8 | },
9 | {
10 | "path": "./tsconfig.spec.json"
11 | }
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/packages/nx-oc/src/generators/deployment/node-files/Dockerfile.template:
--------------------------------------------------------------------------------
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
9 |
--------------------------------------------------------------------------------
/packages/nx-release/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.base.json",
3 | "files": [],
4 | "include": [],
5 | "references": [
6 | {
7 | "path": "./tsconfig.lib.json"
8 | },
9 | {
10 | "path": "./tsconfig.spec.json"
11 | }
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/packages/semantic-release-nuget/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.base.json",
3 | "files": [],
4 | "include": [],
5 | "references": [
6 | {
7 | "path": "./tsconfig.lib.json"
8 | },
9 | {
10 | "path": "./tsconfig.spec.json"
11 | }
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # Editor configuration, see http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | charset = utf-8
6 | indent_style = space
7 | indent_size = 2
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
11 | [*.md]
12 | max_line_length = off
13 | trim_trailing_whitespace = false
14 |
--------------------------------------------------------------------------------
/packages/nx-oc/src/generators/pipeline/actions/openshift/environment.infra.yml__tmpl__:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: List
3 | items:
4 | - apiVersion: v1
5 | kind: ServiceAccount
6 | metadata:
7 | labels:
8 | app: pipeline
9 | name: github-actions
10 | namespace: <%= ocInfraProject %>
11 |
--------------------------------------------------------------------------------
/packages/nx-oc/src/generators/deployment/frontend-files/Dockerfile.template:
--------------------------------------------------------------------------------
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;"
9 |
--------------------------------------------------------------------------------
/tools/tsconfig.tools.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.base.json",
3 | "compilerOptions": {
4 | "outDir": "../dist/out-tsc/tools",
5 | "rootDir": ".",
6 | "module": "commonjs",
7 | "target": "es5",
8 | "types": ["node"],
9 | "importHelpers": false
10 | },
11 | "include": ["**/*.ts"]
12 | }
13 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/angular-app/files/src/app/logout/logout.component.ts__tmpl__:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: '<%= projectName %>-app-logout',
5 | templateUrl: 'logout.component.html',
6 | })
7 | export class LogoutComponent {
8 | isAuthenticated = false;
9 | }
10 |
--------------------------------------------------------------------------------
/packages/nx-oc/src/executors/apply/schema.d.ts:
--------------------------------------------------------------------------------
1 | export interface PipelineEnvironment {
2 | project: string;
3 | tag: string;
4 | }
5 |
6 | export interface Schema {
7 | ocProject: string | string[] | PipelineEnvironment[];
8 | }
9 |
10 | export interface NormalizedSchema {
11 | ocProjects: PipelineEnvironment[];
12 | }
13 |
--------------------------------------------------------------------------------
/packages/nx-oc/src/generators/deployment/dotnet-files/Dockerfile.template:
--------------------------------------------------------------------------------
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}
11 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/dotnet-service/files/Examples/HelloWorldConfiguration.cs__tmpl__:
--------------------------------------------------------------------------------
1 | using System.Text.Json.Serialization;
2 |
3 | namespace Adsp.Sdk.Examples;
4 |
5 | public class HelloWorldConfiguration
6 | {
7 | [JsonPropertyName("responses")]
8 | public Dictionary? Responses { get; set; }
9 | }
10 |
--------------------------------------------------------------------------------
/packages/nx-adsp/tsconfig.lib.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "module": "commonjs",
5 | "outDir": "../../dist/out-tsc",
6 | "declaration": true,
7 | "types": ["node"]
8 | },
9 | "exclude": ["**/*.spec.ts", "**/*.test.ts", "jest.config.ts"],
10 | "include": ["**/*.ts"]
11 | }
12 |
--------------------------------------------------------------------------------
/packages/nx-oc/tsconfig.lib.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "module": "commonjs",
5 | "outDir": "../../dist/out-tsc",
6 | "declaration": true,
7 | "types": ["node"]
8 | },
9 | "exclude": ["**/*.spec.ts", "**/*.test.ts", "jest.config.ts"],
10 | "include": ["**/*.ts"]
11 | }
12 |
--------------------------------------------------------------------------------
/packages/nx-oc/executors.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://json-schema.org/schema",
3 | "executors": {
4 | "apply": {
5 | "implementation": "./src/executors/apply/apply",
6 | "schema": "./src/executors/apply/schema.json",
7 | "description": "Executor that applies deployment template to OpenShift."
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/packages/semantic-release-nuget/tsconfig.lib.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "module": "commonjs",
5 | "outDir": "../../dist/out-tsc",
6 | "declaration": true,
7 | "types": ["node"]
8 | },
9 | "exclude": ["**/*.spec.ts", "**/*.test.ts", "jest.config.ts"],
10 | "include": ["**/*.ts"]
11 | }
12 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/angular-app/files/src/app/auth-callback/auth-callback.component.css__tmpl__:
--------------------------------------------------------------------------------
1 | .info {
2 | display: flex;
3 | flex-direction: column;
4 | justify-content: center;
5 | }
6 |
7 | .token {
8 | font-family: monospace;
9 | background-color: beige;
10 | width: 600px;
11 | text-align: left;
12 | word-break: break-all;
13 | }
14 |
--------------------------------------------------------------------------------
/packages/nx-oc/src/utils/git-utils.ts:
--------------------------------------------------------------------------------
1 | import { execSync } from 'child_process'
2 |
3 | export function getGitRemoteUrl(): string {
4 | try {
5 | const stdout = execSync(
6 | "git config --get remote.origin.url",
7 | { stdio: "pipe" }
8 | ).toString()
9 |
10 | return stdout
11 | } catch (e) {
12 | console.log(`Failed to execute git`, e)
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/dotnet-service/schema.d.ts:
--------------------------------------------------------------------------------
1 | import type { AdspConfiguration, EnvironmentName } from '@abgov/nx-oc';
2 |
3 | export interface Schema {
4 | name: string;
5 | env: EnvironmentName;
6 | accessToken?: string;
7 | }
8 |
9 | export interface NormalizedSchema extends Schema {
10 | projectName: string;
11 | projectRoot: string;
12 | adsp: AdspConfiguration;
13 | }
14 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/express-service/schema.d.ts:
--------------------------------------------------------------------------------
1 | import type { AdspConfiguration, EnvironmentName } from '@abgov/nx-oc';
2 |
3 | export interface Schema {
4 | name: string;
5 | env: EnvironmentName;
6 | accessToken?: string;
7 | }
8 |
9 | export interface NormalizedSchema extends Schema {
10 | projectName: string;
11 | projectRoot: string;
12 | adsp: AdspConfiguration;
13 | }
14 |
--------------------------------------------------------------------------------
/packages/nx-release/generators.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://json-schema.org/schema",
3 | "name": "nx-release",
4 | "version": "0.0.1",
5 | "generators": {
6 | "lib": {
7 | "factory": "./src/generators/lib/lib",
8 | "schema": "./src/generators/lib/schema.json",
9 | "description": "Generator that adds release target to a node library project."
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/packages/nx-release/tsconfig.lib.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "target": "ES2020",
5 | "module": "ES2020",
6 | "outDir": "../../dist/out-tsc",
7 | "esModuleInterop": true,
8 | "declaration": true,
9 | "types": ["node"]
10 | },
11 | "exclude": ["**/*.spec.ts", "**/*.test.ts", "jest.config.ts"],
12 | "include": ["**/*.ts"]
13 | }
14 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/react-form/schema.d.ts:
--------------------------------------------------------------------------------
1 | import { EnvironmentName } from '@abgov/nx-oc';
2 | import { FormDefinition } from '../../utils/form';
3 |
4 | export interface Schema {
5 | project: string;
6 | env: EnvironmentName;
7 | accessToken?: string;
8 | }
9 |
10 | export interface NormalizedSchema extends Schema {
11 | projectRoot: string;
12 | formDefinition: FormDefinition;
13 | }
14 |
--------------------------------------------------------------------------------
/packages/nx-oc/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["../../.eslintrc.json"],
3 | "ignorePatterns": ["!**/*"],
4 | "overrides": [
5 | {
6 | "files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
7 | "rules": {}
8 | },
9 | {
10 | "files": ["*.ts", "*.tsx"],
11 | "rules": {}
12 | },
13 | {
14 | "files": ["*.js", "*.jsx"],
15 | "rules": {}
16 | }
17 | ]
18 | }
19 |
--------------------------------------------------------------------------------
/packages/nx-release/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["../../.eslintrc.json"],
3 | "ignorePatterns": ["!**/*"],
4 | "overrides": [
5 | {
6 | "files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
7 | "rules": {}
8 | },
9 | {
10 | "files": ["*.ts", "*.tsx"],
11 | "rules": {}
12 | },
13 | {
14 | "files": ["*.js", "*.jsx"],
15 | "rules": {}
16 | }
17 | ]
18 | }
19 |
--------------------------------------------------------------------------------
/e2e/nx-oc-e2e/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | displayName: 'nx-oc-e2e',
3 | preset: '../../jest.preset.js',
4 | globals: {},
5 | transform: {
6 | '^.+\\.[tj]s$': [
7 | 'ts-jest',
8 | {
9 | tsConfig: '/tsconfig.spec.json',
10 | },
11 | ],
12 | },
13 | moduleFileExtensions: ['ts', 'js', 'html'],
14 | coverageDirectory: '../../coverage/e2e/nx-oc-e2e',
15 | };
16 |
--------------------------------------------------------------------------------
/packages/nx-oc/jest.config.ts:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | export default {
3 | displayName: 'nx-oc',
4 | preset: '../../jest.preset.js',
5 | globals: {},
6 | transform: {
7 | '^.+\\.[tj]sx?$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }],
8 | },
9 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
10 | coverageDirectory: '../../coverage/packages/nx-oc',
11 | testEnvironment: 'node',
12 | };
13 |
--------------------------------------------------------------------------------
/packages/nx-release/src/generators/lib/files/.releaserc.json__tmpl__:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "<%= offsetFromRoot %>.releaserc.json",
3 | "tagFormat": "<%= project %>-v${version}",
4 | "plugins": [
5 | ["@abgov/nx-release", {
6 | "project": "<%= project %>"
7 | }],
8 | ["@semantic-release/npm", {
9 | "pkgRoot": "<%= projectDist %>"
10 | }],
11 | "@semantic-release/github"
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/e2e/nx-adsp-e2e/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | displayName: 'nx-adsp-e2e',
3 | preset: '../../jest.preset.js',
4 | globals: {},
5 | transform: {
6 | '^.+\\.[tj]s$': [
7 | 'ts-jest',
8 | {
9 | tsConfig: '/tsconfig.spec.json',
10 | },
11 | ],
12 | },
13 | moduleFileExtensions: ['ts', 'js', 'html'],
14 | coverageDirectory: '../../coverage/e2e/nx-adsp-e2e',
15 | };
16 |
--------------------------------------------------------------------------------
/packages/nx-oc/src/generators/pipeline/schema.d.ts:
--------------------------------------------------------------------------------
1 | export interface Schema {
2 | pipeline: string;
3 | type: string;
4 | infra: string;
5 | envs: string;
6 | apply?: boolean;
7 | }
8 |
9 | export interface NormalizedSchema extends Schema {
10 | ocPipelineName: string;
11 | ocInfraProject: string;
12 | ocEnvProjects: string[];
13 | applyPipeline: boolean;
14 | pipelineType: 'jenkins' | 'actions';
15 | }
16 |
--------------------------------------------------------------------------------
/packages/semantic-release-nuget/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["../../.eslintrc.json"],
3 | "ignorePatterns": ["!**/*"],
4 | "overrides": [
5 | {
6 | "files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
7 | "rules": {}
8 | },
9 | {
10 | "files": ["*.ts", "*.tsx"],
11 | "rules": {}
12 | },
13 | {
14 | "files": ["*.js", "*.jsx"],
15 | "rules": {}
16 | }
17 | ]
18 | }
19 |
--------------------------------------------------------------------------------
/e2e/nx-release-e2e/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | displayName: 'nx-release-e2e',
3 | preset: '../../jest.preset.js',
4 | globals: {},
5 | transform: {
6 | '^.+\\.[tj]s$': [
7 | 'ts-jest',
8 | {
9 | tsConfig: '/tsconfig.spec.json',
10 | },
11 | ],
12 | },
13 | moduleFileExtensions: ['ts', 'js', 'html'],
14 | coverageDirectory: '../../coverage/e2e/nx-release-e2e',
15 | };
16 |
--------------------------------------------------------------------------------
/packages/nx-release/jest.config.ts:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | export default {
3 | displayName: 'nx-release',
4 | preset: '../../jest.preset.js',
5 | globals: {},
6 | transform: {
7 | '^.+\\.[tj]sx?$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }],
8 | },
9 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
10 | coverageDirectory: '../../coverage/packages/nx-release',
11 | testEnvironment: 'node',
12 | };
13 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/react-task-list/schema.d.ts:
--------------------------------------------------------------------------------
1 | import { EnvironmentName } from '@abgov/nx-oc';
2 | import { QueueDefinition } from '../../utils/task';
3 |
4 | export interface Schema {
5 | project: string;
6 | env: EnvironmentName;
7 | accessToken?: string;
8 | }
9 |
10 | export interface NormalizedSchema extends Schema {
11 | projectRoot: string;
12 | queueDefinition: QueueDefinition;
13 | updateStreamId: string;
14 | }
15 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/mern/schema.d.ts:
--------------------------------------------------------------------------------
1 | import { AdspConfiguration, EnvironmentName } from '@abgov/nx-oc';
2 |
3 | export interface Schema {
4 | name: string;
5 | env: EnvironmentName;
6 | accessToken?: string;
7 | }
8 |
9 | export interface NormalizedSchema extends Schema {
10 | projectName: string;
11 | projectRoot: string;
12 | projectDirectory: string;
13 | openshiftDirectory: string;
14 | adsp: AdspConfiguration;
15 | }
16 |
--------------------------------------------------------------------------------
/packages/semantic-release-nuget/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@abgov/semantic-release-nuget",
3 | "version": "0.0.0",
4 | "license": "Apache-2.0",
5 | "main": "src/index.js",
6 | "description": "Government of Alberta - Semantic release plugin for nuget.",
7 | "repository": {
8 | "type": "git",
9 | "url": "git+https://github.com/GovAlta/nx-tools.git",
10 | "directory": "packages/semantic-release-nuget"
11 | },
12 | "scripts": {}
13 | }
--------------------------------------------------------------------------------
/packages/semantic-release-nuget/src/types.d.ts:
--------------------------------------------------------------------------------
1 | declare namespace SemanticRelease {
2 | import type { BaseContext } from 'semantic-release';
3 |
4 | type PluginConfig = Record;
5 |
6 | type PluginFunction = (
7 | pluginConfig: PluginConfig,
8 | context: T
9 | ) => Promise;
10 | }
11 |
12 | declare module '@semantic-release/semantic-release' {
13 | export = SemanticRelease;
14 | }
15 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/react-dotnet/schema.d.ts:
--------------------------------------------------------------------------------
1 | import type { AdspConfiguration, EnvironmentName } from '@abgov/nx-oc';
2 |
3 | export interface Schema {
4 | name: string;
5 | env: EnvironmentName;
6 | accessToken?: string;
7 | }
8 |
9 | export interface NormalizedSchema extends Schema {
10 | projectName: string;
11 | projectRoot: string;
12 | projectDirectory: string;
13 | openshiftDirectory: string;
14 | adsp: AdspConfiguration;
15 | }
16 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/react-app/files/src/react-oidc.d.ts__tmpl__:
--------------------------------------------------------------------------------
1 | // Declarations to allow redux-oidc to work with react 18
2 | declare module 'redux-oidc' {
3 | export interface CallbackComponentProps {
4 | children: React.ReactNode;
5 | }
6 |
7 | export interface OidcProviderProps {
8 | children: React.ReactNode;
9 | }
10 |
11 | export interface SignoutCallbackComponentProps {
12 | children: React.ReactNode;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/angular-app/files/src/app/auth-callback/auth-callback.component.html__tmpl__:
--------------------------------------------------------------------------------
1 | Redirected to auth-callback route!
2 | Now you are logged in and allowed to access the "protected" route...
3 |
4 |
5 |
Token Type:
6 |
{{ tokenType }}
7 |
8 |
9 |
Token:
10 |
{{ accessToken }}
11 |
12 |
13 |
--------------------------------------------------------------------------------
/packages/semantic-release-nuget/src/plugin/config.ts:
--------------------------------------------------------------------------------
1 | import { PluginConfig } from '@semantic-release/semantic-release';
2 |
3 | export interface NugetPluginConfig extends PluginConfig {
4 | configuration: string;
5 | noBuild: boolean;
6 | project: string;
7 | includeSymbols: boolean;
8 | includeSource: boolean;
9 | serviceable: boolean;
10 | nupkgRoot: string;
11 | source: string;
12 | symbolSource: string;
13 | skipDuplicate: boolean;
14 | timeout: number;
15 | }
16 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/angular-app/files/src/main.ts__tmpl__:
--------------------------------------------------------------------------------
1 | import { enableProdMode } from '@angular/core';
2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
3 |
4 | import { AppModule } from './app/app.module';
5 | import { environment } from './environments/environment';
6 |
7 | if (environment.production) {
8 | enableProdMode();
9 | }
10 |
11 | platformBrowserDynamic()
12 | .bootstrapModule(AppModule)
13 | .catch((err) => console.error(err));
14 |
--------------------------------------------------------------------------------
/packages/nx-adsp/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../../dist/out-tsc",
5 | "module": "commonjs",
6 | "types": ["jest", "node"]
7 | },
8 | "include": [
9 | "**/*.spec.ts",
10 | "**/*.test.ts",
11 | "**/*.spec.tsx",
12 | "**/*.test.tsx",
13 | "**/*.spec.js",
14 | "**/*.test.js",
15 | "**/*.spec.jsx",
16 | "**/*.test.jsx",
17 | "**/*.d.ts",
18 | "jest.config.ts"
19 | ]
20 | }
21 |
--------------------------------------------------------------------------------
/packages/nx-oc/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../../dist/out-tsc",
5 | "module": "commonjs",
6 | "types": ["jest", "node"]
7 | },
8 | "include": [
9 | "**/*.spec.ts",
10 | "**/*.test.ts",
11 | "**/*.spec.tsx",
12 | "**/*.test.tsx",
13 | "**/*.spec.js",
14 | "**/*.test.js",
15 | "**/*.spec.jsx",
16 | "**/*.test.jsx",
17 | "**/*.d.ts",
18 | "jest.config.ts"
19 | ]
20 | }
21 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/express-service/files/src/environments/environment.prod.ts__tmpl__:
--------------------------------------------------------------------------------
1 | import * as dotenv from 'dotenv';
2 | dotenv.config();
3 |
4 | export const environment = {
5 | production: true,
6 | TENANT_REALM: '<%= tenantRealm %>',
7 | ACCESS_SERVICE_URL: '<%= accessServiceUrl %>',
8 | DIRECTORY_SERVICE_URL: '<%= directoryServiceUrl %>',
9 | CLIENT_ID: 'urn:ads:<%= tenant %>:<%= projectName %>',
10 | CLIENT_SECRET: '',
11 | LOG_LEVEL: 'info',
12 | ...process.env,
13 | };
14 |
--------------------------------------------------------------------------------
/packages/semantic-release-nuget/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../../dist/out-tsc",
5 | "module": "commonjs",
6 | "types": ["jest", "node"]
7 | },
8 | "include": [
9 | "**/*.spec.ts",
10 | "**/*.test.ts",
11 | "**/*.spec.tsx",
12 | "**/*.test.tsx",
13 | "**/*.spec.js",
14 | "**/*.test.js",
15 | "**/*.spec.jsx",
16 | "**/*.test.jsx",
17 | "**/*.d.ts",
18 | "jest.config.ts"
19 | ]
20 | }
21 |
--------------------------------------------------------------------------------
/docs/404.html:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | ---
4 |
5 |
18 |
19 |
20 |
404
21 |
22 |
Page not found :(
23 |
The requested page could not be found.
24 |
25 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/dotnet-service/files/appsettings.Development.json__tmpl__:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft.AspNetCore": "Warning"
6 | }
7 | },
8 | "Adsp": {
9 | "AccessServiceUrl": "<%= accessServiceUrl %>",
10 | "Realm": "<%= tenantRealm %>",
11 | "DirectoryUrl": "<%= directoryServiceUrl %>",
12 | "ClientId": "urn:ads:<%= tenant %>:<%= projectName %>",
13 | "ClientSecret": ""
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/packages/nx-release/src/generators/lib/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://json-schema.org/schema",
3 | "id": "NxRelease",
4 | "title": "",
5 | "type": "object",
6 | "properties": {
7 | "project": {
8 | "type": "string",
9 | "description": "",
10 | "$default": {
11 | "$source": "argv",
12 | "index": 0
13 | },
14 | "x-prompt": "Which project do you want to add semantic release to?"
15 | }
16 | },
17 | "required": [
18 | "project"
19 | ]
20 | }
21 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/express-service/files/src/environments/environment.ts__tmpl__:
--------------------------------------------------------------------------------
1 | import * as dotenv from 'dotenv';
2 | dotenv.config();
3 |
4 | export const environment = {
5 | production: false,
6 | port: '3333',
7 | TENANT_REALM: '<%= tenantRealm %>',
8 | ACCESS_SERVICE_URL: '<%= accessServiceUrl %>',
9 | DIRECTORY_SERVICE_URL: '<%= directoryServiceUrl %>',
10 | CLIENT_ID: 'urn:ads:<%= tenant %>:<%= projectName %>',
11 | CLIENT_SECRET: '',
12 | LOG_LEVEL: 'debug',
13 | ...process.env
14 | };
15 |
--------------------------------------------------------------------------------
/packages/semantic-release-nuget/jest.config.ts:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | export default {
3 | displayName: 'semantic-release-nuget',
4 | preset: '../../jest.preset.js',
5 | globals: {},
6 | testEnvironment: 'node',
7 | transform: {
8 | '^.+\\.[tj]sx?$': [
9 | 'ts-jest',
10 | {
11 | tsconfig: '/tsconfig.spec.json',
12 | },
13 | ],
14 | },
15 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
16 | coverageDirectory: '../../coverage/packages/semantic-release-nuget',
17 | };
18 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/dotnet-service/files/appsettings.json__tmpl__:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft.AspNetCore": "Warning"
6 | }
7 | },
8 | "Adsp": {
9 | "AccessServiceUrl": "<%= accessServiceUrl %>",
10 | "Realm": "<%= tenantRealm %>",
11 | "DirectoryUrl": "<%= directoryServiceUrl %>",
12 | "ClientId": "urn:ads:<%= tenant %>:<%= projectName %>",
13 | "ClientSecret": ""
14 | },
15 | "AllowedHosts": "*"
16 | }
17 |
--------------------------------------------------------------------------------
/packages/nx-release/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../../dist/out-tsc",
5 | "module": "commonjs",
6 | "esModuleInterop": true,
7 | "types": ["jest", "node"]
8 | },
9 | "include": [
10 | "**/*.spec.ts",
11 | "**/*.test.ts",
12 | "**/*.spec.tsx",
13 | "**/*.test.tsx",
14 | "**/*.spec.js",
15 | "**/*.test.js",
16 | "**/*.spec.jsx",
17 | "**/*.test.jsx",
18 | "**/*.d.ts",
19 | "jest.config.ts"
20 | ]
21 | }
22 |
--------------------------------------------------------------------------------
/packages/nx-oc/.releaserc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../.releaserc.json",
3 | "tagFormat": "nx-oc-v${version}",
4 | "plugins": [
5 | [
6 | "@abgov/nx-release",
7 | {
8 | "project": "nx-oc"
9 | }
10 | ],
11 | [
12 | "@semantic-release/npm",
13 | {
14 | "pkgRoot": "dist/packages/nx-oc"
15 | }
16 | ],
17 | [
18 | "@semantic-release/github",
19 | {
20 | "releasedLabels": false,
21 | "successComment": false
22 | }
23 | ]
24 | ]
25 | }
26 |
--------------------------------------------------------------------------------
/packages/nx-adsp/.releaserc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../.releaserc.json",
3 | "tagFormat": "nx-adsp-v${version}",
4 | "plugins": [
5 | [
6 | "@abgov/nx-release",
7 | {
8 | "project": "nx-adsp"
9 | }
10 | ],
11 | [
12 | "@semantic-release/npm",
13 | {
14 | "pkgRoot": "dist/packages/nx-adsp"
15 | }
16 | ],
17 | [
18 | "@semantic-release/github",
19 | {
20 | "releasedLabels": false,
21 | "successComment": false
22 | }
23 | ]
24 | ]
25 | }
26 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/react-app/files/src/environments/environment.ts__tmpl__:
--------------------------------------------------------------------------------
1 | // This file can be replaced during build by using the `fileReplacements` array.
2 | // When building for production, this file is replaced with `environment.prod.ts`.
3 |
4 | export const environment = {
5 | production: false,
6 | directory: {
7 | url: '<%= directoryServiceUrl %>',
8 | },
9 | access: {
10 | url: '<%= accessServiceUrl %>',
11 | realm: '<%= tenantRealm %>',
12 | client_id: 'urn:ads:<%= tenant %>:<%= projectName %>'
13 | }
14 | };
15 |
--------------------------------------------------------------------------------
/packages/nx-release/.releaserc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../.releaserc.json",
3 | "tagFormat": "nx-release-v${version}",
4 | "plugins": [
5 | [
6 | "@abgov/nx-release",
7 | {
8 | "project": "nx-release"
9 | }
10 | ],
11 | [
12 | "@semantic-release/npm",
13 | {
14 | "pkgRoot": "dist/packages/nx-release"
15 | }
16 | ],
17 | [
18 | "@semantic-release/github",
19 | {
20 | "releasedLabels": false,
21 | "successComment": false
22 | }
23 | ]
24 | ]
25 | }
26 |
--------------------------------------------------------------------------------
/packages/nx-oc/src/generators/deployment/schema.d.ts:
--------------------------------------------------------------------------------
1 | import { AdspConfiguration } from '../../adsp';
2 |
3 | export type ApplicationType = 'node' | 'dotnet' | 'frontend';
4 |
5 | export interface Schema {
6 | project: string;
7 | appType?: ApplicationType;
8 | env: EnvironmentName;
9 | adsp?: AdspConfiguration;
10 | accessToken?: string;
11 | }
12 |
13 | export interface NormalizedSchema extends Schema {
14 | projectName: string;
15 | appType: ApplicationType;
16 | ocInfraProject: string;
17 | ocEnvProjects: string[];
18 | adsp: AdspConfiguration;
19 | }
20 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/angular-app/schema.d.ts:
--------------------------------------------------------------------------------
1 | import type { AdspConfiguration, EnvironmentName } from '@abgov/nx-oc';
2 |
3 | export interface AngularAppGeneratorSchema {
4 | name: string;
5 | env: EnvironmentName;
6 | accessToken?: string;
7 | proxy?: NginxProxyConfiguration | NginxProxyConfiguration[];
8 | }
9 |
10 | export interface NormalizedSchema extends AngularAppGeneratorSchema {
11 | projectName: string;
12 | projectRoot: string;
13 | openshiftDirectory: string;
14 | adsp: AdspConfiguration;
15 | nginxProxies: NginxProxyConfiguration[];
16 | }
17 |
--------------------------------------------------------------------------------
/packages/nx-release/src/release-plugin/index.ts:
--------------------------------------------------------------------------------
1 | import type { AnalyzeCommitsContext, GenerateNotesContext } from 'semantic-release';
2 | import { analyzeCommits as baseAnalyzeCommits } from '@semantic-release/commit-analyzer';
3 | import { generateNotes as baseGenerateNotes } from '@semantic-release/release-notes-generator';
4 | import { wrapPlugin } from './wrap-plugin.js';
5 |
6 | const analyzeCommits = wrapPlugin(baseAnalyzeCommits);
7 | const generateNotes = wrapPlugin(baseGenerateNotes);
8 |
9 | export { analyzeCommits, generateNotes };
10 |
--------------------------------------------------------------------------------
/packages/nx-adsp/jest.config.ts:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | export default {
3 | displayName: 'nx-adsp',
4 | preset: '../../jest.preset.js',
5 | globals: {},
6 | transform: {
7 | '^.+\\.[tj]sx?$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }],
8 | },
9 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json'],
10 | moduleNameMapper: {
11 | '@nx/angular/src/utils/test-runners':
12 | '/../../node_modules/@nx/angular/src/utils/test-runners.js',
13 | },
14 | coverageDirectory: '../../coverage/packages/nx-adsp',
15 | testEnvironment: 'node',
16 | };
17 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/utils/form.ts:
--------------------------------------------------------------------------------
1 | import { compile } from 'json-schema-to-typescript';
2 |
3 | export interface FormDefinition {
4 | id: string;
5 | name: string;
6 | dataSchema: Record;
7 | assessorRoles: string[];
8 | applicantRoles: string[];
9 | }
10 |
11 | export async function generateFormInterface({
12 | name,
13 | dataSchema,
14 | }: FormDefinition): Promise {
15 | const types = await compile(dataSchema, name, {
16 | additionalProperties: false,
17 | bannerComment: '',
18 | format: false,
19 | });
20 |
21 | return types;
22 | }
23 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/react-app/schema.d.ts:
--------------------------------------------------------------------------------
1 | import { AdspConfiguration, EnvironmentName } from '@abgov/nx-oc';
2 | import { NginxProxyConfiguration } from '../../utils/nginx';
3 |
4 | export interface Schema {
5 | name: string;
6 | env: EnvironmentName;
7 | accessToken?: string;
8 | proxy?: NginxProxyConfiguration | NginxProxyConfiguration[];
9 | }
10 |
11 | export interface NormalizedSchema extends Schema {
12 | projectName: string;
13 | projectRoot: string;
14 | openshiftDirectory: string;
15 | adsp: AdspConfiguration;
16 | nginxProxies: NginxProxyConfiguration[];
17 | }
18 |
--------------------------------------------------------------------------------
/packages/semantic-release-nuget/.releaserc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../.releaserc.json",
3 | "tagFormat": "semantic-release-nuget-v${version}",
4 | "plugins": [
5 | [
6 | "@abgov/nx-release",
7 | {
8 | "project": "semantic-release-nuget"
9 | }
10 | ],
11 | [
12 | "@semantic-release/npm",
13 | {
14 | "pkgRoot": "dist/packages/semantic-release-nuget"
15 | }
16 | ],
17 | [
18 | "@semantic-release/github",
19 | {
20 | "releasedLabels": false,
21 | "successComment": false
22 | }
23 | ]
24 | ]
25 | }
26 |
--------------------------------------------------------------------------------
/packages/nx-oc/README.md:
--------------------------------------------------------------------------------
1 | # About this project
2 | This is the Government of Alberta - Nx plugin for OpenShift.
3 |
4 | The plugin includes generators for setting up OpenShift pipeline and application yaml files, and executors for `oc cli` commands.
5 |
6 | ## TLDR
7 |
8 | 1. Create your Nx workspace using `npx create-nx-workspace my-workspace`
9 | 2. Install plugin: `npm i -D @abgov/nx-oc`
10 | 3. Login to OpenShift: `oc login {url} --token={token}`
11 | 4. Generate basic infrastructure yml and apply it: `npx nx g @abgov/nx-oc:pipeline`
12 | 5. Set up OpenShift yml on apps using `npx nx g @abgov/nx-oc:deployment`
13 |
14 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/dotnet-service/files/Examples/HelloWorldEvent.cs__tmpl__:
--------------------------------------------------------------------------------
1 | using System.Text.Json.Serialization;
2 |
3 | namespace Adsp.Sdk.Examples;
4 |
5 | public class HelloWorldEvent
6 | {
7 | public const string EventName = "hello-world-event";
8 |
9 | [JsonPropertyName("fromUserId")]
10 | public string? FromUserId { get; set; }
11 |
12 | [JsonPropertyName("fromUser")]
13 | public string? FromUser { get; set; }
14 |
15 | [JsonPropertyName("message")]
16 | public string? Message { get; set; }
17 |
18 | [JsonPropertyName("response")]
19 | public string? Response { get; set; }
20 | }
21 |
--------------------------------------------------------------------------------
/e2e/nx-oc-e2e/project.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "nx-oc-e2e",
3 | "$schema": "../../node_modules/nx/schemas/project-schema.json",
4 | "projectType": "application",
5 | "sourceRoot": "e2e/nx-oc-e2e/src",
6 | "targets": {
7 | "e2e": {
8 | "executor": "@nx/jest:jest",
9 | "options": {
10 | "npmPackageName": "@abgov/nx-oc",
11 | "pluginOutputPath": "dist/packages/nx-oc",
12 | "jestConfig": "e2e/nx-oc-e2e/jest.config.js",
13 | "runInBand": true
14 | },
15 | "dependsOn": ["nx-oc:build"]
16 | }
17 | },
18 | "tags": [],
19 | "implicitDependencies": ["nx-oc"]
20 | }
21 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/angular-app/files/src/environments/environment.ts__tmpl__:
--------------------------------------------------------------------------------
1 | // This file can be replaced during build by using the `fileReplacements` array.
2 | // When building for production, this file is replaced with `environment.prod.ts`.
3 |
4 | export const environment = {
5 | production: false,
6 | access: {
7 | url: '<%= accessServiceUrl %>',
8 | realm: '<%= tenantRealm %>',
9 | client_id: 'urn:ads:<%= tenant %>:<%= projectName %>'
10 | },
11 | tenantApi: {
12 | host: "http://localhost:3333",
13 | endpoints: {
14 | tenantNameByRealm: "/api/tenant/v1/realm",
15 | }
16 | }
17 | };
18 |
--------------------------------------------------------------------------------
/e2e/nx-adsp-e2e/project.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "nx-adsp-e2e",
3 | "$schema": "../../node_modules/nx/schemas/project-schema.json",
4 | "projectType": "application",
5 | "sourceRoot": "e2e/nx-adsp-e2e/src",
6 | "targets": {
7 | "e2e": {
8 | "executor": "@nx/jest:jest",
9 | "options": {
10 | "npmPackageName": "@abgov/nx-adsp",
11 | "pluginOutputPath": "dist/packages/nx-adsp",
12 | "jestConfig": "e2e/nx-adsp-e2e/jest.config.js",
13 | "runInBand": true
14 | },
15 | "dependsOn": ["nx-adsp:build"]
16 | }
17 | },
18 | "tags": [],
19 | "implicitDependencies": ["nx-adsp"]
20 | }
21 |
--------------------------------------------------------------------------------
/e2e/nx-release-e2e/project.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "nx-release-e2e",
3 | "$schema": "../../node_modules/nx/schemas/project-schema.json",
4 | "projectType": "application",
5 | "sourceRoot": "e2e/nx-release-e2e/src",
6 | "targets": {
7 | "e2e": {
8 | "executor": "@nx/jest:jest",
9 | "options": {
10 | "npmPackageName": "@abgov/nx-release",
11 | "pluginOutputPath": "dist/packages/nx-release",
12 | "jestConfig": "e2e/nx-release-e2e/jest.config.js",
13 | "runInBand": true
14 | },
15 | "dependsOn": ["nx-release:build"]
16 | }
17 | },
18 | "tags": [],
19 | "implicitDependencies": ["nx-release"]
20 | }
21 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/angular-app/files/src/app/services/auth-guard.service.ts__tmpl__:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import { CanActivate } from '@angular/router';
3 | import { AuthService } from './auth.service';
4 |
5 | @Injectable({
6 | providedIn: 'root'
7 | })
8 | export class AuthGuardService implements CanActivate {
9 |
10 | constructor(private authService: AuthService) { }
11 |
12 | canActivate(): boolean {
13 | if (this.authService.isLoggedIn()) {
14 | return true;
15 | }
16 |
17 | console.log('start authentication...');
18 | this.authService.startAuthentication();
19 | return false;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/angular-app/files/src/environments/config.ts__tmpl__:
--------------------------------------------------------------------------------
1 | import { environment } from './environment';
2 | import { Injectable } from '@angular/core';
3 |
4 | @Injectable()
5 | export class Config {
6 | constructor() {}
7 |
8 | Init() {
9 | return new Promise((resolve, reject) => {
10 | console.log("AppInitService.init() called");
11 |
12 | fetch('/config/config.json')
13 | .then((res) => {
14 | return (res.ok ? res.json() : environment)
15 | }).then(( envData ) => {
16 | localStorage.setItem('envData', JSON.stringify(envData));
17 | resolve();
18 | })
19 | });
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See http://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | .nx
4 |
5 | # compiled output
6 | /dist
7 | /tmp
8 | /out-tsc
9 |
10 | # dependencies
11 | /node_modules
12 |
13 | # IDEs and editors
14 | /.idea
15 | .project
16 | .classpath
17 | .c9/
18 | *.launch
19 | .settings/
20 | *.sublime-workspace
21 |
22 | # IDE - VSCode
23 | .vscode/*
24 | !.vscode/settings.json
25 | !.vscode/tasks.json
26 | !.vscode/launch.json
27 | !.vscode/extensions.json
28 |
29 | # misc
30 | /.sass-cache
31 | /connect.lock
32 | /coverage
33 | /libpeerconnection.log
34 | npm-debug.log
35 | yarn-error.log
36 | testem.log
37 | /typings
38 |
39 | # System Files
40 | .DS_Store
41 | Thumbs.db
42 |
--------------------------------------------------------------------------------
/jest.preset.js:
--------------------------------------------------------------------------------
1 | const nxPreset = require('@nx/jest/preset').default;
2 |
3 | module.exports = {
4 | ...nxPreset,
5 | /* TODO: Update to latest Jest snapshotFormat
6 | * By default Nx has kept the older style of Jest Snapshot formats
7 | * to prevent breaking of any existing tests with snapshots.
8 | * It's recommend you update to the latest format.
9 | * You can do this by removing snapshotFormat property
10 | * and running tests with --update-snapshot flag.
11 | * Example: "nx affected --targets=e2e --update-snapshot"
12 | * More info: https://jestjs.io/docs/upgrading-to-jest29#snapshot-format
13 | */
14 | snapshotFormat: { escapeString: true, printBasicPrototype: true },
15 | };
16 |
--------------------------------------------------------------------------------
/packages/semantic-release-nuget/README.md:
--------------------------------------------------------------------------------
1 | # About this project
2 | This is the Government of Alberta - Semantic Release plugin for Nuget.
3 |
4 | This plugin includes the following stages and executes:
5 |
6 | **prepare**
7 |
8 | `dotnet pack [options] /p:Version=[semVer]`
9 |
10 | Note that the semantic version is provided as the `Version` MSBuild property and no other version handling is provided (`VersionSuffix`, `AssemblyVersion`, etc.).
11 |
12 | **publish**
13 |
14 | `dotnet nuget push *.nupkg`
15 |
16 | The `nupkgRoot` configuration property is used to determine the working directory for the command.
17 |
18 | The environment variable `NUGET_API_KEY` is used as the API key for pushing to the Nuget source.
19 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/angular-app/files/src/app/tenant.service.ts__tmpl__:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import { HttpClient } from '@angular/common/http';
3 |
4 | @Injectable({ providedIn: 'root' })
5 | export default class TenantService {
6 |
7 | private getTenantNameUrl = `${this.configData().tenantApi.host}${this.configData().tenantApi.endpoints.tenantNameByRealm}/${this.configData().access.realm}`;
8 |
9 | constructor(private http: HttpClient) {}
10 |
11 | /** GET tenants from the server */
12 | getTenant() {
13 | return this.http.get(this.getTenantNameUrl);
14 | }
15 |
16 | configData () {
17 | return JSON.parse(localStorage.getItem('envData') || "\"\"");
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/react-app/files/webpack.config.js__tmpl__:
--------------------------------------------------------------------------------
1 | const { composePlugins, withNx } = require('@nx/webpack');
2 | const { withReact } = require('@nx/react');
3 | const HtmlWebpackPlugin = require('html-webpack-plugin');
4 |
5 | // Nx plugins for webpack.
6 | module.exports = composePlugins(withNx(), withReact(), (config) => {
7 | // Update the webpack config as needed here.
8 | // e.g. `config.plugins.push(new MyPlugin())`
9 | config.entry['renew'] = ['./src/renew.ts'];
10 |
11 | config.plugins.push(
12 | new HtmlWebpackPlugin({
13 | template: './src/renew.html',
14 | chunks: ['renew'],
15 | filename: 'renew.html',
16 | })
17 | );
18 |
19 | return config;
20 | });
21 |
--------------------------------------------------------------------------------
/packages/nx-oc/src/utils/oc-utils.ts:
--------------------------------------------------------------------------------
1 | import { execSync } from 'child_process';
2 |
3 | export function runOcCommand(
4 | command: 'project' | 'start-build' | 'process' | 'apply',
5 | params: string[],
6 | input?: Buffer
7 | ): { success: boolean, stdout?: Buffer} {
8 | const execute = !input ?
9 | `oc ${command} ${params.join(' ')}` :
10 | `cat | oc ${command} ${['-f -', ...params].join(' ')}`;
11 |
12 | try {
13 | console.log(`Executing command: ${execute}`);
14 | const stdout = execSync(execute, { stdio: 'pipe', input });
15 | return { success: true, stdout };
16 | } catch (e) {
17 | console.log(`Failed to execute command: ${execute}`, e);
18 | return { success: false };
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/react-app/files/src/index.html__tmpl__:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | <%= projectName %>
6 |
7 |
8 |
9 |
10 |
11 |
15 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/packages/nx-oc/src/adsp/environments.ts:
--------------------------------------------------------------------------------
1 | export type EnvironmentName = 'dev' | 'test' | 'prod';
2 | interface Environment {
3 | accessServiceUrl: string;
4 | directoryServiceUrl: string;
5 | }
6 |
7 | export const environments: Record = {
8 | dev: {
9 | accessServiceUrl: 'https://access.adsp-dev.gov.ab.ca',
10 | directoryServiceUrl: 'https://directory-service.adsp-dev.gov.ab.ca',
11 | },
12 | test: {
13 | accessServiceUrl: 'https://access-uat.alberta.ca',
14 | directoryServiceUrl: 'https://directory-service.adsp-uat.alberta.ca',
15 | },
16 | prod: {
17 | accessServiceUrl: 'https://access.alberta.ca',
18 | directoryServiceUrl: 'https://directory-service.adsp.alberta.ca',
19 | },
20 | };
21 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/angular-app/files/src/index.html__tmpl__:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | <%= projectName %>
6 |
7 |
8 |
9 |
13 |
17 |
18 |
19 | <<%= projectName %>-app-root><%= projectName %>-app-root>
20 |
21 |
22 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/react-task-list/files/__fileName__/task.d.ts__tmpl__:
--------------------------------------------------------------------------------
1 | export interface QueueDefinition {
2 | namespace: string;
3 | name: string;
4 | description: string;
5 | assignerRoles: string[];
6 | workerRoles: string[];
7 | }
8 |
9 | export interface Task {
10 | id: string;
11 | name: string;
12 | description: string;
13 | priority: string;
14 | status: 'Pending' | 'In Progress' | 'Stopped' | 'Cancelled' | 'Completed';
15 | createdOn: string;
16 | startedOn: string;
17 | endedOn: string;
18 | assignment: {
19 | assignedTo: {
20 | id: string;
21 | name: string;
22 | };
23 | };
24 | }
25 |
26 | export interface Person {
27 | id: string;
28 | name: string;
29 | email: string;
30 | }
31 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "editor.formatOnSave": true,
3 | "editor.trimAutoWhitespace": true,
4 | "editor.tabSize": 2,
5 | "files.trimTrailingWhitespace": false,
6 | "[html]": {
7 | "editor.defaultFormatter": "esbenp.prettier-vscode"
8 | },
9 | "[typescriptreact]": {
10 | "editor.defaultFormatter": "esbenp.prettier-vscode"
11 | },
12 | "[javascript]": {
13 | "editor.defaultFormatter": "esbenp.prettier-vscode"
14 | },
15 | "[jsonc]": {
16 | "editor.defaultFormatter": "vscode.json-language-features"
17 | },
18 | "[typescript]": {
19 | "editor.defaultFormatter": "esbenp.prettier-vscode"
20 | },
21 | "cSpell.words": [
22 | "abgov",
23 | "Adsp",
24 | "nrwl",
25 | "openshift",
26 | "releaserc"
27 | ]
28 | }
--------------------------------------------------------------------------------
/packages/nx-oc/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@abgov/nx-oc",
3 | "version": "0.0.0",
4 | "license": "Apache-2.0",
5 | "main": "src/index.js",
6 | "description": "Government of Alberta - Nx plugin for OpenShift.",
7 | "repository": {
8 | "type": "git",
9 | "url": "git+https://github.com/GovAlta/nx-tools.git",
10 | "directory": "packages/nx-oc"
11 | },
12 | "peerDependencies": {
13 | "@nx/devkit": "^20.0.0",
14 | "tslib": "^2.0.0"
15 | },
16 | "dependencies": {
17 | "axios": "^1.6.0",
18 | "enquirer": "^2.3.6",
19 | "express": "^4.18.2",
20 | "open": "^8.4.0",
21 | "simple-oauth2": "^5.0.0",
22 | "yaml": "~2.2.2"
23 | },
24 | "generators": "./generators.json",
25 | "executors": "./executors.json",
26 | "scripts": {}
27 | }
--------------------------------------------------------------------------------
/packages/nx-adsp/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["../../.eslintrc.json"],
3 | "ignorePatterns": ["!**/*"],
4 | "rules": {
5 | "@nx/dependency-checks": [
6 | "error",
7 | {
8 | "ignoredDependencies": [
9 | "@abgov/nx-oc"
10 | ],
11 | "checkMissingDependencies": true, // toggle to disable
12 | "checkObsoleteDependencies": true, // toggle to disable
13 | "checkVersionMismatches": true // toggle to disable
14 | }
15 | ]
16 | },
17 | "overrides": [
18 | {
19 | "files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
20 | "rules": {}
21 | },
22 | {
23 | "files": ["*.ts", "*.tsx"],
24 | "rules": {}
25 | },
26 | {
27 | "files": ["*.js", "*.jsx"],
28 | "rules": {}
29 | }
30 | ]
31 | }
32 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/react-form/files/__fileName__/__fileName__.slice.spec.ts__tmpl__:
--------------------------------------------------------------------------------
1 | import {
2 | initial<%= className %>State,
3 | <%= propertyName %>Actions,
4 | <%= propertyName %>Reducer,
5 | } from './<%= fileName %>.slice';
6 |
7 | describe('<%= name %> slice', () => {
8 | describe('<%= propertyName %>Reducer', () => {
9 | it('can handle initial state', () => {
10 | expect(<%= propertyName %>Reducer(undefined, { type: '' })).toEqual(
11 | initial<%= className %>State
12 | );
13 | });
14 |
15 | it('can handle set step action', () => {
16 | expect(
17 | <%= propertyName %>Reducer(undefined, <%= propertyName %>Actions.setStep(2))
18 | ).toMatchObject({ step: 2 });
19 | });
20 |
21 | // TODO: Add state unit tests.
22 | });
23 | });
24 |
--------------------------------------------------------------------------------
/packages/nx-release/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@abgov/nx-release",
3 | "version": "0.0.0",
4 | "license": "Apache-2.0",
5 | "main": "src/index.js",
6 | "description": "Government of Alberta - Nx plugin for Semantic Release.",
7 | "repository": {
8 | "type": "git",
9 | "url": "git+https://github.com/GovAlta/nx-tools.git",
10 | "directory": "packages/nx-release"
11 | },
12 | "peerDependencies": {
13 | "@nx/devkit": "^20.0.0",
14 | "semantic-release": "^23.0.0",
15 | "tslib": "^2.0.0"
16 | },
17 | "dependencies": {
18 | "@semantic-release/commit-analyzer": "^11.1.0",
19 | "@semantic-release/release-notes-generator": "^12.1.0",
20 | "get-stream": "~6.0.0",
21 | "split2": "~4.2.0"
22 | },
23 | "generators": "./generators.json",
24 | "scripts": {}
25 | }
26 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/angular-app/files/src/app/protected/protected.component.ts__tmpl__:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 | import TenantService from '../tenant.service';
3 |
4 | @Component({
5 | selector: 'app-protected',
6 | templateUrl: './protected.component.html',
7 | styleUrls: ['./protected.component.css'],
8 | })
9 | export class ProtectedComponent implements OnInit {
10 | constructor(private _tenantService: TenantService) {}
11 |
12 | public tenant = { name: '' };
13 |
14 | getTenant() {
15 | this._tenantService.getTenant().subscribe(
16 | (data: any) => {
17 | this.tenant = data.tenant;
18 | },
19 | (err) => console.error(err),
20 | () => console.log('done loading tenant')
21 | );
22 | }
23 |
24 | ngOnInit() {
25 | this.getTenant();
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/angular-app/files/src/assets/github-1.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/packages/nx-adsp/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@abgov/nx-adsp",
3 | "version": "0.0.0",
4 | "license": "Apache-2.0",
5 | "main": "src/index.js",
6 | "description": "Government of Alberta - Nx plugin for ADSP apps.",
7 | "repository": {
8 | "type": "git",
9 | "url": "git+https://github.com/GovAlta/nx-tools.git",
10 | "directory": "packages/nx-adsp"
11 | },
12 | "peerDependencies": {
13 | "@abgov/nx-oc": "^10.0.0",
14 | "@nx-dotnet/core": "^2.5.0",
15 | "@nx/angular": "^20.0.0",
16 | "@nx/express": "^20.0.0",
17 | "@nx/devkit": "^20.0.0",
18 | "@nx/react": "^20.0.0",
19 | "@nx/eslint": "^20.0.0",
20 | "tslib": "^2.0.0"
21 | },
22 | "dependencies": {
23 | "axios": "^1.6.0",
24 | "enquirer": "^2.3.6",
25 | "json-schema-to-typescript": "^13.0.1"
26 | },
27 | "generators": "./generators.json",
28 | "scripts": {}
29 | }
--------------------------------------------------------------------------------
/tsconfig.base.json:
--------------------------------------------------------------------------------
1 | {
2 | "compileOnSave": false,
3 | "compilerOptions": {
4 | "rootDir": ".",
5 | "sourceMap": true,
6 | "declaration": false,
7 | "moduleResolution": "node",
8 | "emitDecoratorMetadata": true,
9 | "experimentalDecorators": true,
10 | "importHelpers": true,
11 | "target": "es2015",
12 | "module": "esnext",
13 | "lib": ["es2017", "dom"],
14 | "skipLibCheck": true,
15 | "skipDefaultLibCheck": true,
16 | "baseUrl": ".",
17 | "paths": {
18 | "@abgov/nx-adsp": ["packages/nx-adsp/src/index.ts"],
19 | "@abgov/nx-oc": ["packages/nx-oc/src/index.ts"],
20 | "@abgov/nx-release": ["packages/nx-release/src/index.ts"],
21 | "@abgov/semantic-release-nuget": [
22 | "packages/semantic-release-nuget/src/index.ts"
23 | ]
24 | }
25 | },
26 | "exclude": ["node_modules", "tmp"]
27 | }
28 |
--------------------------------------------------------------------------------
/e2e/nx-release-e2e/tests/nx-release.spec.ts:
--------------------------------------------------------------------------------
1 | import {
2 | checkFilesExist,
3 | copyNodeModules,
4 | ensureNxProject,
5 | readJson,
6 | runNxCommandAsync,
7 | uniq,
8 | } from '@nx/plugin/testing';
9 | describe('nx-release e2e', () => {
10 | beforeEach(() => {
11 | ensureNxProject('@abgov/nx-release', 'dist/packages/nx-release');
12 | copyNodeModules(['@nx/node']);
13 | });
14 |
15 | describe('lib', () => {
16 | it('should create release', async (done) => {
17 | const plugin = uniq('lib');
18 | await runNxCommandAsync(
19 | `generate @nx/node:library ${plugin} --publishable --importPath @test/${plugin}`
20 | );
21 | const result = await runNxCommandAsync(
22 | `generate @abgov/nx-release:lib ${plugin}`
23 | );
24 |
25 | expect(result.stderr).toBeFalsy();
26 |
27 | done();
28 | }, 60000);
29 | });
30 | });
31 |
--------------------------------------------------------------------------------
/packages/nx-oc/generators.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://json-schema.org/schema",
3 | "name": "nx-oc",
4 | "version": "0.0.1",
5 | "generators": {
6 | "pipeline": {
7 | "factory": "./src/generators/pipeline/pipeline",
8 | "schema": "./src/generators/pipeline/schema.json",
9 | "description": "Generator that creates OpenShift manifests for pipeline."
10 | },
11 | "apply-infra": {
12 | "factory": "./src/generators/apply-infra/apply-infra",
13 | "schema": "./src/generators/apply-infra/schema.json",
14 | "description": "Generator that applies OpenShift manifests for pipeline."
15 | },
16 | "deployment": {
17 | "factory": "./src/generators/deployment/deployment",
18 | "schema": "./src/generators/deployment/schema.json",
19 | "description": "Generator that creates OpenShift manifests for project deployment."
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/react-app/files/src/access.ts__tmpl__:
--------------------------------------------------------------------------------
1 | import { createUserManager as createOidcUserManager } from 'redux-oidc';
2 |
3 | interface CreateUserManagerProps {
4 | url: string;
5 | realm: string;
6 | client_id: string;
7 | }
8 |
9 | export function createUserManager({
10 | url,
11 | realm,
12 | client_id
13 | }: CreateUserManagerProps) {
14 |
15 | const appUrl = `${window.location.protocol}//${window.location.hostname}${window.location.port ? `:${window.location.port}` : ''}`;
16 | const settings = {
17 | client_id,
18 | redirect_uri: `${appUrl}/auth/callback`,
19 | post_logout_redirect_uri: `${appUrl}/signout/callback`,
20 | silent_redirect_uri: `${appUrl}/renew.html`,
21 | response_type: 'code',
22 | authority: `${url}/auth/realms/${realm}`,
23 | automaticSilentRenew: true,
24 | };
25 | return createOidcUserManager(settings);
26 | }
27 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # About the project
2 | This is a monorepo of the Government of Alberta's custom plugins for [Nx](https://nx.dev)
3 |
4 | [NX Tools Guide](https://govalta.github.io/nx-tools/getting-started.html)
5 |
6 | ## Plugins
7 |
8 | [Nx OpenShift Plugin](./packages/nx-oc/README.md) - includes generators for setting up OpenShift pipeline and application yaml files, and executors for `oc cli` commands.
9 |
10 | [Nx Release Plugin](./packages/nx-release/README.md) - includes generators for adding [semantic-release](https://github.com/semantic-release/semantic-release) based release targets.
11 |
12 | [Nx ADSP Plugin](./packages/nx-adsp/README.md) - includes generators for application, service, and fullstack solution quick starts.
13 |
14 | [Semantic Release Nuget](./packages/semantic-release-nuget/README.md) - [semantic-release](https://github.com/semantic-release/semantic-release) plugin for publishing nuget packages.
15 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/react-task-list/files/__fileName__/__fileName__.slice.spec.ts__tmpl__:
--------------------------------------------------------------------------------
1 | import {
2 | initial<%= className %>TaskListState,
3 | <%= propertyName %>TaskListActions,
4 | <%= propertyName %>TaskListReducer,
5 | } from './<%= fileName %>.slice';
6 |
7 | describe('<%= fileName %> slice', () => {
8 | describe('<%= propertyName %>TaskListReducer', () => {
9 | it('can handle initial state', () => {
10 | expect(<%= propertyName %>TaskListReducer(undefined, { type: '' })).toEqual(
11 | initial<%= className %>TaskListState
12 | );
13 | });
14 |
15 | it('can handle set step action', () => {
16 | expect(
17 | <%= propertyName %>TaskListReducer(
18 | undefined,
19 | <%= propertyName %>TaskListActions.setFilter('active')
20 | )
21 | ).toMatchObject({ filter: 'active' });
22 | });
23 |
24 | // TODO: Add state unit tests.
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/react-app/files/nginx.conf__tmpl__:
--------------------------------------------------------------------------------
1 | events {
2 | worker_connections 1024;
3 | }
4 | http{
5 | sendfile on;
6 | include mime.types;
7 | default_type application/octet-stream;
8 |
9 | server {
10 |
11 | listen 8080;
12 | root /opt/app-root/src;
13 | index index.html;
14 |
15 |
16 | location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
17 | expires 30d;
18 | add_header Cache-Control "public, no-transform";
19 | }
20 |
21 | location / {
22 | gzip on;
23 | try_files $uri /index.html;
24 | }
25 | <% nginxProxies.forEach(function(nginxProxy){ %>
26 | location <%= nginxProxy.location %> {
27 | proxy_pass <%= nginxProxy.proxyPass %>;
28 | proxy_set_header Host $host;
29 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
30 | proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
31 | }
32 | <% }); %>
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/angular-app/files/nginx.conf__tmpl__:
--------------------------------------------------------------------------------
1 | events {
2 | worker_connections 1024;
3 | }
4 | http{
5 | sendfile on;
6 | include mime.types;
7 | default_type application/octet-stream;
8 |
9 | server {
10 |
11 | listen 8080;
12 | root /opt/app-root/src;
13 | index index.html;
14 |
15 |
16 | location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
17 | expires 30d;
18 | add_header Cache-Control "public, no-transform";
19 | }
20 |
21 | location / {
22 | gzip on;
23 | try_files $uri /index.html;
24 | }
25 | <% nginxProxies.forEach(function(nginxProxy){ %>
26 | location <%= nginxProxy.location %> {
27 | proxy_pass <%= nginxProxy.proxyPass %>;
28 | proxy_set_header Host $host;
29 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
30 | proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
31 | }
32 | <% }); %>
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/packages/nx-release/src/release-plugin/git-utils.ts:
--------------------------------------------------------------------------------
1 | import { spawn } from 'child_process';
2 | import { array } from 'get-stream';
3 | import split from 'split2';
4 |
5 | const projectCommits: Record = {};
6 |
7 | export async function getPathCommitHashes(
8 | cwd: string,
9 | project: string,
10 | paths: string[],
11 | from: string,
12 | to = 'HEAD'
13 | ) {
14 | if (!projectCommits[project]) {
15 | // --full-history to avoid history simplification ignoring commits on some merged branches.
16 | const commits = await array(
17 | spawn(
18 | 'git',
19 | [
20 | 'log',
21 | '--format=%H',
22 | '--full-history',
23 | `${from ? `${from}..` : ''}${to}`,
24 | '--',
25 | ...paths,
26 | ],
27 | { cwd }
28 | ).stdout.pipe(split())
29 | );
30 |
31 | projectCommits[project] = commits;
32 | }
33 |
34 | return projectCommits[project];
35 | }
36 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/angular-app/files/src/app/home/home.component.ts__tmpl__:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 | import { HttpClient } from '@angular/common/http';
3 |
4 | @Component({
5 | selector: '<%= projectName %>-app-logout',
6 | templateUrl: 'home.component.html',
7 | })
8 | export class HomeComponent implements OnInit {
9 | constructor(private http: HttpClient) {}
10 | public uptime = 0;
11 |
12 | private getHealthUrl = `${this.configData().tenantApi.host}/health`;
13 |
14 | getHealth() {
15 | const uptimePromise = this.http.get(this.getHealthUrl);
16 |
17 | uptimePromise.subscribe(
18 | (data: any) => {
19 | this.uptime = data.uptime;
20 | },
21 | (err) => console.error(err),
22 | () => console.log('done loading uptime')
23 | );
24 | }
25 |
26 | configData () {
27 | return JSON.parse(localStorage.getItem('envData') || "\"\"");
28 | }
29 |
30 | ngOnInit() {
31 | this.getHealth();
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/angular-app/files/src/app/app.component.ts__tmpl__:
--------------------------------------------------------------------------------
1 | import { Component, OnDestroy, OnInit } from '@angular/core';
2 | import { AuthService } from './services/auth.service';
3 | import { environment } from '../environments/environment'
4 |
5 |
6 | @Component({
7 | selector: '<%= projectName %>-app-root',
8 | templateUrl: './app.component.html',
9 | styleUrls: ['./app.component.css'],
10 | })
11 |
12 | export class AppComponent implements OnInit, OnDestroy {
13 | title = "<%= projectName %>";
14 |
15 | constructor(private authService: AuthService) {}
16 |
17 | isLoggedIn(): boolean {
18 | return this.authService.isLoggedIn()
19 | }
20 |
21 | logout() {
22 | if (this.authService.isLoggedIn()) {
23 | this.authService.logout();
24 | }
25 | }
26 |
27 | login() {
28 | if (!this.authService.isLoggedIn()) {
29 | this.authService.startAuthentication();
30 | }
31 | }
32 |
33 | ngOnInit() {}
34 |
35 | ngOnDestroy(): void {}
36 | }
37 |
--------------------------------------------------------------------------------
/packages/nx-oc/src/executors/apply/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 2,
3 | "outputCapture": "direct-nodejs",
4 | "$schema": "http://json-schema.org/schema",
5 | "title": "Apply executor",
6 | "description": "",
7 | "type": "object",
8 | "properties": {
9 | "ocProject": {
10 | "oneOf": [
11 | {
12 | "type": "string"
13 | },
14 | {
15 | "type": "array",
16 | "items": {
17 | "oneOf": [
18 | {
19 | "type": "string"
20 | },
21 | {
22 | "type": "object",
23 | "properties": {
24 | "project": {
25 | "type": "string"
26 | },
27 | "tag": {
28 | "type": "string"
29 | }
30 | }
31 | }
32 | ]
33 | }
34 | }
35 | ]
36 | }
37 | },
38 | "required": [
39 | "ocProject"
40 | ]
41 | }
42 |
--------------------------------------------------------------------------------
/packages/nx-oc/src/generators/apply-infra/apply-infra.ts:
--------------------------------------------------------------------------------
1 | import { Tree } from '@nx/devkit';
2 | import { runOcCommand } from '../../utils/oc-utils';
3 |
4 | function applyOcResources(host: Tree) {
5 | const { success: pipelineApplied, stdout: pipelineOut } = runOcCommand(
6 | 'apply',
7 | [],
8 | host.read('.openshift/environment.infra.yml')
9 | );
10 | console.log(pipelineOut?.toString());
11 |
12 | const { success: envApplied, stdout: envOut } = runOcCommand(
13 | 'apply',
14 | [],
15 | host.read('.openshift/environments.yml')
16 | );
17 | console.log(envOut?.toString());
18 |
19 | if (!pipelineApplied || !envApplied) {
20 | console.log('Failed to oc apply pipeline and dev environment.');
21 | }
22 | }
23 |
24 | export default async function (host: Tree) {
25 | const { success } = runOcCommand('project', []);
26 | if (success) {
27 | applyOcResources(host);
28 | } else {
29 | console.log(`Use oc login then run 'nx g @abgov/nx-oc:apply-infra'`);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/angular-app/files/src/app/auth.interceptor.ts__tmpl__:
--------------------------------------------------------------------------------
1 | import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
2 | import { Injectable } from '@angular/core';
3 | import { Observable } from 'rxjs';
4 | import { AuthCallbackComponent } from './auth-callback/auth-callback.component';
5 |
6 | @Injectable({ providedIn: 'root' })
7 | export class AuthInterceptor implements HttpInterceptor {
8 |
9 | constructor(private authCallBackComponent: AuthCallbackComponent) { }
10 |
11 | intercept(req: HttpRequest, next: HttpHandler): Observable> {
12 | if (this.authCallBackComponent.setTokens()) {
13 | req = req.clone({
14 | setHeaders: {
15 | 'Content-Type' : 'application/json; charset=utf-8',
16 | 'Accept' : 'application/json',
17 | 'Authorization': `Bearer ${this.authCallBackComponent.accessToken}`,
18 | },
19 | });
20 | }
21 |
22 | return next.handle(req);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/packages/nx-oc/src/generators/apply-infra/apply-infra.spec.ts:
--------------------------------------------------------------------------------
1 | import { createTree } from '@nx/devkit/testing';
2 | import { mocked } from 'jest-mock';
3 | import generator from './apply-infra';
4 | import { runOcCommand } from '../../utils/oc-utils';
5 | import { writeJson } from '@nx/devkit';
6 |
7 | jest.mock('../../utils/oc-utils');
8 | const mockedRunOcCommand = mocked(runOcCommand);
9 |
10 | describe('Apply Infra Generator', () => {
11 | beforeEach(() => {
12 | mockedRunOcCommand.mockReset();
13 | });
14 |
15 | it('can run', async () => {
16 | const host = createTree();
17 | writeJson(host, '.openshift/environment.infra.yml', {});
18 | writeJson(host, '.openshift/environment.env.yml', {});
19 |
20 | mockedRunOcCommand.mockReturnValue({ success: true });
21 |
22 | await generator(host);
23 |
24 | expect(mockedRunOcCommand.mock.calls.length).toBe(3);
25 | expect(mockedRunOcCommand.mock.calls[0][0]).toBe('project');
26 | expect(mockedRunOcCommand.mock.calls[1][0]).toBe('apply');
27 | expect(mockedRunOcCommand.mock.calls[2][0]).toBe('apply');
28 | });
29 | });
30 |
--------------------------------------------------------------------------------
/packages/nx-oc/src/generators/pipeline/jenkins/environments.yml__tmpl__:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: List
3 | items:
4 | - apiVersion: rbac.authorization.k8s.io/v1
5 | kind: RoleBinding
6 | metadata:
7 | name: env_deploy_pullers
8 | namespace: <%= ocInfraProject %>
9 | roleRef:
10 | apiGroup: rbac.authorization.k8s.io
11 | kind: ClusterRole
12 | name: 'system:image-puller'
13 | subjects:
14 | <% ocEnvProjects.forEach(function(ocEnvProject){ -%>
15 | - apiGroup: rbac.authorization.k8s.io
16 | kind: Group
17 | name: 'system:serviceaccounts:<%= ocEnvProject %>'
18 | <% }); -%>
19 | <% ocEnvProjects.forEach(function(ocEnvProject){ -%>
20 | - apiVersion: rbac.authorization.k8s.io/v1
21 | kind: RoleBinding
22 | metadata:
23 | name: jenkins_edit
24 | namespace: <%= ocEnvProject %>
25 | roleRef:
26 | apiGroup: rbac.authorization.k8s.io
27 | kind: ClusterRole
28 | name: edit
29 | subjects:
30 | - kind: ServiceAccount
31 | name: jenkins
32 | namespace: <%= ocInfraProject %>
33 | <% }); -%>
34 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/angular-app/files/src/app/app.routes.ts__tmpl__:
--------------------------------------------------------------------------------
1 | import { LogoutComponent } from './logout/logout.component';
2 | import { NgModule } from '@angular/core';
3 | import { Routes, RouterModule } from '@angular/router';
4 | import { HomeComponent } from './home/home.component';
5 | import { ProtectedComponent } from './protected/protected.component';
6 | import { AuthGuardService } from './services/auth-guard.service';
7 | import { AuthCallbackComponent } from './auth-callback/auth-callback.component';
8 |
9 | const routes: Routes = [
10 | {
11 | path: '',
12 | component: HomeComponent,
13 | children: [],
14 | },
15 | {
16 | path: 'protected',
17 | component: ProtectedComponent,
18 | canActivate: [AuthGuardService],
19 | },
20 | {
21 | path: 'auth-callback',
22 | component: AuthCallbackComponent,
23 | },
24 | {
25 | path: 'signout/callback',
26 | component: LogoutComponent,
27 | },
28 | ];
29 |
30 | @NgModule({
31 | imports: [RouterModule.forRoot(routes)],
32 | exports: [RouterModule],
33 | })
34 | export class AppRoutingModule {}
35 |
--------------------------------------------------------------------------------
/packages/nx-release/src/release-plugin/git-utils.spec.ts:
--------------------------------------------------------------------------------
1 | import { ChildProcess, spawn } from 'child_process';
2 | import { ReadableStreamBuffer } from 'stream-buffers';
3 | import { mocked } from 'jest-mock'
4 | import { getPathCommitHashes } from './git-utils';
5 |
6 | jest.mock('child_process');
7 | const mockedSpawn = mocked(spawn);
8 |
9 | describe('git-utils', () => {
10 |
11 | beforeEach(() => {
12 | mockedSpawn.mockReset()
13 | });
14 |
15 | describe('getPathCommitHashes', () => {
16 |
17 | it('can get commits', async () => {
18 |
19 | const stream = new ReadableStreamBuffer();
20 | stream.put('test1\ntest2\n');
21 | stream.stop();
22 |
23 | mockedSpawn.mockReturnValue({ stdout: stream } as unknown as ChildProcess)
24 | const commits = await getPathCommitHashes(
25 | '/repo',
26 | 'test',
27 | ['test'],
28 | '',
29 | 'HEAD'
30 | );
31 |
32 | expect(commits.length).toBe(2);
33 | expect(commits[0]).toBe('test1');
34 | expect(commits[1]).toBe('test2');
35 | expect(mockedSpawn.mock.calls.length).toBe(1);
36 | });
37 | });
38 | });
39 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/mern/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://json-schema.org/schema",
3 | "id": "NxAdspMern",
4 | "title": "",
5 | "type": "object",
6 | "properties": {
7 | "name": {
8 | "type": "string",
9 | "description": "Name of the MERN stack solution.",
10 | "$default": {
11 | "$source": "argv",
12 | "index": 0
13 | },
14 | "x-prompt": "What name would you like to use?"
15 | },
16 | "env": {
17 | "type": "string",
18 | "description": "Environment to target.",
19 | "$default": {
20 | "$source": "argv",
21 | "index": 1
22 | },
23 | "alias": "e",
24 | "x-prompt": {
25 | "message": "Which ADSP environment do you want to target?",
26 | "type": "list",
27 | "items": [
28 | "dev",
29 | "test",
30 | "prod"
31 | ]
32 | }
33 | },
34 | "accessToken": {
35 | "type": "string",
36 | "description": "Access token for retrieving configuration from ADSP APIs.",
37 | "alias": "at"
38 | }
39 | },
40 | "required": [
41 | "name",
42 | "env"
43 | ]
44 | }
45 |
--------------------------------------------------------------------------------
/packages/nx-release/src/release-plugin/types.d.ts:
--------------------------------------------------------------------------------
1 | declare namespace SemanticRelease {
2 | import type { BaseContext } from 'semantic-release';
3 |
4 | type PluginConfig = Record;
5 |
6 | type PluginFunction = (
7 | pluginConfig: PluginConfig,
8 | context: T
9 | ) => Promise;
10 | }
11 |
12 | declare module '@semantic-release/semantic-release' {
13 | export = SemanticRelease;
14 | }
15 |
16 | declare namespace CommitAnalyzer {
17 | type ReleaseType = string;
18 |
19 | const analyzeCommits: SemanticRelease.PluginFunction;
20 |
21 | module.exports = { analyzeCommits };
22 | }
23 |
24 | declare module '@semantic-release/commit-analyzer' {
25 | export = CommitAnalyzer;
26 | }
27 |
28 | declare module '@semantic-release/semantic-release' {
29 | export = SemanticRelease;
30 | }
31 |
32 | declare namespace ReleaseNotesGenerator {
33 | type ReleaseType = string;
34 |
35 | const generateNotes: SemanticRelease.PluginFunction;
36 |
37 | module.exports = { generateNotes };
38 | }
39 |
40 | declare module '@semantic-release/release-notes-generator' {
41 | export = ReleaseNotesGenerator;
42 | }
43 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/dotnet-service/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://json-schema.org/schema",
3 | "id": "NxAdspDotnetService",
4 | "title": "",
5 | "type": "object",
6 | "properties": {
7 | "name": {
8 | "type": "string",
9 | "description": "Name of the service.",
10 | "$default": {
11 | "$source": "argv",
12 | "index": 0
13 | },
14 | "x-prompt": "What name would you like to use?"
15 | },
16 | "env": {
17 | "type": "string",
18 | "description": "Environment to target.",
19 | "$default": {
20 | "$source": "argv",
21 | "index": 1
22 | },
23 | "alias": "e",
24 | "x-prompt": {
25 | "message": "Which ADSP environment do you want to target?",
26 | "type": "list",
27 | "items": [
28 | "dev",
29 | "test",
30 | "prod"
31 | ]
32 | }
33 | },
34 | "accessToken": {
35 | "type": "string",
36 | "description": "Access token for retrieving configuration from ADSP APIs.",
37 | "alias": "at"
38 | }
39 | },
40 | "required": [
41 | "name",
42 | "env"
43 | ]
44 | }
45 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/express-service/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://json-schema.org/schema",
3 | "id": "NxAdspExpressService",
4 | "title": "",
5 | "type": "object",
6 | "properties": {
7 | "name": {
8 | "type": "string",
9 | "description": "Name of the service.",
10 | "$default": {
11 | "$source": "argv",
12 | "index": 0
13 | },
14 | "x-prompt": "What name would you like to use?"
15 | },
16 | "env": {
17 | "type": "string",
18 | "description": "Environment to target.",
19 | "$default": {
20 | "$source": "argv",
21 | "index": 1
22 | },
23 | "alias": "e",
24 | "x-prompt": {
25 | "message": "Which ADSP environment do you want to target?",
26 | "type": "list",
27 | "items": [
28 | "dev",
29 | "test",
30 | "prod"
31 | ]
32 | }
33 | },
34 | "accessToken": {
35 | "type": "string",
36 | "description": "Access token for retrieving configuration from ADSP APIs.",
37 | "alias": "at"
38 | }
39 | },
40 | "required": [
41 | "name",
42 | "env"
43 | ]
44 | }
45 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/react-dotnet/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://json-schema.org/schema",
3 | "id": "NxAdspReactDotnet",
4 | "title": "",
5 | "type": "object",
6 | "properties": {
7 | "name": {
8 | "type": "string",
9 | "description": "Name of the React-Dotnet stack solution.",
10 | "$default": {
11 | "$source": "argv",
12 | "index": 0
13 | },
14 | "x-prompt": "What name would you like to use?"
15 | },
16 | "env": {
17 | "type": "string",
18 | "description": "Environment to target.",
19 | "$default": {
20 | "$source": "argv",
21 | "index": 1
22 | },
23 | "alias": "e",
24 | "x-prompt": {
25 | "message": "Which ADSP environment do you want to target?",
26 | "type": "list",
27 | "items": [
28 | "dev",
29 | "test",
30 | "prod"
31 | ]
32 | }
33 | },
34 | "accessToken": {
35 | "type": "string",
36 | "description": "Access token for retrieving configuration from ADSP APIs.",
37 | "alias": "at"
38 | }
39 | },
40 | "required": [
41 | "name",
42 | "env"
43 | ]
44 | }
45 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/react-form/files/__fileName__/__fileName__.module.css__tmpl__:
--------------------------------------------------------------------------------
1 | .form {
2 | max-width: 800px;
3 |
4 | > fieldset {
5 | display: none;
6 | padding-bottom: 64px;
7 | }
8 |
9 | > fieldset.show {
10 | display: block;
11 | }
12 | }
13 |
14 | .formFile {
15 | display: flex;
16 | align-items: center;
17 |
18 | > a {
19 | display: none;
20 | }
21 | }
22 |
23 | .formActions {
24 | display: flex;
25 | margin-top: 16px;
26 |
27 | > * {
28 | margin-left: 16px;
29 | }
30 |
31 | .save {
32 | margin-right: auto;
33 | display: flex;
34 | opacity: 0;
35 | transition-property: opacity;
36 | transition-duration: 500ms;
37 |
38 | > * {
39 | margin-top: auto;
40 | margin-bottom: auto;
41 | margin-right: 8px;
42 | }
43 | }
44 |
45 | .save[data-show='true'] {
46 | opacity: 1;
47 | }
48 | }
49 |
50 | .sectionActions {
51 | display: flex;
52 |
53 | > *:first-child {
54 | margin-right: auto;
55 | }
56 | }
57 |
58 | .load {
59 | display: flex;
60 | flex-direction: row;
61 | padding-top: 64px;
62 | padding-bottom: 64px;
63 | > * {
64 | margin: auto;
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/express-service/express-service.spec.ts:
--------------------------------------------------------------------------------
1 | import { readProjectConfiguration } from '@nx/devkit';
2 | import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
3 |
4 | import * as utils from '@abgov/nx-oc';
5 | import { environments } from '@abgov/nx-oc';
6 | import { Schema } from './schema';
7 | import generator from './express-service';
8 |
9 | jest.mock('@abgov/nx-oc');
10 | const utilsMock = utils as jest.Mocked;
11 | utilsMock.getAdspConfiguration.mockResolvedValue({
12 | tenant: 'test',
13 | tenantRealm: 'test',
14 | accessServiceUrl: environments.test.accessServiceUrl,
15 | directoryServiceUrl: environments.test.directoryServiceUrl,
16 | });
17 |
18 | describe('Express Service Generator', () => {
19 | const options: Schema = {
20 | name: 'test',
21 | env: 'dev',
22 | };
23 |
24 | it('can run', async () => {
25 | const host = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
26 | await generator(host, options);
27 |
28 | const config = readProjectConfiguration(host, 'test');
29 | expect(config.root).toBe('apps/test');
30 |
31 | expect(host.exists('apps/test/src/main.ts')).toBeTruthy();
32 | }, 60000);
33 | });
34 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/react-form/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://json-schema.org/schema",
3 | "id": "NxAdspReactForm",
4 | "title": "",
5 | "type": "object",
6 | "properties": {
7 | "project": {
8 | "type": "string",
9 | "description": "Project to add form component in.",
10 | "$default": {
11 | "$source": "argv",
12 | "index": 0
13 | },
14 | "x-prompt": "Which project to add form component for?"
15 | },
16 | "env": {
17 | "type": "string",
18 | "description": "Environment to target.",
19 | "$default": {
20 | "$source": "argv",
21 | "index": 1
22 | },
23 | "alias": "e",
24 | "x-prompt": {
25 | "message": "Which ADSP environment do you want to target? (Typically test for ADSP tenants.)",
26 | "type": "list",
27 | "items": [
28 | "test",
29 | "prod",
30 | "dev"
31 | ]
32 | }
33 | },
34 | "accessToken": {
35 | "type": "string",
36 | "description": "Access token for retrieving configuration from ADSP APIs.",
37 | "alias": "at"
38 | }
39 | },
40 | "required": [
41 | "project",
42 | "env"
43 | ]
44 | }
45 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/react-task-list/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://json-schema.org/schema",
3 | "id": "NxAdspReactTaskList",
4 | "title": "",
5 | "type": "object",
6 | "properties": {
7 | "project": {
8 | "type": "string",
9 | "description": "Project to add task list component in.",
10 | "$default": {
11 | "$source": "argv",
12 | "index": 0
13 | },
14 | "x-prompt": "Which project to add task list component for?"
15 | },
16 | "env": {
17 | "type": "string",
18 | "description": "Environment to target.",
19 | "$default": {
20 | "$source": "argv",
21 | "index": 1
22 | },
23 | "alias": "e",
24 | "x-prompt": {
25 | "message": "Which ADSP environment do you want to target? (Typically test for ADSP tenants.)",
26 | "type": "list",
27 | "items": [
28 | "test",
29 | "prod",
30 | "dev"
31 | ]
32 | }
33 | },
34 | "accessToken": {
35 | "type": "string",
36 | "description": "Access token for retrieving configuration from ADSP APIs.",
37 | "alias": "at"
38 | }
39 | },
40 | "required": [
41 | "project",
42 | "env"
43 | ]
44 | }
45 |
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "root": true,
3 | "ignorePatterns": ["**/*"],
4 | "plugins": ["@nx"],
5 | "overrides": [
6 | {
7 | "files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
8 | "rules": {
9 | "@nx/enforce-module-boundaries": [
10 | "error",
11 | {
12 | "enforceBuildableLibDependency": true,
13 | "allow": [],
14 | "depConstraints": [
15 | {
16 | "sourceTag": "*",
17 | "onlyDependOnLibsWithTags": ["*"]
18 | }
19 | ]
20 | }
21 | ]
22 | }
23 | },
24 | {
25 | "files": ["*.ts", "*.tsx"],
26 | "extends": ["plugin:@nx/typescript"],
27 | "rules": {
28 | "@typescript-eslint/no-extra-semi": "error",
29 | "no-extra-semi": "off"
30 | }
31 | },
32 | {
33 | "files": ["*.js", "*.jsx"],
34 | "extends": ["plugin:@nx/javascript"],
35 | "rules": {
36 | "@typescript-eslint/no-extra-semi": "error",
37 | "no-extra-semi": "off"
38 | }
39 | },
40 | {
41 | "files": ["*.json"],
42 | "parser": "jsonc-eslint-parser",
43 | "rules": {
44 | "@nx/dependency-checks": "error"
45 | }
46 | }
47 | ]
48 | }
49 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/utils/form.spec.ts:
--------------------------------------------------------------------------------
1 | import { FormDefinition, generateFormInterface } from './form';
2 |
3 | describe('generateFormInterface', () => {
4 | const dataSchema = {
5 | type: 'object',
6 | properties: {
7 | firstName: {
8 | type: 'string',
9 | },
10 | lastName: {
11 | type: 'string',
12 | },
13 | age: {
14 | description: 'Age in years',
15 | type: 'integer',
16 | minimum: 0,
17 | },
18 | hairColor: {
19 | enum: ['black', 'brown', 'blue'],
20 | type: 'string',
21 | },
22 | personal: {
23 | type: 'object',
24 | properties: {
25 | firstName: {
26 | type: 'string',
27 | },
28 | lastName: {
29 | type: 'string',
30 | },
31 | },
32 | },
33 | },
34 | additionalProperties: false,
35 | required: ['firstName', 'lastName'],
36 | };
37 |
38 | it('can generate form interface', async () => {
39 | const result = await generateFormInterface({
40 | name: 'Test questionnaire',
41 | dataSchema: dataSchema as unknown,
42 | } as FormDefinition);
43 |
44 | expect(result).toBeTruthy();
45 | // expect(result).toMatchSnapshot();
46 | });
47 | });
48 |
--------------------------------------------------------------------------------
/packages/semantic-release-nuget/src/plugin/prepare.ts:
--------------------------------------------------------------------------------
1 | import { PluginFunction } from '@semantic-release/semantic-release';
2 | import { PrepareContext } from 'semantic-release';
3 | import { exec as execCb } from 'child_process';
4 | import { promisify } from 'util';
5 | import { NugetPluginConfig } from './config';
6 | const exec = promisify(execCb);
7 |
8 | export const prepare: PluginFunction = async (
9 | config: NugetPluginConfig,
10 | context
11 | ) => {
12 | const { project, configuration, noBuild, includeSymbols, includeSource, serviceable } =
13 | config;
14 |
15 | const {
16 | cwd,
17 | env,
18 | // stdout,
19 | // stderr,
20 | nextRelease: { version },
21 | } = context;
22 |
23 | const args = [
24 | 'dotnet',
25 | 'pack',
26 | project,
27 | noBuild ? '--no-build' : null,
28 | includeSymbols ? '--include-symbols' : null,
29 | includeSource ? '--include-source' : null,
30 | serviceable ? '--serviceable' : null,
31 | `/p:Configuration=${configuration || 'Release'}`,
32 | `/p:Version=${version}`,
33 | ].filter((v) => !!v);
34 |
35 | const dotnetResult = await exec(args.join(' '), { env, cwd });
36 |
37 | // dotnetResult.stdout.pipe(stdout, { end: false });
38 | // dotnetResult.stderr.pipe(stderr, { end: false });
39 |
40 | await dotnetResult;
41 | };
42 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/react-app/files/src/store.ts__tmpl__:
--------------------------------------------------------------------------------
1 | import { configureStore } from '@reduxjs/toolkit';
2 | import {
3 | reducer as oidcReducer,
4 | LOAD_USER_ERROR,
5 | LOADING_USER,
6 | USER_EXPIRED,
7 | USER_EXPIRING,
8 | USER_FOUND,
9 | USER_LOADED,
10 | USER_SIGNED_OUT,
11 | } from 'redux-oidc';
12 | import { CONFIG_FEATURE_KEY, configReducer } from './app/config.slice';
13 | import { START_FEATURE_KEY, startReducer } from './app/start.slice';
14 | import { INTAKE_FEATURE_KEY, intakeReducer } from './app/intake.slice';
15 |
16 | export const store = configureStore({
17 | reducer: {
18 | user: oidcReducer,
19 | [CONFIG_FEATURE_KEY]: configReducer,
20 | [START_FEATURE_KEY]: startReducer,
21 | [INTAKE_FEATURE_KEY]: intakeReducer,
22 | },
23 | devTools: process.env.NODE_ENV !== 'production',
24 | // Optional Redux store enhancers
25 | enhancers: [],
26 | middleware: (getDefault) =>
27 | getDefault({
28 | serializableCheck: {
29 | ignoredActions: [
30 | LOAD_USER_ERROR,
31 | LOADING_USER,
32 | USER_EXPIRED,
33 | USER_EXPIRING,
34 | USER_FOUND,
35 | USER_LOADED,
36 | USER_SIGNED_OUT,
37 | ],
38 | ignoredPaths: ['user'],
39 | },
40 | }),
41 | });
42 | export type AppDispatch = typeof store.dispatch;
43 |
--------------------------------------------------------------------------------
/e2e/nx-oc-e2e/tests/nx-oc.spec.ts:
--------------------------------------------------------------------------------
1 | import { ensureNxProject, runNxCommandAsync, uniq } from '@nx/plugin/testing';
2 | describe('nx-oc e2e', () => {
3 | beforeEach(() => ensureNxProject('@abgov/nx-oc', 'dist/packages/nx-oc'));
4 |
5 | describe('pipeline', () => {
6 | it('should create jenkins pipeline', async (done) => {
7 | const plugin = uniq('pipeline');
8 | const result = await runNxCommandAsync(
9 | `generate @abgov/nx-oc:pipeline ${plugin}-build ${plugin}-infra --t jenkins --e ${plugin}-dev`
10 | );
11 |
12 | expect(result.stderr).toBeFalsy();
13 |
14 | done();
15 | });
16 |
17 | it('should create github actions pipeline', async (done) => {
18 | const plugin = uniq('pipeline');
19 | const result = await runNxCommandAsync(
20 | `generate @abgov/nx-oc:pipeline ${plugin}-build ${plugin}-infra --t actions --e ${plugin}-dev`
21 | );
22 |
23 | expect(result.stderr).toBeFalsy();
24 |
25 | done();
26 | });
27 | });
28 |
29 | describe('apply-infra', () => {
30 | it('should run oc cli', async (done) => {
31 | const plugin = uniq('apply-infra');
32 | const result = await runNxCommandAsync(
33 | `generate @abgov/nx-oc:apply-infra`
34 | );
35 |
36 | expect(result.stdout).toContain('oc project');
37 |
38 | done();
39 | });
40 | });
41 | });
42 |
--------------------------------------------------------------------------------
/nx.json:
--------------------------------------------------------------------------------
1 | {
2 | "workspaceLayout": {
3 | "appsDir": "e2e",
4 | "libsDir": "packages"
5 | },
6 | "$schema": "./node_modules/nx/schemas/nx-schema.json",
7 | "targetDefaults": {
8 | "build": {
9 | "dependsOn": ["^build"],
10 | "inputs": ["production", "^production"],
11 | "cache": true
12 | },
13 | "test": {
14 | "inputs": ["default", "^production", "{workspaceRoot}/jest.preset.js"],
15 | "cache": true
16 | },
17 | "lint": {
18 | "inputs": ["default", "{workspaceRoot}/.eslintrc.json"],
19 | "cache": true
20 | },
21 | "e2e": {
22 | "cache": true
23 | }
24 | },
25 | "namedInputs": {
26 | "default": ["{projectRoot}/**/*", "sharedGlobals"],
27 | "sharedGlobals": [
28 | "{workspaceRoot}/workspace.json",
29 | "{workspaceRoot}/tsconfig.base.json",
30 | "{workspaceRoot}/tslint.json",
31 | "{workspaceRoot}/.github/**/*.yml",
32 | "{workspaceRoot}/nx.json"
33 | ],
34 | "production": [
35 | "default",
36 | "!{projectRoot}/**/?(*.)+(spec|test).[jt]s?(x)?(.snap)",
37 | "!{projectRoot}/tsconfig.spec.json",
38 | "!{projectRoot}/jest.config.[jt]s",
39 | "!{projectRoot}/.eslintrc.json",
40 | "!{projectRoot}/src/test-setup.[jt]s"
41 | ]
42 | },
43 | "parallel": 1,
44 | "defaultBase": "origin/main",
45 | "useLegacyCache": true
46 | }
47 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/angular-app/files/src/app/auth-callback/auth-callback.component.spec.ts__tmpl__:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed } from '@angular/core/testing';
2 | import { AuthCallbackComponent } from './auth-callback.component';
3 | import {
4 | BrowserDynamicTestingModule,
5 | platformBrowserDynamicTesting
6 | } from "@angular/platform-browser-dynamic/testing";
7 |
8 | describe('AuthCallbackComponent', () => {
9 | let component: AuthCallbackComponent;
10 | let fixture: ComponentFixture;
11 | let envData = {"production":false,"access":{"url":"https://testurl.com","realm":"123","client_id":"urn:ads:platform:tenant-admin-app"},"tenantApi":{"host":"http://localhost:3333","endpoints":{"tenantNameByRealm":"/api/tenant/v1/realm"}}}
12 |
13 | localStorage.setItem('envData', JSON.stringify(envData));
14 |
15 | beforeEach((() => {
16 | TestBed.initTestEnvironment(
17 | BrowserDynamicTestingModule,
18 | platformBrowserDynamicTesting()
19 | );
20 |
21 | TestBed.configureTestingModule({
22 | declarations: [AuthCallbackComponent],
23 | }).compileComponents();
24 |
25 | fixture = TestBed.createComponent(AuthCallbackComponent);
26 | component = fixture.componentInstance;
27 | fixture.detectChanges();
28 | }));
29 |
30 | it('should create', () => {
31 | expect(component).toBeTruthy();
32 | });
33 | });
34 |
--------------------------------------------------------------------------------
/packages/nx-release/src/release-plugin/nx-utils.spec.ts:
--------------------------------------------------------------------------------
1 | import { getProjectChangePaths } from './nx-util';
2 | jest.mock('child_process', () => ({
3 | exec: jest.fn((_c, cb) => cb(null)),
4 | }));
5 | jest.mock('fs', () => ({
6 | readFile: jest.fn((_f, _e, cb) =>
7 | cb(
8 | null,
9 | Buffer.from(
10 | JSON.stringify({
11 | graph: {
12 | nodes: {
13 | test: { data: { root: 'libs/test' } },
14 | dep: { data: { root: 'libs/dep' } },
15 | },
16 | dependencies: {
17 | test: [
18 | {
19 | type: 'static',
20 | target: 'dep',
21 | },
22 | ],
23 | },
24 | },
25 | }),
26 | 'utf-8'
27 | )
28 | )
29 | ),
30 | }));
31 |
32 | describe('getProjectChangePaths', () => {
33 | it('can get paths', async () => {
34 | const paths = await getProjectChangePaths('', 'test');
35 |
36 | expect(paths.length).toBe(2);
37 | expect(paths[0]).toBe('libs/test');
38 | expect(paths[1]).toBe('libs/dep');
39 | });
40 |
41 | it('can get paths with working directory', async () => {
42 | const paths = await getProjectChangePaths('libs/test', 'test');
43 |
44 | expect(paths.length).toBe(2);
45 | expect(paths[0]).toBe('libs/test');
46 | expect(paths[1]).toBe('libs/dep');
47 | });
48 | });
49 |
--------------------------------------------------------------------------------
/.github/workflows/pull-request.yml:
--------------------------------------------------------------------------------
1 | # This is a basic workflow to help you get started with Actions
2 |
3 | name: Pull Request Check
4 |
5 | # Controls when the action will run.
6 | on:
7 | # Triggers the workflow on push or pull request events but only for the main branch
8 | pull_request:
9 | branches:
10 | - main
11 | - beta
12 |
13 | # Allows you to run this workflow manually from the Actions tab
14 | workflow_dispatch:
15 |
16 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel
17 | jobs:
18 | # This workflow contains a single job called "build"
19 | build:
20 | # The type of runner that the job will run on
21 | runs-on: ubuntu-latest
22 |
23 | # Steps represent a sequence of tasks that will be executed as part of the job
24 | steps:
25 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
26 | - uses: actions/checkout@v3
27 | with:
28 | fetch-depth: 0
29 | - uses: actions/setup-node@v3
30 | with:
31 | node-version: "20"
32 | cache: "npm"
33 | - run: npm ci
34 | - name: Lint
35 | run: npm run affected:lint -- --base=origin/${{ github.base_ref }}
36 | - name: Test
37 | run: npm run affected:test -- --base=origin/${{ github.base_ref }}
38 | - name: Build
39 | run: npm run affected:build -- --base=origin/${{ github.base_ref }}
40 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/angular-app/files/src/app/app.component.css__tmpl__:
--------------------------------------------------------------------------------
1 | .container {
2 | width: 100%;
3 | margin: 0 auto;
4 | padding: 0;
5 | }
6 |
7 | @media (min-width: 640px) {
8 | .container {
9 | margin: 0 auto;
10 | padding: 3rem 1rem;
11 | width: 640px;
12 | }
13 | }
14 | @media (min-width: 768px) {
15 | .container {
16 | margin: 0 auto;
17 | padding: 3rem 1rem;
18 | width: 768px;
19 | }
20 | }
21 | @media (min-width: 1024px) {
22 | .container {
23 | padding: 3rem 1rem;
24 | margin: 0 auto;
25 | width: 1024px;
26 | }
27 | }
28 | @media (min-width: 1280px) {
29 | .container {
30 | padding: 3rem 1rem;
31 | margin: 0 auto;
32 | width: 1280px;
33 | }
34 | }
35 |
36 | .nextSteps {
37 | margin-top: 0;
38 | }
39 |
40 | .nextSteps li {
41 | margin-top: 0;
42 | margin-bottom: 0;
43 | line-height: 50px;
44 | }
45 |
46 | .nextSteps li button {
47 | margin: 20px 0 0 10px;
48 | }
49 |
50 |
51 | .footer {
52 | background-color: #f1f1f1;
53 | padding-top: 56px;
54 | padding-bottom: 56px;
55 | padding-left: 150px;
56 | padding-right: 150px;
57 | display: flex;
58 | flex-direction: row;
59 | flex-wrap: wrap;
60 | border-bottom: 16px solid #0081a2;
61 | }
62 |
63 | @media (max-width: 767px) {
64 | /* On small screens, the nav menu spans the full width of the screen. Leave a space for it. */
65 | .body-content {
66 | padding-top: 50px;
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/angular-app/files/src/app/auth-callback/auth-callback.component.ts__tmpl__:
--------------------------------------------------------------------------------
1 | import { Injectable, Component, OnInit } from '@angular/core';
2 | import { AuthService } from '../services/auth.service';
3 | import { User } from 'oidc-client';
4 |
5 | @Component({
6 | selector: '<%= projectName %>-app-auth-callback',
7 | templateUrl: './auth-callback.component.html',
8 | styleUrls: ['./auth-callback.component.css'],
9 | })
10 | @Injectable({
11 | providedIn: 'root',
12 | })
13 | export class AuthCallbackComponent implements OnInit {
14 | public tokenType = '';
15 | public accessToken = '';
16 |
17 | constructor(private authService: AuthService) {}
18 |
19 | ngOnInit() {
20 | this.getAuth();
21 | }
22 |
23 | getAuth() {
24 | if (!this.authService.isLoggedIn()) {
25 | this.authService
26 | .completeAuthentication()
27 | .catch((error) => {
28 | console.error(`could not complete authentication: ${error}`);
29 | })
30 | .then(() => {
31 | this.setTokens();
32 | });
33 | }
34 | }
35 |
36 | setTokens() {
37 | if (this.authService.isLoggedIn()) {
38 | const user: User | null = this.authService.getUser();
39 | if (user) {
40 | this.accessToken = user.access_token;
41 | this.tokenType = user.token_type;
42 | }
43 | return true;
44 | } else {
45 | return false;
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/docs/Gemfile:
--------------------------------------------------------------------------------
1 | source "https://rubygems.org"
2 |
3 | # Hello! This is where you manage which Jekyll version is used to run.
4 | # When you want to use a different version, change it below, save the
5 | # file and run `bundle install`. Run Jekyll with `bundle exec`, like so:
6 | #
7 | # bundle exec jekyll serve
8 | #
9 | # This will help ensure the proper Jekyll version is running.
10 | # Happy Jekylling!
11 | # gem "jekyll", "~> 3.9.0"
12 |
13 | # This is the default theme for new Jekyll sites. You may change this to anything you like.
14 | # gem "minima", "~> 2.0"
15 | # gem "just-the-docs"
16 |
17 | # If you want to use GitHub Pages, remove the "gem "jekyll"" above and
18 | # uncomment the line below. To upgrade, run `bundle update github-pages`.
19 | gem "github-pages", "~> 228", group: :jekyll_plugins
20 |
21 | # If you have any plugins, put them here!
22 | group :jekyll_plugins do
23 | gem "jekyll-remote-theme", "~> 0.4.3"
24 | end
25 |
26 | # Windows does not include zoneinfo files, so bundle the tzinfo-data gem
27 | # and associated library.
28 | install_if -> { RUBY_PLATFORM =~ %r!mingw|mswin|java! } do
29 | gem "tzinfo", "~> 1.2"
30 | gem "tzinfo-data"
31 | end
32 |
33 | # Performance-booster for watching directories on Windows
34 | gem "wdm", "~> 0.1.0", :install_if => Gem.win_platform?
35 |
36 | # kramdown v2 ships without the gfm parser by default. If you're using
37 | # kramdown v1, comment out this line.
38 | gem "kramdown-parser-gfm"
39 |
40 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/mern/mern.spec.ts:
--------------------------------------------------------------------------------
1 | import { readProjectConfiguration } from '@nx/devkit';
2 | import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
3 |
4 | import * as utils from '@abgov/nx-oc';
5 | import { environments } from '@abgov/nx-oc';
6 | import { Schema } from './schema';
7 | import generator from './mern';
8 |
9 | jest.mock('@abgov/nx-oc');
10 | const utilsMock = utils as jest.Mocked;
11 | utilsMock.getAdspConfiguration.mockResolvedValue({
12 | tenant: 'test',
13 | tenantRealm: 'test',
14 | accessServiceUrl: environments.test.accessServiceUrl,
15 | directoryServiceUrl: environments.test.directoryServiceUrl,
16 | });
17 |
18 | describe.skip('React App Generator', () => {
19 | const options: Schema = {
20 | name: 'test',
21 | env: 'dev',
22 | };
23 |
24 | it('can run', async () => {
25 | const host = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
26 | await generator(host, options);
27 |
28 | const appConfig = readProjectConfiguration(host, 'test-app');
29 | expect(appConfig.root).toBe('apps/test-app');
30 |
31 | const serviceConfig = readProjectConfiguration(host, 'test-service');
32 | expect(serviceConfig.root).toBe('apps/test-service');
33 |
34 | expect(host.exists('apps/test-app/nginx.conf')).toBeTruthy();
35 | const nginxConf = host.read('apps/test-app/nginx.conf').toString();
36 | expect(nginxConf).toContain('http://test-service:3333/');
37 | }, 30000);
38 | });
39 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/react-app/files/src/app/app.spec.tsx__tmpl__:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Provider } from 'react-redux';
3 | import { getDefaultMiddleware } from '@reduxjs/toolkit';
4 | import { render } from '@testing-library/react';
5 | import { BrowserRouter } from 'react-router-dom';
6 | import configureStore from 'redux-mock-store';
7 |
8 | import App from './app';
9 |
10 | const mockStore = configureStore(getDefaultMiddleware());
11 |
12 | describe('App', () => {
13 | let store, userManager;
14 |
15 | beforeEach(() => {
16 | store = mockStore({
17 | user: {},
18 | intake: {},
19 | start: {}
20 | });
21 |
22 | userManager = {
23 | signoutRedirect: jest.fn(),
24 | signinRedirect: jest.fn()
25 | }
26 | });
27 |
28 | it('should render successfully', () => {
29 | const { baseElement } = render(
30 |
31 |
32 |
33 |
34 |
35 | );
36 |
37 | expect(baseElement).toBeTruthy();
38 | });
39 |
40 | it('should have a greeting as the title', () => {
41 | const { getByText } = render(
42 |
43 |
44 |
45 |
46 |
47 | );
48 |
49 | expect(getByText('Welcome to <%= projectName %>!')).toBeTruthy();
50 | });
51 | });
52 |
--------------------------------------------------------------------------------
/packages/semantic-release-nuget/project.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "semantic-release-nuget",
3 | "$schema": "../../node_modules/nx/schemas/project-schema.json",
4 | "sourceRoot": "packages/semantic-release-nuget/src",
5 | "projectType": "library",
6 | "targets": {
7 | "lint": {
8 | "executor": "@nx/eslint:lint",
9 | "outputs": ["{options.outputFile}"],
10 | "options": {
11 | "lintFilePatterns": ["packages/semantic-release-nuget/**/*.ts"]
12 | }
13 | },
14 | "test": {
15 | "executor": "@nx/jest:jest",
16 | "outputs": ["{workspaceRoot}/coverage/packages/semantic-release-nuget"],
17 | "options": {
18 | "jestConfig": "packages/semantic-release-nuget/jest.config.ts",
19 | "passWithNoTests": true
20 | }
21 | },
22 | "build": {
23 | "executor": "@nx/js:tsc",
24 | "outputs": ["{options.outputPath}"],
25 | "options": {
26 | "outputPath": "dist/packages/semantic-release-nuget",
27 | "tsConfig": "packages/semantic-release-nuget/tsconfig.lib.json",
28 | "packageJson": "packages/semantic-release-nuget/package.json",
29 | "main": "packages/semantic-release-nuget/src/index.ts",
30 | "assets": ["packages/semantic-release-nuget/*.md"]
31 | }
32 | },
33 | "release": {
34 | "executor": "nx:run-commands",
35 | "options": {
36 | "command": "npx semantic-release -e ./packages/semantic-release-nuget/.releaserc.json"
37 | }
38 | }
39 | },
40 | "tags": []
41 | }
42 |
--------------------------------------------------------------------------------
/packages/semantic-release-nuget/src/plugin/publish.ts:
--------------------------------------------------------------------------------
1 | import { PluginFunction } from '@semantic-release/semantic-release';
2 | import { PublishContext } from 'semantic-release';
3 | import { exec as execCb } from 'child_process';
4 | import * as path from 'path';
5 | import { promisify } from 'util';
6 | import { NugetPluginConfig } from './config';
7 |
8 | const exec = promisify(execCb);
9 |
10 | export const publish: PluginFunction = async (
11 | config: NugetPluginConfig,
12 | context
13 | ) => {
14 | const { nupkgRoot, source, symbolSource, skipDuplicate, timeout } = config;
15 | const {
16 | cwd,
17 | env,
18 | // stdout,
19 | // stderr
20 | } = context;
21 |
22 | const basePath = nupkgRoot ? path.resolve(cwd, nupkgRoot) : cwd;
23 |
24 | const args = [
25 | 'dotnet',
26 | 'nuget',
27 | 'push',
28 | '*.nupkg',
29 | source ? `--source ${source}` : null,
30 | env.NUGET_API_KEY ? `--api-key ${env.NUGET_API_KEY}` : null,
31 | symbolSource ? `--symbol-source ${symbolSource}` : null,
32 | env.NUGET_API_KEY ? `--symbol-api-key ${env.NUGET_API_KEY}` : null,
33 | skipDuplicate ? '--skip-duplicate' : null,
34 | timeout ? `--timeout ${timeout}` : null,
35 | ].filter((v) => !!v);
36 |
37 | const dotnetResult = await exec(args.join(' '), { env, cwd: basePath });
38 |
39 | // dotnetResult.stdout.pipe(stdout, { end: false });
40 | // dotnetResult.stderr.pipe(stderr, { end: false });
41 |
42 | await dotnetResult;
43 |
44 | return false;
45 | };
46 |
--------------------------------------------------------------------------------
/packages/nx-oc/src/generators/pipeline/actions/openshift/environments.yml__tmpl__:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: List
3 | items:
4 | - apiVersion: rbac.authorization.k8s.io/v1
5 | kind: RoleBinding
6 | metadata:
7 | name: env_deploy_pullers
8 | namespace: <%= ocInfraProject %>
9 | roleRef:
10 | apiGroup: rbac.authorization.k8s.io
11 | kind: ClusterRole
12 | name: 'system:image-puller'
13 | subjects:
14 | <% ocEnvProjects.forEach(function(ocEnvProject){ -%>
15 | - apiGroup: rbac.authorization.k8s.io
16 | kind: Group
17 | name: 'system:serviceaccounts:<%= ocEnvProject %>'
18 | <% }); -%>
19 | - apiVersion: rbac.authorization.k8s.io/v1
20 | kind: RoleBinding
21 | metadata:
22 | name: pipeline_edit
23 | namespace: <%= ocInfraProject %>
24 | roleRef:
25 | apiGroup: rbac.authorization.k8s.io
26 | kind: ClusterRole
27 | name: edit
28 | subjects:
29 | - kind: ServiceAccount
30 | name: github-actions
31 | namespace: <%= ocInfraProject %>
32 | <% ocEnvProjects.forEach(function(ocEnvProject){ -%>
33 | - apiVersion: rbac.authorization.k8s.io/v1
34 | kind: RoleBinding
35 | metadata:
36 | name: pipeline_edit
37 | namespace: <%= ocEnvProject %>
38 | roleRef:
39 | apiGroup: rbac.authorization.k8s.io
40 | kind: ClusterRole
41 | name: edit
42 | subjects:
43 | - kind: ServiceAccount
44 | name: github-actions
45 | namespace: <%= ocInfraProject %>
46 | <% }); -%>
47 |
--------------------------------------------------------------------------------
/packages/nx-release/src/release-plugin/nx-util.ts:
--------------------------------------------------------------------------------
1 | import { exec } from 'child_process';
2 | import { readFile } from 'fs';
3 | import { resolve } from 'path';
4 | import { promisify } from 'util';
5 |
6 | interface ProjectNode {
7 | data: {
8 | root: string
9 | }
10 | }
11 |
12 | interface Dependency {
13 | type: 'static' | 'implicit';
14 | target: string;
15 | }
16 |
17 | interface DependencyGraph {
18 | nodes: Record;
19 | dependencies: Record;
20 | }
21 |
22 | const paths: Record = {}
23 |
24 | export const getProjectChangePaths = async (cwd: string, project: string) => {
25 |
26 | if (!paths[project]) {
27 |
28 | const file = resolve(cwd, `tmp/${project}-deps.json`);
29 | await promisify(exec)(
30 | [
31 | 'npx',
32 | 'nx',
33 | 'dep-graph',
34 | '--focus',
35 | project,
36 | '--file',
37 | file
38 | ].join(' ')
39 | );
40 |
41 | const result = await promisify(readFile)(file, 'utf8');
42 | const { graph }: { graph: DependencyGraph } = JSON.parse(result);
43 |
44 | // Include the project's root as well as the roots of all its dependencies.
45 | paths[project] = [
46 | graph.nodes[project].data.root,
47 | ...graph.dependencies[project]
48 | .map(d =>
49 | d.type === 'static' ?
50 | graph.nodes[d.target].data.root : null
51 | )
52 | .filter(d => !!d)
53 | ];
54 | }
55 |
56 | return paths[project];
57 | }
58 |
--------------------------------------------------------------------------------
/packages/nx-oc/src/generators/pipeline/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://json-schema.org/schema",
3 | "id": "NxOcPipeline",
4 | "title": "",
5 | "type": "object",
6 | "properties": {
7 | "pipeline": {
8 | "type": "string",
9 | "description": "Name of the OpenShift Pipeline.",
10 | "$default": {
11 | "$source": "argv",
12 | "index": 0
13 | },
14 | "x-prompt": "What should be the name of the oc pipeline?"
15 | },
16 | "infra": {
17 | "type": "string",
18 | "description": "Name of the OpenShift Project for build infrastructure.",
19 | "$default": {
20 | "$source": "argv",
21 | "index": 1
22 | },
23 | "alias": "i",
24 | "x-prompt": "What project should be used for build infrastructure?"
25 | },
26 | "type": {
27 | "type": "string",
28 | "description": "Jenkins or GitHub Actions based pipeline.",
29 | "alias": "t",
30 | "default": "actions"
31 | },
32 | "envs": {
33 | "type": "string",
34 | "description": "Names of the OpenShift Projects for environments.",
35 | "alias": "e",
36 | "x-prompt": "What projects should be used for environments (dev test prod)?"
37 | },
38 | "apply": {
39 | "type": "boolean",
40 | "description": "Flag indicating if the pipeline should be applied.",
41 | "alias": "a",
42 | "x-prompt": "Apply the pipeline to OpenShift?"
43 | }
44 | },
45 | "required": [
46 | "pipeline",
47 | "infra",
48 | "type",
49 | "envs"
50 | ]
51 | }
52 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/react-task-list/files/__fileName__/__fileName__.module.css__tmpl__:
--------------------------------------------------------------------------------
1 | .taskList {
2 | width: 80vw;
3 | height: 80vh;
4 | display: flex;
5 | flex-direction: column;
6 |
7 | .header {
8 | height: 6vh;
9 | flex-shrink: 0;
10 | flex-grow: 0;
11 |
12 | > div:first-child {
13 | display: flex;
14 | align-items: baseline;
15 |
16 | > span {
17 | margin-right: 14px;
18 | }
19 |
20 | > span:first-child {
21 | margin-left: 14px;
22 | }
23 |
24 | > :last-child {
25 | margin-left: auto;
26 | }
27 | }
28 | }
29 |
30 | .details {
31 | height: 0;
32 | transition: height 200ms;
33 | position: relative;
34 | flex-shrink: 0;
35 |
36 | > * {
37 | height: 100%;
38 | width: 100%;
39 | }
40 |
41 | .detailsPlaceholder {
42 | display: flex;
43 | flex-direction: column;
44 |
45 | > *:first-child {
46 | flex-grow: 1;
47 | }
48 | }
49 | }
50 |
51 | .details[data-opened='true'] {
52 | height: 74vh;
53 | }
54 |
55 | .list {
56 | flex-grow: 1;
57 | flex-shrink: 1;
58 | position: relative;
59 | overflow: hidden;
60 |
61 | > div:first-child {
62 | display: flex;
63 | flex-direction: row;
64 |
65 | > :first-child {
66 | margin-right: auto;
67 | }
68 | }
69 | }
70 |
71 | .loading {
72 | flex-grow: 2;
73 | flex-shrink: 0;
74 | height: 80vh;
75 | display: flex;
76 | > * {
77 | margin: auto;
78 | }
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/react-app/files/src/app/app.module.css__tmpl__:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | }
4 |
5 | main {
6 | display: grid;
7 | grid-template-columns: repeat(6, auto);
8 | }
9 |
10 | section {
11 | grid-column: 2 / span 2;
12 | margin-top: 40px;
13 | margin-bottom: 40px;
14 | }
15 |
16 | .app {
17 | margin: 0;
18 | }
19 |
20 | .nextSteps {
21 | margin-top: 0;
22 | }
23 |
24 | .nextSteps li {
25 | margin-top: 0;
26 | margin-bottom: 0;
27 | line-height: 50px;
28 | }
29 |
30 | .nextSteps li button {
31 | margin: 20px 0 0 10px;
32 | }
33 |
34 | .github a:before {
35 | background: url("data:image/svg+xml,%3Csvg version='1.0' xmlns='http://www.w3.org/2000/svg' width='18' height='18' viewBox='0 0 255 255'%3E%3Cg transform='translate(0,255) scale(0.8,-0.8)'%0Afill='%23000000' stroke='none'%3E%3Cpath d='M72 300 c-48 -29 -72 -75 -72 -138 0 -60 17 -101 56 -131 35 -28 74%0A-28 74 -1 0 15 -7 20 -24 20 -14 0 -27 4 -30 9 -3 4 6 6 20 3 16 -3 30 1 35 9%0A14 22 11 26 -20 32 -35 7 -59 54 -42 85 6 12 11 30 11 42 0 14 4 19 12 14 18%0A-11 110 -13 131 -2 13 7 17 4 17 -12 0 -12 5 -30 11 -42 17 -31 -7 -78 -43%0A-85 -20 -4 -27 -10 -24 -20 4 -8 6 -28 6 -44 0 -24 4 -29 24 -29 29 0 72 33%0A91 70 8 16 15 53 15 82 0 63 -24 109 -72 138 -45 27 -131 27 -176 0z'/%3E%3C/g%3E%3C/svg%3E")
36 | no-repeat center center;
37 | }
38 |
39 | .footer {
40 | background-color: #f1f1f1;
41 | padding-top: 56px;
42 | padding-bottom: 56px;
43 | padding-left: 150px;
44 | padding-right: 150px;
45 | display: flex;
46 | flex-direction: row;
47 | flex-wrap: wrap;
48 | border-bottom: 16px solid #0081a2
49 | }
50 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/react-dotnet/react-dotnet.spec.ts:
--------------------------------------------------------------------------------
1 | import { readProjectConfiguration } from '@nx/devkit';
2 | import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
3 |
4 | import * as utils from '@abgov/nx-oc';
5 | import { environments } from '@abgov/nx-oc';
6 | import serviceGenerator from '../dotnet-service/dotnet-service';
7 | import { Schema } from './schema';
8 | import generator from './react-dotnet';
9 |
10 | jest.mock('@abgov/nx-oc');
11 | const utilsMock = utils as jest.Mocked;
12 | utilsMock.getAdspConfiguration.mockResolvedValue({
13 | tenant: 'test',
14 | tenantRealm: 'test',
15 | accessServiceUrl: environments.test.accessServiceUrl,
16 | directoryServiceUrl: environments.test.directoryServiceUrl,
17 | });
18 |
19 | jest.mock('../dotnet-service/dotnet-service');
20 | const serviceGeneratorMock = serviceGenerator as jest.Mocked<
21 | typeof serviceGenerator
22 | >;
23 |
24 | describe('React App Generator', () => {
25 | const options: Schema = {
26 | name: 'test',
27 | env: 'dev',
28 | };
29 |
30 | it('can run', async () => {
31 | const host = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
32 | await generator(host, options);
33 |
34 | const appConfig = readProjectConfiguration(host, 'test-app');
35 | expect(appConfig.root).toBe('apps/test-app');
36 |
37 | expect(serviceGeneratorMock).toHaveBeenCalled();
38 |
39 | expect(host.exists('apps/test-app/nginx.conf')).toBeTruthy();
40 | const nginxConf = host.read('apps/test-app/nginx.conf').toString();
41 | expect(nginxConf).toContain('http://test-service:5000/');
42 | }, 30000);
43 | });
44 |
--------------------------------------------------------------------------------
/packages/nx-oc/src/generators/deployment/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://json-schema.org/schema",
3 | "id": "NxOcDeployment",
4 | "title": "",
5 | "type": "object",
6 | "properties": {
7 | "project": {
8 | "type": "string",
9 | "description": "Project to add deployment in.",
10 | "$default": {
11 | "$source": "argv",
12 | "index": 0
13 | },
14 | "x-prompt": "Which project to add deployment for?"
15 | },
16 | "appType": {
17 | "type": "string",
18 | "description": "Type of application.",
19 | "$default": {
20 | "$source": "argv",
21 | "index": 1
22 | },
23 | "alias": "t",
24 | "x-prompt": {
25 | "message": "What type of application is the project?",
26 | "type": "list",
27 | "items": [
28 | "frontend",
29 | "dotnet",
30 | "node"
31 | ]
32 | }
33 | },
34 | "env": {
35 | "type": "string",
36 | "description": "Environment to target.",
37 | "$default": {
38 | "$source": "argv",
39 | "index": 2
40 | },
41 | "alias": "e",
42 | "x-prompt": {
43 | "message": "Which ADSP environment do you want to target?",
44 | "type": "list",
45 | "items": [
46 | "dev",
47 | "test",
48 | "prod"
49 | ]
50 | }
51 | },
52 | "accessToken": {
53 | "type": "string",
54 | "description": "Access token for retrieving configuration from ADSP APIs.",
55 | "alias": "at"
56 | }
57 | },
58 | "required": [
59 | "project",
60 | "appType",
61 | "env"
62 | ]
63 | }
64 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/react-dotnet/react-dotnet.ts:
--------------------------------------------------------------------------------
1 | import { getAdspConfiguration } from '@abgov/nx-oc';
2 | import {
3 | getWorkspaceLayout,
4 | installPackagesTask,
5 | names,
6 | Tree,
7 | } from '@nx/devkit';
8 | import initDotnetService from '../dotnet-service/dotnet-service';
9 | import initReactApp from '../react-app/react-app';
10 | import { NormalizedSchema, Schema } from './schema';
11 |
12 | async function normalizeOptions(
13 | host: Tree,
14 | options: Schema
15 | ): Promise {
16 | const name = names(options.name).fileName;
17 | const projectDirectory = name;
18 | const projectName = projectDirectory.replace(new RegExp('/', 'g'), '-');
19 | const projectRoot = `${getWorkspaceLayout(host).appsDir}/${projectDirectory}`;
20 | const openshiftDirectory = `.openshift/${projectDirectory}`;
21 |
22 | const adsp = await getAdspConfiguration(host, options);
23 |
24 | return {
25 | ...options,
26 | projectName,
27 | projectRoot,
28 | projectDirectory,
29 | openshiftDirectory,
30 | adsp,
31 | };
32 | }
33 |
34 | export default async function (host: Tree, options: Schema) {
35 | const normalizedOptions = await normalizeOptions(host, options);
36 |
37 | await initDotnetService(host, {
38 | ...normalizedOptions,
39 | name: `${options.name}-service`,
40 | });
41 |
42 | await initReactApp(host, {
43 | ...normalizedOptions,
44 | name: `${options.name}-app`,
45 | proxy: {
46 | location: '/api/',
47 | proxyPass: `http://${options.name}-service:5000/${options.name}-service/`,
48 | },
49 | });
50 |
51 | return () => {
52 | installPackagesTask(host);
53 | };
54 | }
55 |
--------------------------------------------------------------------------------
/packages/nx-release/src/generators/lib/lib.spec.ts:
--------------------------------------------------------------------------------
1 | import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
2 | import {
3 | Tree,
4 | readProjectConfiguration,
5 | addProjectConfiguration,
6 | writeJson,
7 | readJson,
8 | } from '@nx/devkit';
9 |
10 | import generator from './lib';
11 | import { Schema } from './schema';
12 |
13 | describe('nx-release generator', () => {
14 | let appTree: Tree;
15 | const options: Schema = { project: 'test' };
16 |
17 | beforeEach(() => {
18 | appTree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
19 | addProjectConfiguration(appTree, 'test', {
20 | root: 'libs/test',
21 | projectType: 'library',
22 | targets: {
23 | build: {
24 | executor: '@nx/node:package',
25 | options: {
26 | outputPath: 'dist/libs/test',
27 | },
28 | },
29 | },
30 | });
31 | });
32 |
33 | it('should run successfully', async () => {
34 | await generator(appTree, options);
35 | const config = readProjectConfiguration(appTree, 'test');
36 |
37 | expect(config.targets.release).toBeDefined();
38 | expect(appTree.exists('.releaserc.json')).toBeTruthy();
39 | expect(appTree.exists('libs/test/.releaserc.json')).toBeTruthy();
40 | });
41 |
42 | it('should skip root .releaserc.json if present', async () => {
43 | await generator(appTree, options);
44 | const config = readProjectConfiguration(appTree, 'test');
45 | const releaseConfig = { value: 'a' };
46 | writeJson(appTree, '.releaserc.json', releaseConfig);
47 |
48 | expect(config.targets.release).toBeDefined();
49 | expect(readJson(appTree, '.releaserc.json')).toMatchObject(releaseConfig);
50 | });
51 | });
52 |
--------------------------------------------------------------------------------
/docs/_config.yml:
--------------------------------------------------------------------------------
1 | # Welcome to Jekyll!
2 | #
3 | # This config file is meant for settings that affect your whole blog, values
4 | # which you are expected to set up once and rarely edit after that. If you find
5 | # yourself editing this file very often, consider using Jekyll's data files
6 | # feature for the data you need to update frequently.
7 | #
8 | # For technical reasons, this file is *NOT* reloaded automatically when you use
9 | # 'bundle exec jekyll serve'. If you change this file, please restart the server process.
10 |
11 | # Site settings
12 | # These are used to personalize your new site. If you look in the HTML files,
13 | # you will see them accessed via {{ site.title }}, {{ site.email }}, and so on.
14 | # You can create any custom variable you would like, and they will be accessible
15 | # in the templates via {{ site.myvariable }}.
16 | title: Nx Tools Guide
17 | email: DIO@gov.ab.ca
18 | description: >- # this means to ignore newlines until "baseurl:"
19 | Government of Alberta plugins for nx guide.
20 | baseurl: "/nx-tools" # the subpath of your site, e.g. /blog
21 | url: "https://govalta.github.io" # the base hostname & protocol for your site, e.g. http://example.com
22 | # twitter_username: jekyllrb
23 | # github_username: jekyll
24 |
25 | # Build settings
26 | markdown: kramdown
27 | remote_theme: pmarsceill/just-the-docs
28 | plugins:
29 | - jekyll-remote-theme
30 | # - jekyll-feed
31 |
32 | # Exclude from processing.
33 | # The following items will not be processed, by default. Create a custom list
34 | # to override the default setting.
35 | # exclude:
36 | # - Gemfile
37 | # - Gemfile.lock
38 | # - node_modules
39 | # - vendor/bundle/
40 | # - vendor/cache/
41 | # - vendor/gems/
42 | # - vendor/ruby/
43 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/angular-app/files/src/app/app.module.ts__tmpl__:
--------------------------------------------------------------------------------
1 | import { NgModule, APP_INITIALIZER, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
2 | import { BrowserModule } from '@angular/platform-browser';
3 | import "@abgov/web-components";
4 | import { AngularComponentsModule } from '@abgov/angular-components';
5 |
6 | import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http';
7 | import { AuthInterceptor } from './auth.interceptor';
8 | import { FormsModule } from '@angular/forms';
9 | import { AppRoutingModule } from './app.routes';
10 | import { ProtectedComponent } from './protected/protected.component';
11 | import { AuthCallbackComponent } from './auth-callback/auth-callback.component';
12 | import { AuthGuardService } from './services/auth-guard.service';
13 | import { AuthService } from './services/auth.service';
14 | import { AppComponent } from './app.component';
15 | import { Config } from '../environments/config';
16 |
17 | @NgModule({
18 | imports: [
19 | AngularComponentsModule,
20 | BrowserModule,
21 | HttpClientModule,
22 | FormsModule,
23 | AppRoutingModule,
24 | ],
25 | providers: [
26 | AuthGuardService,
27 | AuthService,
28 | Config,
29 | {
30 | provide: APP_INITIALIZER,
31 | useFactory: initializeApp,
32 | deps: [Config],
33 | multi: true,
34 | },
35 | { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true },
36 | ],
37 | declarations: [AppComponent, AuthCallbackComponent, ProtectedComponent],
38 | bootstrap: [AppComponent],
39 | schemas: [CUSTOM_ELEMENTS_SCHEMA],
40 | })
41 | export class AppModule {}
42 |
43 | export function initializeApp(config: Config) {
44 | return (): Promise => {
45 | return config.Init();
46 | };
47 | }
48 |
--------------------------------------------------------------------------------
/packages/nx-oc/src/executors/apply/apply.spec.ts:
--------------------------------------------------------------------------------
1 | import { ExecutorContext } from '@nx/devkit';
2 | import { mocked } from 'jest-mock';
3 | import { Schema } from './schema';
4 | import executor from './apply';
5 | import { runOcCommand } from '../../utils/oc-utils';
6 |
7 | jest.mock('../../utils/oc-utils');
8 | const mockedRunOcCommand = mocked(runOcCommand);
9 |
10 | const options: Schema = { ocProject: 'test-dev' };
11 |
12 | describe('Apply Executor', () => {
13 | beforeEach(() => {
14 | mockedRunOcCommand.mockReset();
15 | });
16 |
17 | it('can run', async () => {
18 | mockedRunOcCommand.mockReturnValue({ success: true });
19 |
20 | const { success } = await executor(options, {
21 | projectName: 'test',
22 | } as ExecutorContext);
23 | expect(success).toBe(true);
24 |
25 | expect(mockedRunOcCommand.mock.calls.length).toBe(2);
26 | expect(mockedRunOcCommand.mock.calls[0][0]).toBe('process');
27 | expect(mockedRunOcCommand.mock.calls[1][0]).toBe('apply');
28 | });
29 |
30 | it('can run for multiple environments', async () => {
31 | mockedRunOcCommand.mockReturnValue({ success: true });
32 |
33 | const { success } = await executor(
34 | { ...options, ocProject: ['test-dev', 'test-qa'] },
35 | { projectName: 'test' } as ExecutorContext
36 | );
37 |
38 | expect(success).toBe(true);
39 | expect(mockedRunOcCommand.mock.calls.length).toBe(4);
40 | });
41 |
42 | it('can return unsuccessful result', async () => {
43 | mockedRunOcCommand.mockReturnValue({ success: false });
44 |
45 | const { success } = await executor(options, {
46 | projectName: 'test',
47 | } as ExecutorContext);
48 |
49 | expect(success).toBe(false);
50 | expect(mockedRunOcCommand.mock.calls.length).toBe(1);
51 | });
52 | });
53 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/angular-app/files/src/app/services/auth.service.ts__tmpl__:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import { UserManager, UserManagerSettings, User } from 'oidc-client';
3 |
4 | @Injectable({
5 | providedIn: 'root',
6 | })
7 | export class AuthService {
8 | private manager = new UserManager(getClientSettings());
9 | private user: User | null = null;
10 |
11 | constructor() {
12 | this.manager.getUser().then((user) => {
13 | this.user = user;
14 | });
15 | }
16 |
17 | isLoggedIn(): boolean {
18 | return this.user != null && !this.user.expired;
19 | }
20 |
21 | getUser(): User | null {
22 | return this.user;
23 | }
24 |
25 | startAuthentication(): Promise {
26 | return this.manager.signinRedirect();
27 | }
28 |
29 | completeAuthentication(): Promise {
30 | return this.manager.signinRedirectCallback().then((user) => {
31 | this.user = user;
32 | console.log(JSON.stringify(this.user));
33 | });
34 | }
35 |
36 | logout() {
37 | return this.manager.signoutRedirect();
38 | }
39 | }
40 |
41 | export function getClientSettings(): UserManagerSettings {
42 | const data = JSON.parse(localStorage.getItem('envData') || "\"\"");
43 | const appUrl = `${window.location.protocol}//${window.location.hostname}${
44 | window.location.port ? `:${window.location.port}` : ''
45 | }`;
46 |
47 | const settings = {
48 | client_id: data.access.client_id,
49 | redirect_uri: `${appUrl}/auth-callback`,
50 | post_logout_redirect_uri: `${appUrl}/signout/callback`,
51 | silent_redirect_uri: `${appUrl}/auth-callback`,
52 | response_type: 'code',
53 | authority: `${data.access.url}/auth/realms/${data.access.realm}`,
54 | automaticSilentRenew: true,
55 | };
56 | return settings;
57 | }
58 |
--------------------------------------------------------------------------------
/packages/nx-oc/src/executors/apply/apply.ts:
--------------------------------------------------------------------------------
1 | import { ExecutorContext } from '@nx/devkit';
2 | import { pipelineEnvs as envs } from '../../pipeline-envs';
3 | import { runOcCommand } from '../../utils/oc-utils';
4 | import { NormalizedSchema, PipelineEnvironment, Schema } from './schema';
5 |
6 | function mapOcProject(
7 | project: string | PipelineEnvironment,
8 | i: number
9 | ): PipelineEnvironment {
10 | if (typeof project === 'string') {
11 | return { project: 'string', tag: envs[i].toLowerCase() };
12 | } else {
13 | return project;
14 | }
15 | }
16 |
17 | function normalizeSchema(options: Schema): NormalizedSchema {
18 | const ocProjects = Array.isArray(options.ocProject)
19 | ? options.ocProject.map(mapOcProject)
20 | : [mapOcProject(options.ocProject, 0)];
21 |
22 | return { ocProjects };
23 | }
24 |
25 | export default async function runExecutor(
26 | options: Schema,
27 | { projectName }: ExecutorContext
28 | ): Promise<{ success: boolean }> {
29 | console.log(`Running oc apply for ${projectName}...`);
30 |
31 | const { ocProjects } = normalizeSchema(options);
32 |
33 | const failed = ocProjects
34 | .map(({ project, tag }) => {
35 | const processResult = runOcCommand('process', [
36 | `-f .openshift/${projectName}/${projectName}.yml`,
37 | `-p PROJECT=${project}`,
38 | `-p DEPLOY_TAG=${tag}`,
39 | ]);
40 |
41 | if (!processResult.success) {
42 | return false;
43 | } else {
44 | const { success, stdout } = runOcCommand(
45 | 'apply',
46 | [],
47 | processResult.stdout
48 | );
49 | console.log(stdout?.toString());
50 |
51 | return success;
52 | }
53 | })
54 | .filter((success) => !success);
55 |
56 | return {
57 | success: !failed.length,
58 | };
59 | }
60 |
--------------------------------------------------------------------------------
/.github/workflows/release-ci.yml:
--------------------------------------------------------------------------------
1 | # This is a basic workflow to help you get started with Actions
2 |
3 | name: Release CI
4 |
5 | # Controls when the action will run.
6 | on:
7 | # Triggers the workflow on push or pull request events but only for the main branch
8 | push:
9 | branches:
10 | - main
11 | - beta
12 |
13 | # Allows you to run this workflow manually from the Actions tab
14 | workflow_dispatch:
15 |
16 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel
17 | jobs:
18 | # This workflow contains a single job called "build"
19 | build:
20 | # The type of runner that the job will run on
21 | runs-on: ubuntu-latest
22 |
23 | # Steps represent a sequence of tasks that will be executed as part of the job
24 | steps:
25 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
26 | - uses: actions/checkout@v3
27 | with:
28 | fetch-depth: 0
29 | - uses: actions/setup-node@v3
30 | with:
31 | node-version: "20"
32 | cache: "npm"
33 | - run: npm ci
34 | - name: Get last successful commit
35 | id: last_successful_commit
36 | uses: nrwl/nx-set-shas@v3
37 | - name: Lint
38 | run: npm run affected:lint -- --base=${{ steps.last_successful_commit.outputs.base }}
39 | - name: Test
40 | run: npm run affected:test -- --base=${{ steps.last_successful_commit.outputs.base }}
41 | - name: Build
42 | run: npm run affected:build -- --base=${{ steps.last_successful_commit.outputs.base }}
43 | - name: Release
44 | env:
45 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
46 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
47 | run: npx nx affected --target release --base=${{ steps.last_successful_commit.outputs.base }}
48 |
--------------------------------------------------------------------------------
/packages/nx-adsp/README.md:
--------------------------------------------------------------------------------
1 | # About this project
2 |
3 | This is the Government of Alberta - Nx plugin for ADSP apps.
4 |
5 | The plugin includes generators for application, service, and fullstack solution quick starts. If the peer dependency `@abgov/nx-oc` is found, then OpenShift yml files are also included in the quickstarts. Application stack peer dependencies are required for the associated ADSP application type; for example, `@nx/angular` is required for the angular-app, and [@nx-dotnet/core](https://github.com/nx-dotnet/nx-dotnet) is required for dotnet-service.
6 |
7 | ## TLDR
8 |
9 | 1. Create your Nx workspace using `npx create-nx-workspace my-workspace`
10 | 2. Install plugin: `npm i -D @abgov/nx-adsp`
11 | 3. Generate a quick start `npx g @abgov/nx-adsp:express-service my-app`
12 |
13 | # Dev Features
14 |
15 | Stuff inside [] needs to be replaced with your own names
16 |
17 | ## To add a plugin to @abgov/nx-adsp
18 |
19 | nx g @nx/plugin:plugin [pluginName] --importPath .
20 | move the code generated into packages/ns-adsp and make changes in the plugin directory you've just generated
21 |
22 | ## To test the plugin locally
23 |
24 | 1. Generate a temp folder with a local nx-adsp using `nx run nx-adsp-e2e:e2e`
25 | 2. Generate a new project somewhere with `npx create-nx-workspace`, following the prompts
26 |
27 | 3. Inside the new workspace,
28 | i) run
29 | npm i -D [location-of-nx-tools]/dist/packages/nx-adsp //to update package.json
30 | npm i -D @nx/angular //(this assumes you are building an angular plugin)
31 |
32 | ii) generate the plugin - tenantRealm is the realm UUID used to generate a login feature that will log into that particular tenant (eg '2a9a2c30-a094-4097-9247-8d41b39cb80e')
33 | `npx nx g @abgov/nx-adsp:[pluginName] my-ang-app --tenant tenantRealm`
34 | iii) run `npm install`
35 | iv) serve the plugin using `nx serve [pluginName]
36 |
--------------------------------------------------------------------------------
/packages/nx-oc/project.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "nx-oc",
3 | "$schema": "../../node_modules/nx/schemas/project-schema.json",
4 | "sourceRoot": "packages/nx-oc/src",
5 | "projectType": "library",
6 | "targets": {
7 | "lint": {
8 | "executor": "@nx/eslint:lint",
9 | "options": {
10 | "lintFilePatterns": [
11 | "packages/nx-oc/**/*.ts",
12 | "packages/nx-oc/package.json"
13 | ]
14 | },
15 | "outputs": ["{options.outputFile}"]
16 | },
17 | "test": {
18 | "executor": "@nx/jest:jest",
19 | "outputs": ["{workspaceRoot}/coverage/packages/nx-oc"],
20 | "options": {
21 | "jestConfig": "packages/nx-oc/jest.config.ts",
22 | "passWithNoTests": true
23 | }
24 | },
25 | "build": {
26 | "executor": "@nx/js:tsc",
27 | "outputs": ["{options.outputPath}"],
28 | "options": {
29 | "outputPath": "dist/packages/nx-oc",
30 | "tsConfig": "packages/nx-oc/tsconfig.lib.json",
31 | "packageJson": "packages/nx-oc/package.json",
32 | "main": "packages/nx-oc/src/index.ts",
33 | "assets": [
34 | "packages/nx-oc/*.md",
35 | {
36 | "input": "./packages/nx-oc/src",
37 | "glob": "**/*.!(ts)",
38 | "output": "./src"
39 | },
40 | {
41 | "input": "./packages/nx-oc",
42 | "glob": "generators.json",
43 | "output": "."
44 | },
45 | {
46 | "input": "./packages/nx-oc",
47 | "glob": "executors.json",
48 | "output": "."
49 | }
50 | ]
51 | }
52 | },
53 | "release": {
54 | "executor": "nx:run-commands",
55 | "options": {
56 | "command": "npx semantic-release -e ./packages/nx-oc/.releaserc.json"
57 | }
58 | }
59 | },
60 | "tags": []
61 | }
62 |
--------------------------------------------------------------------------------
/packages/nx-adsp/project.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "nx-adsp",
3 | "$schema": "../../node_modules/nx/schemas/project-schema.json",
4 | "sourceRoot": "packages/nx-adsp/src",
5 | "projectType": "library",
6 | "targets": {
7 | "lint": {
8 | "executor": "@nx/eslint:lint",
9 | "options": {
10 | "lintFilePatterns": [
11 | "packages/nx-adsp/**/*.ts",
12 | "packages/nx-adsp/package.json"
13 | ]
14 | },
15 | "outputs": ["{options.outputFile}"]
16 | },
17 | "test": {
18 | "executor": "@nx/jest:jest",
19 | "outputs": ["{workspaceRoot}/coverage/packages/nx-adsp"],
20 | "options": {
21 | "jestConfig": "packages/nx-adsp/jest.config.ts",
22 | "passWithNoTests": true
23 | }
24 | },
25 | "build": {
26 | "executor": "@nx/js:tsc",
27 | "outputs": ["{options.outputPath}"],
28 | "options": {
29 | "outputPath": "dist/packages/nx-adsp",
30 | "tsConfig": "packages/nx-adsp/tsconfig.lib.json",
31 | "packageJson": "packages/nx-adsp/package.json",
32 | "main": "packages/nx-adsp/src/index.ts",
33 | "assets": [
34 | "packages/nx-adsp/*.md",
35 | {
36 | "input": "./packages/nx-adsp/src",
37 | "glob": "**/*.!(ts)",
38 | "output": "./src"
39 | },
40 | {
41 | "input": "./packages/nx-adsp",
42 | "glob": "generators.json",
43 | "output": "."
44 | },
45 | {
46 | "input": "./packages/nx-adsp",
47 | "glob": "executors.json",
48 | "output": "."
49 | }
50 | ]
51 | }
52 | },
53 | "release": {
54 | "executor": "nx:run-commands",
55 | "options": {
56 | "command": "npx semantic-release -e ./packages/nx-adsp/.releaserc.json"
57 | }
58 | }
59 | },
60 | "tags": []
61 | }
62 |
--------------------------------------------------------------------------------
/packages/nx-release/src/release-plugin/wrap-plugin.ts:
--------------------------------------------------------------------------------
1 | import { workspaceRoot } from '@nx/devkit';
2 | import type {
3 | PluginConfig,
4 | PluginFunction,
5 | } from '@semantic-release/semantic-release';
6 | import type { BaseContext } from 'semantic-release';
7 | import { getPathCommitHashes } from './git-utils.js';
8 | import { getProjectChangePaths } from './nx-util.js';
9 |
10 | export interface WrappedPluginConfig extends PluginConfig {
11 | project: string;
12 | }
13 |
14 | export const wrapPlugin =
15 | (plugin: PluginFunction) =>
16 | async ({ project, ...pluginConfig }: WrappedPluginConfig, context: T) => {
17 | const { logger } = context;
18 | const commits = context['commits'];
19 | let filteredCommits = commits;
20 |
21 | if (!project) {
22 | logger.log(
23 | "Skipping filtering of commits; no 'project' in configuration..."
24 | );
25 | } else {
26 | logger.log(`Filtering commits to those affecting ${project}...`);
27 |
28 | const paths = await getProjectChangePaths(workspaceRoot, project);
29 | logger.log(`Resolved to paths: ${paths.join(', ')}...`);
30 |
31 | const from = context['lastRelease']?.gitHead;
32 | const to = context['nextRelease']?.gitHead;
33 |
34 | const hashes = await getPathCommitHashes(
35 | workspaceRoot,
36 | project,
37 | paths,
38 | from,
39 | to
40 | );
41 |
42 | filteredCommits = commits.filter((commit) => {
43 | const match = hashes.includes(commit.commit.long);
44 | if (match) {
45 | logger.log(
46 | `Including commit ${commit.commit.short}: ${commit.message}`
47 | );
48 | }
49 | return match;
50 | });
51 | }
52 |
53 | return await plugin(pluginConfig, {
54 | ...context,
55 | commits: [...filteredCommits] as const,
56 | });
57 | };
58 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/angular-app/files/src/app/app.component.spec.ts__tmpl__:
--------------------------------------------------------------------------------
1 | import { TestBed, getTestBed } from '@angular/core/testing';
2 | import { AppComponent } from './app.component';
3 | import { AngularComponentsModule } from '@abgov/angular-components';
4 | import { RouterTestingModule } from '@angular/router/testing';
5 | import {
6 | BrowserDynamicTestingModule,
7 | platformBrowserDynamicTesting
8 | } from "@angular/platform-browser-dynamic/testing";
9 |
10 |
11 | describe('AppComponent', () => {
12 | beforeAll( ()=> {
13 | TestBed.initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());
14 | });
15 | beforeEach(async () => {
16 | let envData = {"production":false,"access":{"url":"https://testurl.com","realm":"123","client_id":"urn:ads:platform:tenant-admin-app"},"tenantApi":{"host":"http://localhost:3333","endpoints":{"tenantNameByRealm":"/api/tenant/v1/realm"}}}
17 |
18 | localStorage.setItem('envData', JSON.stringify(envData));
19 | await TestBed.configureTestingModule({
20 | declarations: [AppComponent],
21 | imports: [AngularComponentsModule, RouterTestingModule],
22 | }).compileComponents();
23 | });
24 |
25 | it('should create the app', () => {
26 | const fixture = TestBed.createComponent(AppComponent);
27 | const app = fixture.componentInstance;
28 | expect(app).toBeTruthy();
29 | });
30 |
31 | it(`should have as title '<%= projectName %>'`, () => {
32 | const fixture = TestBed.createComponent(AppComponent);
33 | const app = fixture.componentInstance;
34 | expect(app.title).toEqual('<%= projectName %>');
35 | });
36 |
37 | it('should render title', () => {
38 | const fixture = TestBed.createComponent(AppComponent);
39 | fixture.detectChanges();
40 | const compiled = fixture.nativeElement;
41 | expect(compiled.querySelector('h2').textContent).toContain(
42 | 'Welcome to <%= projectName %>!'
43 | );
44 | });
45 | });
46 |
--------------------------------------------------------------------------------
/packages/nx-release/README.md:
--------------------------------------------------------------------------------
1 | # About this project
2 | This is the Government of Alberta - Nx plugin for Semantic Release.
3 |
4 | The project contains both the Nx plugin generator for setting up a monorepo with semantic release
5 | configuration as well as a plugin for semantic release.
6 |
7 | ## Semantic release / monorepo
8 | There are multiple challenges with using semantic release in a monorepo:
9 | 1. Each release project needs distinct release tags.
10 | 2. Each project should be evaluated based on only commits related to it.
11 | 3. Interdependencies between projects need to be handled.
12 | 4. Interdependencies between publishable/releasable projects require coordination of releases.
13 | 5. Channel (next-major, next, latest) information is stored in a git note on a semantic-release ref and does not distinguished between tags (and consequently projects).
14 |
15 | For (1), (2), and (3) in part this project uses the approach from [semantic-release-monorepo](https://github.com/pmowrer/semantic-release-monorepo) along with Nx capabilities:
16 | - Each project uses a distinct `tagFormat`;
17 | - A custom plugin wraps default plugins for `analyzeCommits` and `generateNotes` and filters for only relevant commits;
18 | - Nx `dep-graph` is used to determine dependency paths that should also be included.
19 |
20 | (4) is not currently handled, but a solution leveraging Nx capabilities is the general direction. For example, Nx supports ordered execution of tasks based on 'affected'.
21 |
22 |
23 |
24 | **KNOWN ISSUE** (5) from above is not handled, and non-prerelease channel upgrades will result in only the first project being upgraded when release tags from multiple projects are on the same commit.
25 |
26 | In Semantic Release the channel upgrade is done separately from the next version analysis and there are no extension hooks to modify the behaviour. Prerelease channels with a distinct version format (e.g. 1.0.0-beta.x) are excluded from that process and appear to work.
27 |
--------------------------------------------------------------------------------
/e2e/nx-adsp-e2e/tests/nx-adsp.spec.ts:
--------------------------------------------------------------------------------
1 | import {
2 | checkFilesExist,
3 | ensureNxProject,
4 | runNxCommandAsync,
5 | uniq,
6 | } from '@nx/plugin/testing';
7 |
8 | describe('nx-adsp e2e', () => {
9 | beforeEach(() => ensureNxProject('@abgov/nx-adsp', 'dist/packages/nx-adsp'));
10 |
11 | describe('express service', () => {
12 | it('should create express-service', async (done) => {
13 | const plugin = uniq('express-service');
14 | const result = await runNxCommandAsync(
15 | `generate @abgov/nx-adsp:express-service ${plugin} test`
16 | );
17 | expect(() => checkFilesExist(`apps/${plugin}/src/main.ts`)).not.toThrow();
18 |
19 | done();
20 | }, 60000);
21 |
22 | describe('--tenant', () => {
23 | it('should create express-service', async (done) => {
24 | const plugin = uniq('express-service');
25 | const result = await runNxCommandAsync(
26 | `generate @abgov/nx-adsp:express-service ${plugin} --tenant test`
27 | );
28 | expect(() =>
29 | checkFilesExist(`apps/${plugin}/src/main.ts`)
30 | ).not.toThrow();
31 |
32 | done();
33 | }, 60000);
34 | });
35 | });
36 |
37 | describe('react app', () => {
38 | it('should create react-app', async (done) => {
39 | const plugin = uniq('react-app');
40 | const result = await runNxCommandAsync(
41 | `generate @abgov/nx-adsp:react-app ${plugin} test`
42 | );
43 | expect(
44 | () => {} // checkFilesExist(`apps/${plugin}/src/main.ts`)
45 | ).not.toThrow();
46 |
47 | done();
48 | }, 60000);
49 | });
50 |
51 | it('should create angular app', async (done) => {
52 | const plugin = uniq('angular-app');
53 | await runNxCommandAsync(
54 | `generate @abgov/nx-adsp:angular-app ${plugin} test`
55 | );
56 |
57 | const result = await runNxCommandAsync(`build ${plugin}`);
58 | expect(result.stdout).toContain('Executor ran');
59 |
60 | done();
61 | }, 60000);
62 | });
63 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/dotnet-service/dotnet-service.spec.ts:
--------------------------------------------------------------------------------
1 | import { addDependenciesToPackageJson } from '@nx/devkit';
2 | import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
3 | import appGenerator from '@nx-dotnet/core/src/generators/app/generator';
4 | import refGenerator from '@nx-dotnet/core/src/generators/nuget-reference/generator';
5 |
6 | import * as utils from '@abgov/nx-oc';
7 | import { environments } from '@abgov/nx-oc';
8 | import { Schema } from './schema';
9 | import generator from './dotnet-service';
10 |
11 | jest.mock('@nx-dotnet/core/src/generators/app/generator');
12 | jest.mock('@nx-dotnet/core/src/generators/nuget-reference/generator');
13 |
14 | const appGeneratorMock = appGenerator as jest.Mocked;
15 | const refGeneratorMock = refGenerator as jest.Mocked;
16 |
17 | jest.mock('@abgov/nx-oc', () => ({
18 | ...jest.requireActual('@abgov/nx-oc'),
19 | getAdspConfiguration: jest.fn(),
20 | deploymentGenerator: jest.fn(),
21 | }));
22 | const utilsMock = utils as jest.Mocked;
23 | utilsMock.getAdspConfiguration.mockResolvedValue({
24 | tenant: 'test',
25 | tenantRealm: 'test',
26 | accessServiceUrl: environments.test.accessServiceUrl,
27 | directoryServiceUrl: environments.test.directoryServiceUrl,
28 | });
29 | utilsMock.deploymentGenerator.mockResolvedValue();
30 |
31 | describe('Dotnet Service Generator', () => {
32 | const options: Schema = {
33 | name: 'test',
34 | env: 'dev',
35 | };
36 |
37 | it('can run', async () => {
38 | const host = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
39 | addDependenciesToPackageJson(
40 | host,
41 | {},
42 | {
43 | '@nx-dotnet/core': '^1.16.0',
44 | }
45 | );
46 | await generator(host, options);
47 | expect(appGeneratorMock).toHaveBeenCalled();
48 | expect(refGeneratorMock).toHaveBeenCalled();
49 | expect(utils.deploymentGenerator).toHaveBeenCalled();
50 | host.exists('apps/test/Program.cs');
51 | });
52 | });
53 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/angular-app/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://json-schema.org/schema",
3 | "id": "AngularApp",
4 | "title": "",
5 | "type": "object",
6 | "properties": {
7 | "name": {
8 | "type": "string",
9 | "description": "Name of the application.",
10 | "$default": {
11 | "$source": "argv",
12 | "index": 0
13 | },
14 | "x-prompt": "What name would you like to use?"
15 | },
16 | "env": {
17 | "type": "string",
18 | "description": "Environment to target.",
19 | "$default": {
20 | "$source": "argv",
21 | "index": 1
22 | },
23 | "alias": "e",
24 | "x-prompt": {
25 | "message": "Which ADSP environment do you want to target?",
26 | "type": "list",
27 | "items": [
28 | "dev",
29 | "test",
30 | "prod"
31 | ]
32 | }
33 | },
34 | "accessToken": {
35 | "type": "string",
36 | "description": "Access token for retrieving configuration from ADSP APIs.",
37 | "alias": "at"
38 | },
39 | "proxy": {
40 | "oneOf": [
41 | {
42 | "type": "array",
43 | "items": {
44 | "type": "object",
45 | "properties": {
46 | "location": {
47 | "type": "string"
48 | },
49 | "proxyPass": {
50 | "type": "string"
51 | }
52 | },
53 | "required": [
54 | "location",
55 | "proxyPass"
56 | ]
57 | }
58 | },
59 | {
60 | "type": "object",
61 | "properties": {
62 | "location": {
63 | "type": "string"
64 | },
65 | "proxyPass": {
66 | "type": "string"
67 | }
68 | },
69 | "required": [
70 | "location",
71 | "proxyPass"
72 | ]
73 | }
74 | ]
75 | }
76 | },
77 | "required": [
78 | "name",
79 | "env"
80 | ]
81 | }
82 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/react-app/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://json-schema.org/schema",
3 | "id": "NxAdspReactApp",
4 | "title": "",
5 | "type": "object",
6 | "properties": {
7 | "name": {
8 | "type": "string",
9 | "description": "Name of the application.",
10 | "$default": {
11 | "$source": "argv",
12 | "index": 0
13 | },
14 | "x-prompt": "What name would you like to use?"
15 | },
16 | "env": {
17 | "type": "string",
18 | "description": "Environment to target.",
19 | "$default": {
20 | "$source": "argv",
21 | "index": 1
22 | },
23 | "alias": "e",
24 | "x-prompt": {
25 | "message": "Which ADSP environment do you want to target?",
26 | "type": "list",
27 | "items": [
28 | "dev",
29 | "test",
30 | "prod"
31 | ]
32 | }
33 | },
34 | "accessToken": {
35 | "type": "string",
36 | "description": "Access token for retrieving configuration from ADSP APIs.",
37 | "alias": "at"
38 | },
39 | "proxy": {
40 | "oneOf": [
41 | {
42 | "type": "array",
43 | "items": {
44 | "type": "object",
45 | "properties": {
46 | "location": {
47 | "type": "string"
48 | },
49 | "proxyPass": {
50 | "type": "string"
51 | }
52 | },
53 | "required": [
54 | "location",
55 | "proxyPass"
56 | ]
57 | }
58 | },
59 | {
60 | "type": "object",
61 | "properties": {
62 | "location": {
63 | "type": "string"
64 | },
65 | "proxyPass": {
66 | "type": "string"
67 | }
68 | },
69 | "required": [
70 | "location",
71 | "proxyPass"
72 | ]
73 | }
74 | ]
75 | }
76 | },
77 | "required": [
78 | "name",
79 | "env"
80 | ]
81 | }
82 |
--------------------------------------------------------------------------------
/packages/nx-release/project.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "nx-release",
3 | "$schema": "../../node_modules/nx/schemas/project-schema.json",
4 | "sourceRoot": "packages/nx-release/src",
5 | "projectType": "library",
6 | "targets": {
7 | "lint": {
8 | "executor": "@nx/eslint:lint",
9 | "options": {
10 | "lintFilePatterns": [
11 | "packages/nx-release/**/*.ts",
12 | "packages/nx-release/package.json"
13 | ]
14 | },
15 | "outputs": ["{options.outputFile}"]
16 | },
17 | "test": {
18 | "executor": "@nx/jest:jest",
19 | "outputs": ["{workspaceRoot}/coverage/packages/nx-release"],
20 | "options": {
21 | "jestConfig": "packages/nx-release/jest.config.ts",
22 | "passWithNoTests": true
23 | }
24 | },
25 | "build": {
26 | "executor": "@nx/js:tsc",
27 | "outputs": ["{options.outputPath}"],
28 | "options": {
29 | "outputPath": "dist/packages/nx-release",
30 | "tsConfig": "packages/nx-release/tsconfig.lib.json",
31 | "packageJson": "packages/nx-release/package.json",
32 | "main": "packages/nx-release/src/index.ts",
33 | "assets": [
34 | "packages/nx-release/*.md",
35 | {
36 | "input": "./packages/nx-release/src",
37 | "glob": "**/*.!(ts)",
38 | "output": "./src"
39 | },
40 | {
41 | "input": "./packages/nx-release/src",
42 | "glob": "**/.*",
43 | "output": "./src"
44 | },
45 | {
46 | "input": "./packages/nx-release",
47 | "glob": "generators.json",
48 | "output": "."
49 | },
50 | {
51 | "input": "./packages/nx-release",
52 | "glob": "executors.json",
53 | "output": "."
54 | }
55 | ]
56 | }
57 | },
58 | "release": {
59 | "executor": "nx:run-commands",
60 | "options": {
61 | "command": "npx semantic-release -e ./packages/nx-release/.releaserc.json"
62 | }
63 | }
64 | },
65 | "tags": []
66 | }
67 |
--------------------------------------------------------------------------------
/packages/nx-release/src/generators/lib/lib.ts:
--------------------------------------------------------------------------------
1 | import {
2 | addDependenciesToPackageJson,
3 | formatFiles,
4 | generateFiles,
5 | getWorkspaceLayout,
6 | installPackagesTask,
7 | offsetFromRoot,
8 | readProjectConfiguration,
9 | Tree,
10 | updateProjectConfiguration,
11 | } from '@nx/devkit';
12 | import * as path from 'path';
13 | import { NormalizedSchema, Schema } from './schema';
14 |
15 | function addFiles(host: Tree, options: NormalizedSchema) {
16 | const templateOptions = {
17 | ...options,
18 | offsetFromRoot: offsetFromRoot(options.projectRoot),
19 | tmpl: '',
20 | };
21 |
22 | if (!host.exists('.releaserc.json')) {
23 | generateFiles(
24 | host,
25 | path.join(__dirname, 'root-files'),
26 | '.',
27 | templateOptions
28 | );
29 | }
30 |
31 | generateFiles(
32 | host,
33 | path.join(__dirname, 'files'),
34 | options.projectRoot,
35 | templateOptions
36 | );
37 | }
38 |
39 | export default async function (host: Tree, options: Schema) {
40 | const config = readProjectConfiguration(host, options.project);
41 | const { build } = config.targets;
42 | if (config.projectType !== 'library' || !build) {
43 | console.log('This generator can only be run against buildable libraries.');
44 | } else {
45 | addDependenciesToPackageJson(
46 | host,
47 | {},
48 | {
49 | 'semantic-release': '^23.0.0',
50 | }
51 | );
52 |
53 | config.targets.release = {
54 | executor: 'nx:run-commands',
55 | options: {
56 | command: `npx semantic-release -e ./${config.root}/.releaserc.json`,
57 | },
58 | };
59 |
60 | updateProjectConfiguration(host, options.project, config);
61 |
62 | const { libsDir } = getWorkspaceLayout(host);
63 | const normalizedOptions = {
64 | ...options,
65 | projectRoot: config.root,
66 | projectDist:
67 | build.options.outputPath || `dist/${libsDir}/${options.project}`,
68 | };
69 |
70 | addFiles(host, normalizedOptions);
71 | await formatFiles(host);
72 |
73 | return () => {
74 | installPackagesTask(host);
75 | };
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/angular-app/files/src/app/app.component.html__tmpl__:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
10 |
11 | Welcome to {{ title }}!
12 |
13 | Don't panic. Start editing the project to build your digital service.
14 |
15 | A few things you might want to do next:
16 |
17 | - Create the 'my-app' client in your realm to let users sign in
18 | -
19 | Make requests to the backend API by either updating nginx.conf or
20 | enabling CORS on the API.
21 |
22 | - Add requests to public API resources:
23 | - Add requests to private API resources:
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 | Sign Out
32 |
33 |
34 |
35 |
36 | Sign In
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
58 |
59 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/angular-app/files/src/app/protected/protected.component.spec.ts__tmpl__:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed, waitForAsync, inject } from '@angular/core/testing';
2 | import { ProtectedComponent } from './protected.component';
3 | import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
4 | import TenantService from '../tenant.service';
5 | import {
6 | BrowserDynamicTestingModule,
7 | platformBrowserDynamicTesting
8 | } from "@angular/platform-browser-dynamic/testing";
9 |
10 | describe('ProtectedComponent', () => {
11 | let fixture: ComponentFixture;
12 | let httpTestingController: HttpTestingController;
13 | let envData = {"production":false,"access":{"url":"https://testurl.com","realm":"123","client_id":"urn:ads:platform:tenant-admin-app"},"tenantApi":{"host":"http://localhost:3333","endpoints":{"tenantNameByRealm":"/api/tenant/v1/realm"}}}
14 |
15 | localStorage.setItem('envData', JSON.stringify(envData));
16 | beforeAll( ()=> {
17 | TestBed.initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());
18 | });
19 | beforeEach(
20 | waitForAsync(() => {
21 | TestBed.configureTestingModule({
22 | declarations: [ProtectedComponent],
23 | providers: [ProtectedComponent, TenantService],
24 | imports: [HttpClientTestingModule],
25 | }).compileComponents();
26 |
27 | httpTestingController = TestBed.inject(HttpTestingController);
28 | })
29 | );
30 |
31 | beforeEach(() => {
32 | fixture = TestBed.createComponent(ProtectedComponent);
33 | fixture.detectChanges();
34 | });
35 |
36 | afterEach(() => {
37 | httpTestingController.verify();
38 | });
39 |
40 | it('should create', (inject([TenantService, HttpTestingController],
41 | () => {
42 | const mockTenant = { status: 200, statusText: 'OK'}
43 | const data = { name: 'Child Services' }
44 | const req = httpTestingController.expectOne(
45 | 'http://localhost:3333/api/tenant/v1/realm/123'
46 | )
47 |
48 | expect(req.request.method).toEqual('GET');
49 |
50 | req.flush(data, mockTenant);
51 | })));
52 | });
53 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/express-service/files/src/main.ts__tmpl__:
--------------------------------------------------------------------------------
1 | /**
2 | * This is not a production server yet!
3 | * This is only a minimal backend to get started.
4 | */
5 | import { AdspId, initializeService } from '@abgov/adsp-service-sdk';
6 | import express from 'express';
7 | import passport from 'passport';
8 | import { Strategy as AnonymousStrategy } from 'passport-anonymous';
9 |
10 | import { environment } from './environments/environment';
11 |
12 | async function initializeApp(): Promise {
13 | const app = express();
14 | app.use(passport.initialize());
15 |
16 | const serviceId = AdspId.parse(environment.CLIENT_ID);
17 | const { tenantStrategy } = await initializeService(
18 | {
19 | displayName: '<%= projectName %>',
20 | description: 'Put your service description here.',
21 | realm: environment.TENANT_REALM,
22 | serviceId,
23 | clientSecret: environment.CLIENT_SECRET,
24 | accessServiceUrl: new URL(environment.ACCESS_SERVICE_URL),
25 | directoryUrl: new URL(environment.DIRECTORY_SERVICE_URL),
26 | },
27 | { logLevel: environment.LOG_LEVEL }
28 | );
29 |
30 | passport.use('tenant', tenantStrategy);
31 | passport.use('anonymous', new AnonymousStrategy());
32 |
33 | app.use(passport.authenticate(['tenant', 'anonymous'], { session: false }));
34 |
35 | app.get('/<%= projectName %>/v1/public', (_req, res) => {
36 | res.send({ message: `Welcome to public API resource!` });
37 | });
38 |
39 | app.get(
40 | '/<%= projectName %>/v1/private',
41 | (req, res, next) => {
42 | if (!req.user) {
43 | res.sendStatus(401);
44 | } else {
45 | next();
46 | }
47 | },
48 | (req, res) => {
49 | const user = req.user;
50 | res.send({ message: `Welcome to private API resource! ${user.name}` });
51 | }
52 | );
53 | return app;
54 | }
55 |
56 | initializeApp().then((app) => {
57 | const port = environment.port || 3333;
58 |
59 | const server = app.listen(port, () => {
60 | console.log(`Listening at http://localhost:${port}/<%= projectName %>/v1`);
61 | });
62 | server.on('error', console.error);
63 | });
64 |
--------------------------------------------------------------------------------
/packages/nx-adsp/generators.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://json-schema.org/schema",
3 | "name": "nx-adsp",
4 | "version": "0.0.1",
5 | "generators": {
6 | "express-service": {
7 | "factory": "./src/generators/express-service/express-service",
8 | "schema": "./src/generators/express-service/schema.json",
9 | "description": "Generator that creates an Node/Express based backend service."
10 | },
11 | "react-app": {
12 | "factory": "./src/generators/react-app/react-app",
13 | "schema": "./src/generators/react-app/schema.json",
14 | "description": "Generator that creates a React/Redux based frontend application."
15 | },
16 | "mern": {
17 | "factory": "./src/generators/mern/mern",
18 | "schema": "./src/generators/mern/schema.json",
19 | "description": "Generator that creates a MERN fullstack solution.",
20 | "hidden": true
21 | },
22 | "dotnet-service": {
23 | "factory": "./src/generators/dotnet-service/dotnet-service",
24 | "schema": "./src/generators/dotnet-service/schema.json",
25 | "description": "Generator that creates a ASP.NET Core backend service."
26 | },
27 | "react-dotnet": {
28 | "factory": "./src/generators/react-dotnet/react-dotnet",
29 | "schema": "./src/generators/react-dotnet/schema.json",
30 | "description": "Generator that creates a React-Dotnet fullstack solution."
31 | },
32 | "react-form": {
33 | "factory": "./src/generators/react-form/react-form",
34 | "schema": "./src/generators/react-form/schema.json",
35 | "description": "Generator that creates a React component based on an ADSP Form Definition."
36 | },
37 | "react-task-list": {
38 | "factory": "./src/generators/react-task-list/react-task-list",
39 | "schema": "./src/generators/react-task-list/schema.json",
40 | "description": "Generator that creates a React component based on an ADSP Task Queue."
41 | },
42 | "angular-app": {
43 | "factory": "./src/generators/angular-app/angular-app",
44 | "schema": "./src/generators/angular-app/schema.json",
45 | "description": "Generator that creates a Angular based frontend application."
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/react-app/files/src/app/config.slice.ts__tmpl__:
--------------------------------------------------------------------------------
1 | import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';
2 |
3 | export const CONFIG_FEATURE_KEY = 'config';
4 |
5 | export interface ConfigState {
6 | initialized: boolean;
7 | environment: Record;
8 | directory: Record;
9 | }
10 |
11 | export const initializeConfig = createAsyncThunk(
12 | 'config/initialize',
13 | async (environment?: Record) => {
14 | // Initialize state with environment and ADSP directory of services.
15 | const directoryUrl = environment?.directory?.['url'];
16 |
17 | let directory: Record = {};
18 | if (directoryUrl) {
19 | const platform: { urn: string; url: string }[] = await (
20 | await fetch(`${directoryUrl}/directory/v2/namespaces/platform/entries`)
21 | ).json();
22 | directory = platform.reduce(
23 | (result, entry) => ({ ...result, [entry.urn]: entry.url }),
24 | directory
25 | );
26 |
27 | try {
28 | const tenant: { urn: string; url: string }[] = await (
29 | await fetch(
30 | `${directoryUrl}/directory/v2/namespaces/<%= tenant %>/entries`
31 | )
32 | ).json();
33 |
34 | directory = tenant.reduce(
35 | (result, entry) => ({ ...result, [entry.urn]: entry.url }),
36 | directory
37 | );
38 | } catch (err) {
39 | // Tenant directory may not exist if no entries have been added.
40 | }
41 | }
42 |
43 | return { directory, environment };
44 | }
45 | );
46 |
47 | export const initialConfigState: ConfigState = {
48 | initialized: false,
49 | environment: {},
50 | directory: {},
51 | };
52 |
53 | const configSlice = createSlice({
54 | name: CONFIG_FEATURE_KEY,
55 | initialState: initialConfigState,
56 | reducers: {},
57 | extraReducers: (builder) => {
58 | builder.addCase(initializeConfig.fulfilled, (state, { payload }) => {
59 | state.environment = payload.environment;
60 | state.directory = payload.directory;
61 | state.initialized = true;
62 | });
63 | },
64 | });
65 |
66 | export const configReducer = configSlice.reducer;
67 |
--------------------------------------------------------------------------------
/packages/nx-oc/src/generators/pipeline/pipeline.ts:
--------------------------------------------------------------------------------
1 | import { formatFiles, generateFiles, Tree } from '@nx/devkit';
2 | import * as path from 'path';
3 | import { pipelineEnvs as envs } from '../../pipeline-envs';
4 | import { getGitRemoteUrl } from '../../utils/git-utils';
5 | import applyInfraGenerator from '../apply-infra/apply-infra';
6 | import { NormalizedSchema, Schema } from './schema';
7 |
8 | function normalizeOptions(host: Tree, options: Schema): NormalizedSchema {
9 | const ocEnvProjects = options.envs?.split(' ') || [options.infra];
10 |
11 | const envsProjectsSet = new Set(ocEnvProjects);
12 | if (envsProjectsSet.size !== ocEnvProjects.length) {
13 | throw new Error('Each environment must be a unique project.');
14 | } else if (ocEnvProjects.length > envs.length) {
15 | throw new Error(
16 | `Provided projects must correspond to ${envs.join(', ')} environments.`
17 | );
18 | }
19 |
20 | return {
21 | ...options,
22 | ocPipelineName: options.pipeline,
23 | ocInfraProject: options.infra,
24 | ocEnvProjects: ocEnvProjects,
25 | applyPipeline: !!options.apply,
26 | pipelineType: options.type === 'jenkins' ? 'jenkins' : 'actions',
27 | };
28 | }
29 |
30 | function addFiles(host: Tree, options: NormalizedSchema) {
31 | const templateOptions = {
32 | ...options,
33 | sourceRepositoryUrl: getGitRemoteUrl()?.trim(),
34 | envs,
35 | tmpl: '',
36 | };
37 |
38 | if (options.pipelineType === 'jenkins') {
39 | generateFiles(
40 | host,
41 | path.join(__dirname, 'jenkins'),
42 | `./.openshift`,
43 | templateOptions
44 | );
45 | } else if (options.pipelineType === 'actions') {
46 | generateFiles(
47 | host,
48 | path.join(__dirname, 'actions/openshift'),
49 | `./.openshift`,
50 | templateOptions
51 | );
52 | generateFiles(
53 | host,
54 | path.join(__dirname, 'actions/workflows'),
55 | `./.github/workflows`,
56 | templateOptions
57 | );
58 | }
59 | }
60 |
61 | export default async function (host: Tree, options: Schema) {
62 | const normalizedOptions = normalizeOptions(host, options);
63 |
64 | addFiles(host, normalizedOptions);
65 | await formatFiles(host);
66 |
67 | if (normalizedOptions.applyPipeline) {
68 | await applyInfraGenerator(host);
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/express-service/express-service.ts:
--------------------------------------------------------------------------------
1 | import { deploymentGenerator, getAdspConfiguration } from '@abgov/nx-oc';
2 | import {
3 | addDependenciesToPackageJson,
4 | formatFiles,
5 | generateFiles,
6 | getWorkspaceLayout,
7 | installPackagesTask,
8 | names,
9 | Tree,
10 | } from '@nx/devkit';
11 | import { Linter } from '@nx/eslint';
12 | import * as path from 'path';
13 | import { Schema, NormalizedSchema } from './schema';
14 |
15 | async function normalizeOptions(
16 | host: Tree,
17 | options: Schema
18 | ): Promise {
19 | const projectName = names(options.name).fileName;
20 | const projectRoot = `${getWorkspaceLayout(host).appsDir}/${projectName}`;
21 |
22 | const adsp = await getAdspConfiguration(host, options);
23 |
24 | return {
25 | ...options,
26 | projectName,
27 | projectRoot,
28 | adsp,
29 | };
30 | }
31 |
32 | function addFiles(host: Tree, options: NormalizedSchema) {
33 | const templateOptions = {
34 | ...options,
35 | ...options.adsp,
36 | tmpl: '',
37 | };
38 | generateFiles(
39 | host,
40 | path.join(__dirname, 'files'),
41 | options.projectRoot,
42 | templateOptions
43 | );
44 | }
45 |
46 | export default async function (host: Tree, options: Schema) {
47 | const normalizedOptions = await normalizeOptions(host, options);
48 |
49 | const { applicationGenerator: initExpress } = await import('@nx/express');
50 | await initExpress(host, {
51 | ...options,
52 | skipFormat: true,
53 | skipPackageJson: false,
54 | linter: Linter.EsLint,
55 | unitTestRunner: 'jest',
56 | js: false,
57 | directory: `apps/${options.name}`,
58 | });
59 |
60 | addDependenciesToPackageJson(
61 | host,
62 | {
63 | '@abgov/adsp-service-sdk': '^2.0.0',
64 | dotenv: '^16.0.0',
65 | passport: '^0.6.0',
66 | 'passport-anonymous': '^1.0.1',
67 | },
68 | {
69 | '@types/passport': '^1.0.9',
70 | '@types/passport-anonymous': '^1.0.3',
71 | }
72 | );
73 |
74 | addFiles(host, normalizedOptions);
75 | await formatFiles(host);
76 |
77 | await deploymentGenerator(host, {
78 | ...normalizedOptions,
79 | appType: 'node',
80 | project: normalizedOptions.projectName,
81 | });
82 |
83 | return () => {
84 | installPackagesTask(host);
85 | };
86 | }
87 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/dotnet-service/dotnet-service.ts:
--------------------------------------------------------------------------------
1 | import {
2 | deploymentGenerator,
3 | getAdspConfiguration,
4 | hasDependency,
5 | } from '@abgov/nx-oc';
6 | import { default as appGenerator } from '@nx-dotnet/core/src/generators/app/generator';
7 | import { default as refGenerator } from '@nx-dotnet/core/src/generators/nuget-reference/generator';
8 | import {
9 | generateFiles,
10 | getWorkspaceLayout,
11 | installPackagesTask,
12 | names,
13 | Tree,
14 | } from '@nx/devkit';
15 | import * as path from 'path';
16 | import { Schema, NormalizedSchema } from './schema';
17 |
18 | async function normalizeOptions(
19 | host: Tree,
20 | options: Schema
21 | ): Promise {
22 | const projectName = names(options.name).fileName;
23 | const projectRoot = `${getWorkspaceLayout(host).appsDir}/${projectName}`;
24 |
25 | const adsp = await getAdspConfiguration(host, options);
26 |
27 | return {
28 | ...options,
29 | projectName,
30 | projectRoot,
31 | adsp,
32 | };
33 | }
34 |
35 | function addFiles(host: Tree, options: NormalizedSchema) {
36 | const templateOptions = {
37 | ...options,
38 | ...options.adsp,
39 | tmpl: '',
40 | };
41 | generateFiles(
42 | host,
43 | path.join(__dirname, 'files'),
44 | options.projectRoot,
45 | templateOptions
46 | );
47 | }
48 |
49 | export default async function (host: Tree, options: Schema) {
50 | if (!hasDependency(host, '@nx-dotnet/core')) {
51 | throw new Error('nx-dotnet/core is required to generate dotnet service');
52 | }
53 |
54 | const normalizedOptions = await normalizeOptions(host, options);
55 |
56 | await appGenerator(host, {
57 | name: normalizedOptions.projectName,
58 | template: 'webapi',
59 | language: 'C#',
60 | testTemplate: 'none',
61 | solutionFile: false,
62 | skipSwaggerLib: true,
63 | pathScheme: 'nx',
64 | });
65 |
66 | await refGenerator(host, {
67 | allowVersionMismatch: false,
68 | project: normalizedOptions.projectName,
69 | packageName: 'Adsp.Sdk',
70 | version: '2.*',
71 | });
72 |
73 | addFiles(host, normalizedOptions);
74 |
75 | await deploymentGenerator(host, {
76 | ...normalizedOptions,
77 | appType: 'dotnet',
78 | project: normalizedOptions.projectName,
79 | });
80 |
81 | return async () => {
82 | installPackagesTask(host);
83 | };
84 | }
85 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/mern/mern.ts:
--------------------------------------------------------------------------------
1 | import {
2 | formatFiles,
3 | generateFiles,
4 | getWorkspaceLayout,
5 | installPackagesTask,
6 | names,
7 | offsetFromRoot,
8 | Tree,
9 | } from '@nx/devkit';
10 | import * as path from 'path';
11 | import { getAdspConfiguration } from '@abgov/nx-oc';
12 | import initExpressService from '../express-service/express-service';
13 | import initReactApp from '../react-app/react-app';
14 | import { Schema, NormalizedSchema } from './schema';
15 |
16 | async function normalizeOptions(
17 | host: Tree,
18 | options: Schema
19 | ): Promise {
20 | const name = names(options.name).fileName;
21 | const projectDirectory = name;
22 | const projectName = projectDirectory.replace(new RegExp('/', 'g'), '-');
23 | const projectRoot = `${getWorkspaceLayout(host).appsDir}/${projectDirectory}`;
24 | const openshiftDirectory = `.openshift/${projectDirectory}`;
25 |
26 | const adsp = await getAdspConfiguration(host, options);
27 |
28 | return {
29 | ...options,
30 | projectName,
31 | projectRoot,
32 | projectDirectory,
33 | openshiftDirectory,
34 | adsp,
35 | };
36 | }
37 |
38 | function addFiles(host: Tree, options: NormalizedSchema) {
39 | const templateOptions = {
40 | ...options,
41 | ...names(options.name),
42 | offsetFromRoot: offsetFromRoot(options.projectRoot),
43 | template: '',
44 | };
45 | generateFiles(
46 | host,
47 | path.join(__dirname, 'files'),
48 | options.projectRoot,
49 | templateOptions
50 | );
51 | generateFiles(
52 | host,
53 | path.join(__dirname, 'openshift'),
54 | `${options.openshiftDirectory}`,
55 | templateOptions
56 | );
57 | }
58 |
59 | export default async function(host: Tree, options: Schema) {
60 | const normalizedOptions = await normalizeOptions(host, options);
61 |
62 | await initExpressService(host, {
63 | ...normalizedOptions,
64 | name: `${options.name}-service`,
65 | });
66 |
67 | await initReactApp(host, {
68 | ...normalizedOptions,
69 | name: `${options.name}-app`,
70 | proxy: {
71 | location: '/api/',
72 | proxyPass: `http://${options.name}-service:3333/${options.name}-service/`,
73 | },
74 | });
75 |
76 | // Currently no files specific to MERN generator.
77 | // addFiles(host, normalizedOptions);
78 | await formatFiles(host);
79 |
80 | return () => {
81 | installPackagesTask(host);
82 | };
83 | }
84 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/react-task-list/react-task-list.spec.ts:
--------------------------------------------------------------------------------
1 | import * as utils from '@abgov/nx-oc';
2 | import { addProjectConfiguration } from '@nx/devkit';
3 | import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
4 | import axios from 'axios';
5 | import { prompt } from 'enquirer';
6 |
7 | import { Schema } from './schema';
8 | import generator from './react-task-list';
9 | import { QueueDefinition } from '../../utils/task';
10 |
11 | const queueDefinition: QueueDefinition = {
12 | namespace: 'test',
13 | name: 'run-test',
14 | assignerRoles: ['test-assigner'],
15 | workerRoles: ['test-worker'],
16 | };
17 |
18 | jest.mock('@abgov/nx-oc');
19 | const utilsMock = utils as jest.Mocked;
20 | utilsMock.getServiceUrls.mockResolvedValue({
21 | 'urn:ads:platform:tenant-service:v2': 'https://tenant-service/tenant/v2',
22 | 'urn:ads:platform:configuration-service': 'https://configuration-service',
23 | });
24 |
25 | utilsMock.realmLogin.mockResolvedValue('token');
26 | utilsMock.selectTenant.mockResolvedValue({ name: 'demo', realm: 'demo' });
27 |
28 | jest.mock('axios');
29 | const axiosMock = axios as jest.Mocked;
30 | axiosMock.get.mockResolvedValueOnce({
31 | data: { configuration: { queues: { 'test:run-test': queueDefinition } } },
32 | });
33 | axiosMock.patch.mockResolvedValueOnce({
34 | data: { 'test:run-test': queueDefinition },
35 | });
36 |
37 | jest.mock('enquirer', () => ({ prompt: jest.fn() }));
38 | const promptMock = prompt as jest.Mock;
39 | promptMock
40 | .mockResolvedValueOnce({ definition: 'test:run-test' })
41 | .mockResolvedValueOnce({ addStream: true });
42 |
43 | describe('React Task List Generator', () => {
44 | const options: Schema = {
45 | project: 'test',
46 | env: 'dev',
47 | };
48 |
49 | it('can run', async () => {
50 | const host = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
51 |
52 | addProjectConfiguration(host, 'test', {
53 | root: 'apps/test',
54 | projectType: 'application',
55 | targets: {
56 | build: {
57 | executor: '@nx/web:webpack',
58 | },
59 | },
60 | });
61 |
62 | await generator(host, options);
63 | expect(host.exists('apps/test/src/app/run-test/run-test.tsx')).toBeTruthy();
64 | expect(
65 | host.exists('apps/test/src/app/run-test/run-test.slice.ts')
66 | ).toBeTruthy();
67 | expect(
68 | host.exists('apps/test/src/app/run-test/run-test.module.css')
69 | ).toBeTruthy();
70 | }, 30000);
71 | });
72 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/dotnet-service/files/Program.cs__tmpl__:
--------------------------------------------------------------------------------
1 | using Adsp.Sdk;
2 | using Adsp.Sdk.Examples;
3 |
4 | var builder = WebApplication.CreateBuilder(args);
5 |
6 | // Add services to the container.
7 | builder.Services.AddLogging();
8 | builder.Services.AddControllers();
9 |
10 | // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
11 | builder.Services.AddEndpointsApiExplorer();
12 | builder.Services.AddSwaggerGen();
13 |
14 | // Initialization of ADSP SDK components...
15 | // Learn more about configuring ADSP SDK at https://govalta.github.io/adsp-monorepo/platform/platform-dotnet-sdk.html
16 | // 1. Bind configuration section or otherwise configure the options.
17 | var adspConfiguration = builder.Configuration.GetSection("Adsp");
18 | builder.Services.Configure(adspConfiguration);
19 |
20 | // 2. Add ADSP components to the service collection.
21 | builder.Services.AddAdspForService(options =>
22 | {
23 | // 3. Provide configuration of the service.
24 | // 3a. Configure basic service information.
25 | var serviceId = AdspId.Parse(adspConfiguration.GetValue("ClientId"));
26 | options.ServiceId = serviceId;
27 | options.DisplayName = "<%= projectName %>";
28 |
29 | // 3b. Register configuration definition.
30 | options.Configuration = new ConfigurationDefinition(
31 | "Configuration of the hello world sample service.",
32 | (tenant, core) => tenant
33 | );
34 | // Enable / disable socket.io based configuration invalidation.
35 | // Include `urn:ads:platform:push-service` audience in access token; e.g use an audience mapper on the associated client.
36 | options.EnableConfigurationInvalidation = false;
37 |
38 | // 3c. Register service roles.
39 | options.Roles = new[] {
40 | new ServiceRole {
41 | Role = ServiceRoles.HelloWorlder,
42 | Description = "Hello worlder role that allows user to post a message to the API."
43 | }
44 | };
45 |
46 | // 3d. Register domain events.
47 | options.Events = new[] {
48 | new DomainEventDefinition(
49 | HelloWorldEvent.EventName,
50 | "Signalled when a hello world message is posted to the API."
51 | )
52 | };
53 | });
54 |
55 | var app = builder.Build();
56 |
57 | app.UseSwagger();
58 | app.UseHttpsRedirection();
59 |
60 | // 4. Add ADSP middleware.
61 | app.UseAdsp();
62 | app.UseAuthorization();
63 | app.UseAdspMetadata(new AdspMetadataOptions
64 | {
65 | ApiPath = "WeatherForecast"
66 | });
67 |
68 | app.MapControllers();
69 |
70 | app.Run();
71 |
--------------------------------------------------------------------------------
/packages/nx-adsp/src/generators/react-app/files/src/main.tsx__tmpl__:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
4 | import { Provider } from 'react-redux';
5 | import {
6 | CallbackComponent,
7 | loadUser,
8 | OidcProvider,
9 | SignoutCallbackComponent,
10 | } from 'redux-oidc';
11 |
12 | import { environment } from './environments/environment';
13 | import { createUserManager } from './access';
14 | import App from './app/app';
15 | import { initializeConfig } from './app/config.slice';
16 | import { store } from './store';
17 |
18 | // Fetch configuration from web server; otherwise fallback to static environment.
19 | fetch('/config/config.json')
20 | .then(res => res.ok ?
21 | res.json() :
22 | environment
23 | )
24 | .then((env) => {
25 |
26 | store.dispatch(initializeConfig(env));
27 | const userManager = createUserManager(env.access);
28 | loadUser(store, userManager);
29 |
30 | ReactDOM.render(
31 |
32 |
33 |
34 |
35 |
36 |
39 | history.push('/')}
42 | errorCallback={() => history.push('/')}
43 | >
44 | signing in...
45 |
46 | }
47 | />
48 |
51 | history.push('/')}
54 | errorCallback={() => history.push('/')}
55 | >
56 | signing out...
57 |
58 | }
59 | />
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 | ,
68 | document.getElementById('root')
69 | );
70 | });
71 |
--------------------------------------------------------------------------------
/packages/nx-oc/src/generators/pipeline/jenkins/environment.infra.yml__tmpl__:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: List
3 | items:
4 | - apiVersion: v1
5 | kind: ImageStream
6 | metadata:
7 | name: jenkins-agent-node12
8 | namespace: <%= ocInfraProject %>
9 | annotations:
10 | slave-label: node12
11 | labels:
12 | role: jenkins-slave
13 | - apiVersion: v1
14 | kind: BuildConfig
15 | metadata:
16 | name: jenkins-agent-node12
17 | namespace: <%= ocInfraProject %>
18 | spec:
19 | output:
20 | to:
21 | kind: ImageStreamTag
22 | name: jenkins-agent-node12:latest
23 | runPolicy: Serial
24 | source:
25 | contextDir: agent-nodejs-12
26 | git:
27 | uri: 'https://github.com/openshift/jenkins.git'
28 | type: Git
29 | strategy:
30 | dockerStrategy: {}
31 | type: Docker
32 | triggers:
33 | - type: ConfigChange
34 | - apiVersion: v1
35 | kind: ImageStream
36 | metadata:
37 | name: jenkins-agent-node12-dotnet5
38 | namespace: <%= ocInfraProject %>
39 | annotations:
40 | slave-label: node12-dotnet5
41 | labels:
42 | role: jenkins-slave
43 | - apiVersion: v1
44 | kind: BuildConfig
45 | metadata:
46 | name: jenkins-agent-node12-dotnet5
47 | namespace: <%= ocInfraProject %>
48 | spec:
49 | output:
50 | to:
51 | kind: ImageStreamTag
52 | name: jenkins-agent-node12-dotnet5:latest
53 | runPolicy: Serial
54 | source:
55 | dockerfile: |
56 | FROM quay.io/openshift/origin-jenkins-agent-base:v4.0
57 |
58 | USER 0
59 |
60 | RUN rpm -Uvh https://packages.microsoft.com/config/centos/7/packages-microsoft-prod.rpm && \
61 | DISABLES="--disablerepo=rhel-server-extras --disablerepo=rhel-server --disablerepo=rhel-fast-datapath --disablerepo=rhel-server-optional --disablerepo=rhel-server-ose --disablerepo=rhel-server-rhscl" && \
62 | yum $DISABLES install -y --setopt=tsflags=nodocs --disableplugin=subscription-manager dotnet-sdk-5.0 && \
63 | yum clean all -y
64 |
65 | USER 1001
66 | type: Binary
67 | strategy:
68 | dockerStrategy:
69 | from:
70 | kind: ImageStreamTag
71 | name: jenkins-agent-node12:latest
72 | type: Docker
73 | - apiVersion: v1
74 | kind: BuildConfig
75 | metadata:
76 | name: <%= ocPipelineName %>
77 | namespace: <%= ocInfraProject %>
78 | spec:
79 | runPolicy: Serial
80 | source:
81 | git:
82 | uri: '<%= sourceRepositoryUrl %>'
83 | type: Git
84 | strategy:
85 | jenkinsPipelineStrategy:
86 | jenkinsfilePath: .openshift/Jenkinsfile
87 | type: JenkinsPipeline
88 |
--------------------------------------------------------------------------------
/packages/nx-release/src/release-plugin/wrap-plugin.spec.ts:
--------------------------------------------------------------------------------
1 | import type { Commit, VerifyReleaseContext } from 'semantic-release';
2 | import { mocked } from 'jest-mock';
3 | import { wrapPlugin } from './wrap-plugin';
4 | import { getProjectChangePaths } from './nx-util';
5 | import { getPathCommitHashes } from './git-utils';
6 |
7 | jest.mock('./nx-util');
8 | const mockedGetProjectChangePaths = mocked(getProjectChangePaths);
9 | jest.mock('./git-utils');
10 | const mockedGetPathCommitHashes = mocked(getPathCommitHashes);
11 |
12 | describe('wrapPlugin', () => {
13 | beforeEach(() => {
14 | mockedGetProjectChangePaths.mockReset();
15 | mockedGetPathCommitHashes.mockReset();
16 | });
17 |
18 | it('can wrap plugin function', () => {
19 | const wrapped = wrapPlugin(jest.fn());
20 | expect(wrapped).toBeTruthy();
21 | expect(typeof wrapped).toBe('function');
22 | });
23 |
24 | it('can filter commits', async () => {
25 | const plugin = jest.fn();
26 | plugin.mockReturnValue('result');
27 | jest.mock('./git-utils');
28 | const wrapped = wrapPlugin(plugin);
29 |
30 | mockedGetProjectChangePaths.mockReturnValue(Promise.resolve(['test1']));
31 |
32 | mockedGetPathCommitHashes.mockReturnValue(Promise.resolve(['test1']));
33 |
34 | const logger = {
35 | log: jest.fn(),
36 | error: jest.fn(),
37 | };
38 |
39 | const result = await wrapped(
40 | { project: 'test', config: 'config' },
41 | {
42 | commits: [
43 | { commit: { long: 'test1', short: 'test1' } } as Commit,
44 | { commit: { long: 'test2', short: 'test2' } } as Commit,
45 | ],
46 | logger,
47 | env: {},
48 | cwd: '',
49 | stderr: null,
50 | stdout: null,
51 | } as unknown as VerifyReleaseContext
52 | );
53 |
54 | expect(result).toBe('result');
55 | expect(plugin.mock.calls.length).toBe(1);
56 | expect(plugin.mock.calls[0][0].config).toBe('config');
57 | expect(plugin.mock.calls[0][1].commits.length).toBe(1);
58 | expect(plugin.mock.calls[0][1].commits[0].commit.long).toBe('test1');
59 | });
60 |
61 | it('can skip filtering if no project configured', async () => {
62 | const plugin = jest.fn();
63 | plugin.mockReturnValue('result');
64 | const wrapped = wrapPlugin(plugin);
65 |
66 | const logger = {
67 | log: jest.fn(),
68 | error: jest.fn(),
69 | };
70 |
71 | const result = await wrapped(
72 | { project: null, config: 'config' },
73 | {
74 | commits: [
75 | { commit: { long: 'test1', short: 'test1' } } as Commit,
76 | { commit: { long: 'test2', short: 'test2' } } as Commit,
77 | ],
78 | logger,
79 | env: {},
80 | cwd: '',
81 | } as unknown as VerifyReleaseContext
82 | );
83 |
84 | expect(result).toBe('result');
85 | expect(plugin.mock.calls.length).toBe(1);
86 | expect(plugin.mock.calls[0][1].commits.length).toBe(2);
87 | });
88 | });
89 |
--------------------------------------------------------------------------------
/.github/workflows/codeql-analysis.yml:
--------------------------------------------------------------------------------
1 | # For most projects, this workflow file will not need changing; you simply need
2 | # to commit it to your repository.
3 | #
4 | # You may wish to alter this file to override the set of languages analyzed,
5 | # or to provide custom queries or build logic.
6 | #
7 | # ******** NOTE ********
8 | # We have attempted to detect the languages in your repository. Please check
9 | # the `language` matrix defined below to confirm you have the correct set of
10 | # supported CodeQL languages.
11 | #
12 | name: "CodeQL"
13 |
14 | on:
15 | push:
16 | branches: [main, beta]
17 | pull_request:
18 | # The branches below must be a subset of the branches above
19 | branches: [main, beta]
20 |
21 | jobs:
22 | analyze:
23 | name: Analyze
24 | runs-on: ubuntu-latest
25 | permissions:
26 | actions: read
27 | contents: read
28 | security-events: write
29 |
30 | strategy:
31 | fail-fast: false
32 | matrix:
33 | language: ["javascript", "typescript"]
34 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
35 | # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
36 |
37 | steps:
38 | - name: Checkout repository
39 | uses: actions/checkout@v3
40 |
41 | # Initializes the CodeQL tools for scanning.
42 | - name: Initialize CodeQL
43 | uses: github/codeql-action/init@v2
44 | with:
45 | languages: ${{ matrix.language }}
46 | # If you wish to specify custom queries, you can do so here or in a config file.
47 | # By default, queries listed here will override any specified in a config file.
48 | # Prefix the list here with "+" to use these queries and those in the config file.
49 |
50 | # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
51 | # queries: security-extended,security-and-quality
52 |
53 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
54 | # If this step fails, then you should remove it and run the build manually (see below)
55 | - name: Autobuild
56 | uses: github/codeql-action/autobuild@v2
57 |
58 | # ℹ️ Command-line programs to run using the OS shell.
59 | # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
60 |
61 | # If the Autobuild fails above, remove it and uncomment the following three lines.
62 | # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
63 |
64 | # - run: |
65 | # echo "Run, Build Application using script"
66 | # ./location_of_script_within_repo/buildscript.sh
67 |
68 | - name: Perform CodeQL Analysis
69 | uses: github/codeql-action/analyze@v2
70 |
--------------------------------------------------------------------------------
/packages/nx-oc/src/generators/pipeline/pipeline.spec.ts:
--------------------------------------------------------------------------------
1 | import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
2 | import { Schema } from './schema';
3 | import generator from './pipeline';
4 |
5 | describe('Pipeline Generator', () => {
6 | describe('Jenkins', () => {
7 | const options: Schema = {
8 | pipeline: 'test',
9 | type: 'jenkins',
10 | infra: 'test-infra',
11 | envs: 'test-dev',
12 | };
13 |
14 | it('can run', async () => {
15 | const host = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
16 | await generator(host, options);
17 | expect(host.exists('.openshift/Jenkinsfile')).toBeTruthy();
18 | expect(host.exists('.openshift/environment.infra.yml')).toBeTruthy();
19 | expect(host.exists('.openshift/environments.yml')).toBeTruthy();
20 | });
21 |
22 | it('can generate multiple envs', async () => {
23 | const host = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
24 | await generator(host, { ...options, envs: 'test-dev test-test' });
25 | expect(host.exists('.openshift/environments.yml')).toBeTruthy();
26 |
27 | const envs = host.read('.openshift/environments.yml').toString();
28 | expect(envs).toContain('test-dev');
29 | expect(envs).toContain('test-test');
30 | });
31 |
32 | it('can fail for duplicate env project', async () => {
33 | const host = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
34 | await expect(
35 | generator(host, { ...options, envs: 'test-dev test-dev' })
36 | ).rejects.toThrow('Each environment must be a unique project.');
37 | });
38 | });
39 |
40 | describe('GitHub Actions', () => {
41 | const options: Schema = {
42 | pipeline: 'test',
43 | type: 'actions',
44 | infra: 'test-infra',
45 | envs: 'test-dev',
46 | };
47 |
48 | it('can run', async () => {
49 | const host = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
50 | await generator(host, options);
51 | expect(host.exists('.github/workflows/pipeline.yml')).toBeTruthy();
52 | expect(host.exists('.openshift/environment.infra.yml')).toBeTruthy();
53 | expect(host.exists('.openshift/environments.yml')).toBeTruthy();
54 | });
55 |
56 | it('can generate multiple envs', async () => {
57 | const host = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
58 | await generator(host, { ...options, envs: 'test-dev test-test' });
59 | expect(host.exists('.openshift/environments.yml')).toBeTruthy();
60 |
61 | const envs = host.read('.openshift/environments.yml').toString();
62 | expect(envs).toContain('test-dev');
63 | expect(envs).toContain('test-test');
64 | });
65 |
66 | it('can fail for duplicate env project', async () => {
67 | const host = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
68 | await expect(
69 | generator(host, { ...options, envs: 'test-dev test-dev' })
70 | ).rejects.toThrow('Each environment must be a unique project.');
71 | });
72 | });
73 | });
74 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@abgov/nx-tools",
3 | "version": "0.0.0",
4 | "license": "Apache-2.0",
5 | "scripts": {
6 | "nx": "nx",
7 | "start": "nx serve",
8 | "build": "nx build",
9 | "test": "nx test",
10 | "lint": "nx workspace-lint && nx lint",
11 | "e2e": "nx e2e",
12 | "affected:apps": "nx affected:apps",
13 | "affected:libs": "nx affected:libs",
14 | "affected:build": "nx affected:build",
15 | "affected:e2e": "nx affected:e2e",
16 | "affected:test": "nx affected:test",
17 | "affected:lint": "nx affected:lint",
18 | "affected:dep-graph": "nx affected:dep-graph",
19 | "affected": "nx affected",
20 | "format": "nx format:write",
21 | "format:write": "nx format:write",
22 | "format:check": "nx format:check",
23 | "update": "nx migrate latest",
24 | "workspace-generator": "nx workspace-generator",
25 | "dep-graph": "nx dep-graph",
26 | "help": "nx help"
27 | },
28 | "private": true,
29 | "dependencies": {
30 | "@angular/core": "19.1.6",
31 | "@nx/devkit": "20.4.2",
32 | "json-schema-to-typescript": "^13.0.1",
33 | "react": "18.3.1",
34 | "react-dom": "18.3.1",
35 | "react-is": "18.3.1"
36 | },
37 | "devDependencies": {
38 | "@abgov/nx-release": "^8.1.4",
39 | "@angular-devkit/build-angular": "19.1.7",
40 | "@angular-devkit/core": "19.1.7",
41 | "@angular-devkit/schematics": "19.1.7",
42 | "@nx-dotnet/core": "^2.5.0",
43 | "@nx/angular": "20.4.2",
44 | "@nx/cypress": "20.4.2",
45 | "@nx/eslint": "20.4.2",
46 | "@nx/eslint-plugin": "20.4.2",
47 | "@nx/express": "20.4.2",
48 | "@nx/jest": "20.4.2",
49 | "@nx/js": "20.4.2",
50 | "@nx/node": "20.4.2",
51 | "@nx/plugin": "20.4.2",
52 | "@nx/react": "20.4.2",
53 | "@nx/web": "20.4.2",
54 | "@nx/workspace": "20.4.2",
55 | "@schematics/angular": "19.1.7",
56 | "@semantic-release/commit-analyzer": "^11.1.0",
57 | "@semantic-release/release-notes-generator": "^12.1.0",
58 | "@types/jest": "29.5.13",
59 | "@types/node": "^18.16.9",
60 | "@types/semantic-release": "^20.0.6",
61 | "@types/simple-oauth2": "^4.1.1",
62 | "@types/split2": "^4.2.3",
63 | "@types/stream-buffers": "^3.0.3",
64 | "@typescript-eslint/eslint-plugin": "7.18.0",
65 | "@typescript-eslint/parser": "7.18.0",
66 | "@typescript-eslint/utils": "^8.13.0",
67 | "axios": "^1.6.0",
68 | "dotenv": "10.0.0",
69 | "enquirer": "^2.3.6",
70 | "eslint": "8.57.1",
71 | "eslint-config-prettier": "9.1.0",
72 | "execa": "^5.0.0",
73 | "get-stream": "^6.0.0",
74 | "jest": "29.7.0",
75 | "json-schema-to-typescript": "^13.0.1",
76 | "nx": "20.4.2",
77 | "open": "^8.4.0",
78 | "prettier": "2.7.1",
79 | "semantic-release": "^23.0.2",
80 | "simple-oauth2": "^5.0.0",
81 | "split2": "^4.2.0",
82 | "stream-buffers": "^3.0.2",
83 | "ts-jest": "^29.1.2",
84 | "ts-node": "10.9.1",
85 | "tslib": "^2.0.0",
86 | "typescript": "5.7.3",
87 | "yaml": "~2.2.2"
88 | },
89 | "overrides": {
90 | "@angular-devkit/build-angular": "19.1.7",
91 | "@angular/compiler-cli": "19.1.6",
92 | "@nx/devkit": "20.4.2",
93 | "semantic-release": "^23.0.2"
94 | }
95 | }
96 |
--------------------------------------------------------------------------------