Skip to content
This repository was archived by the owner on Jan 26, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"singleQuote": true
}
51 changes: 25 additions & 26 deletions src/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
> This is a sample project that helps you to implement your own deployment builder (`ng deploy`) for the Angular CLI.
> The actual "deployment" is only a simple copy to another folder in the file system.
>
>**Learn more at
> **Learn more at
> https://github.com/angular-schule/ngx-deploy-starter**

## Usage
Expand All @@ -23,18 +23,17 @@ Deploy your project to the file system.
ng deploy [options]
```


## Options

The following options are also available.


#### --configuration
* __optional__
* Default: `production` (string)
* Example:
* `ng deploy` – Angular project is build in production mode
* `ng deploy --configuration=test` – Angular project is using the configuration `test` (this configuration must exist in the `angular.json` file)

- **optional**
- Default: `production` (string)
- Example:
- `ng deploy` – Angular project is build in production mode
- `ng deploy --configuration=test` – Angular project is using the configuration `test` (this configuration must exist in the `angular.json` file)

A named build target, as specified in the `configurations` section of `angular.json`.
Each named target is accompanied by a configuration of option defaults for that target.
Expand All @@ -43,37 +42,37 @@ This command has no effect if the option `--no-build` option is active.

> **This is a proposal from [RFC #1](https://github.com/angular-schule/ngx-deploy-starter/issues/1).**


#### --no-build
* __optional__
* Default: `false` (string)
* Example:
* `ng deploy` – Angular project is build in production mode before the deployment
* `ng deploy --no-build` – Angular project is NOT build

- **optional**
- Default: `false` (string)
- Example:
- `ng deploy` – Angular project is build in production mode before the deployment
- `ng deploy --no-build` – Angular project is NOT build

Skip build process during deployment.
This can be used when you are sure that you haven't changed anything and want to deploy with the latest artifact.
This command causes the `--configuration` setting to have no effect.

> **This is a proposal from [RFC #1](https://github.com/angular-schule/ngx-deploy-starter/issues/1).**


#### --target-dir
* __optional__
* Default: `/example-folder` (string)
* Example:
* `ng deploy` -- App is "deployed" to the example folder (if existing)
* `ng deploy --target=/var/www/html` -- App is "deployed" to another folder

> **This is one of the options you can freely choose according to your needs.**
- **optional**
- Default: `/example-folder` (string)
- Example:
- `ng deploy` -- App is "deployed" to the example folder (if existing)
- `ng deploy --target=/var/www/html` -- App is "deployed" to another folder

> **This is one of the options you can freely choose according to your needs.**

#### --base-href <a name="base-href"></a>
* __optional__
* Default: `undefined` (string)
* Example:
* `ng deploy` -- `<base href="/">` remains unchanged in your `index.html`
* `ng deploy --base-href=/the-repositoryname/` -- `<base href="/the-repositoryname/">` is added to your `index.html`

- **optional**
- Default: `undefined` (string)
- Example:
- `ng deploy` -- `<base href="/">` remains unchanged in your `index.html`
- `ng deploy --base-href=/the-repositoryname/` -- `<base href="/the-repositoryname/">` is added to your `index.html`

Specifies the base URL for the application being built.
Same as `ng build --base-href=/XXX/`
Expand Down
31 changes: 20 additions & 11 deletions src/deploy/actions.spec.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import { JsonObject, logging } from '@angular-devkit/core';
import { BuilderContext, BuilderRun, ScheduleOptions, Target } from '@angular-devkit/architect/src/index';
import {
BuilderContext,
BuilderRun,
ScheduleOptions,
Target
} from '@angular-devkit/architect/src/index';
import deploy from './actions';

let context: BuilderContext;
const mockEngine = { run: (_: string, __: any, __2: any) => Promise.resolve() }
const mockEngine = { run: (_: string, __: any, __2: any) => Promise.resolve() };

const PROJECT = 'pirojok-project';

Expand All @@ -14,7 +19,8 @@ describe('Deploy Angular apps', () => {
const spy = spyOn(context, 'scheduleTarget').and.callThrough();
await deploy(mockEngine, context, 'host', {});

expect(spy).toHaveBeenCalledWith({
expect(spy).toHaveBeenCalledWith(
{
target: 'build',
configuration: 'production',
project: PROJECT
Expand All @@ -25,9 +31,10 @@ describe('Deploy Angular apps', () => {

it('should invoke the builder with the baseHref', async () => {
const spy = spyOn(context, 'scheduleTarget').and.callThrough();
await deploy(mockEngine, context, 'host', { baseHref: '/folder'});
await deploy(mockEngine, context, 'host', { baseHref: '/folder' });

expect(spy).toHaveBeenCalledWith({
expect(spy).toHaveBeenCalledWith(
{
target: 'build',
configuration: 'production',
project: PROJECT
Expand Down Expand Up @@ -72,15 +79,17 @@ const initMocks = () => {
id: 1,
logger: new logging.NullLogger() as any,
workspaceRoot: 'cwd',
addTeardown: _ => { },
addTeardown: _ => {},
validateOptions: _ => Promise.resolve({} as any),
getBuilderNameForTarget: () => Promise.resolve(''),
analytics: null as any,
getTargetOptions: (_: Target) => Promise.resolve({}),
reportProgress: (_: number, __?: number, ___?: string) => { },
reportStatus: (_: string) => { },
reportRunning: () => { },
scheduleBuilder: (_: string, __?: JsonObject, ___?: ScheduleOptions) => Promise.resolve({} as BuilderRun),
scheduleTarget: (_: Target, __?: JsonObject, ___?: ScheduleOptions) => Promise.resolve({} as BuilderRun)
reportProgress: (_: number, __?: number, ___?: string) => {},
reportStatus: (_: string) => {},
reportRunning: () => {},
scheduleBuilder: (_: string, __?: JsonObject, ___?: ScheduleOptions) =>
Promise.resolve({} as BuilderRun),
scheduleTarget: (_: Target, __?: JsonObject, ___?: ScheduleOptions) =>
Promise.resolve({} as BuilderRun)
};
};
42 changes: 28 additions & 14 deletions src/deploy/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,41 +3,55 @@ import { json, logging } from '@angular-devkit/core';

import { Schema } from './schema';


export default async function deploy(
engine: { run: (dir: string, options: Schema, logger: logging.LoggerApi) => Promise<void> },
engine: {
run: (
dir: string,
options: Schema,
logger: logging.LoggerApi
) => Promise<void>;
},
context: BuilderContext,
projectRoot: string,
options: Schema
) {

if (options.noBuild) {
context.logger.info(`📦 Skipping build`);
} else {

if (!context.target) {
throw new Error('Cannot execute the build target');
}

const configuration = options.configuration ? options.configuration : 'production'
const configuration = options.configuration
? options.configuration
: 'production';
const overrides = {
// this is an example how to override the workspace set of options
...(options.baseHref && {baseHref: options.baseHref})
...(options.baseHref && { baseHref: options.baseHref })
};

context.logger.info(`📦 Building "${ context.target.project }". Configuration: "${ configuration }".${ options.baseHref ? ' Your base-href: "' + options.baseHref + '"' : '' }`);

const build = await context.scheduleTarget({
target: 'build',
project: context.target.project,
configuration
}, overrides as json.JsonObject);
context.logger.info(
`📦 Building "${
context.target.project
}". Configuration: "${configuration}".${
options.baseHref ? ' Your base-href: "' + options.baseHref + '"' : ''
}`
);

const build = await context.scheduleTarget(
{
target: 'build',
project: context.target.project,
configuration
},
overrides as json.JsonObject
);
await build.result;
}

await engine.run(
projectRoot,
options,
context.logger as unknown as logging.LoggerApi
(context.logger as unknown) as logging.LoggerApi
);
}
15 changes: 9 additions & 6 deletions src/deploy/builder.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { BuilderContext, BuilderOutput, createBuilder } from '@angular-devkit/architect';
import {
BuilderContext,
BuilderOutput,
createBuilder
} from '@angular-devkit/architect';
import { asWindowsPath, experimental, normalize } from '@angular-devkit/core';
import { NodeJsSyncHost } from '@angular-devkit/core/node';
import os from 'os';
Expand All @@ -11,10 +15,7 @@ import { Schema } from './schema';
// Call the createBuilder() function to create a builder. This mirrors
// createJobHandler() but add typings specific to Architect Builders.
export default createBuilder<any>(
async (
options: Schema,
context: BuilderContext
): Promise<BuilderOutput> => {
async (options: Schema, context: BuilderContext): Promise<BuilderOutput> => {
// The project root is added to a BuilderContext.
const root = normalize(context.workspaceRoot);
const workspace = new experimental.workspace.Workspace(
Expand Down Expand Up @@ -43,7 +44,9 @@ export default createBuilder<any>(
// normalizes pathes don't work with all native functions
// as a workaround, you can use the following 2 lines
const isWin = os.platform() === 'win32';
const workspaceRoot = !isWin ? workspace.root : asWindowsPath(workspace.root);
const workspaceRoot = !isWin
? workspace.root
: asWindowsPath(workspace.root);
// if this is not necessary, use this:
// const workspaceRoot = workspace.root;

Expand Down
1 change: 0 additions & 1 deletion src/engine/engine.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { NullLogger } from '@angular-devkit/core/src/logger';

describe('engine', () => {
it('should copy directory', () => {

// TODO: really write test here!
expect(1 + 1).toEqual(2);
});
Expand Down
23 changes: 13 additions & 10 deletions src/engine/engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,25 @@ import * as fse from 'fs-extra';
import { Schema } from '../deploy/schema';

// TODO: add your deployment code here!
export async function run(dir: string, options: Schema, logger: logging.LoggerApi) {

export async function run(
dir: string,
options: Schema,
logger: logging.LoggerApi
) {
try {

options.targetDir = options.targetDir || '/example-folder';

if (!await fse.pathExists(options.targetDir)) {
throw new Error(`Target directory ${ options.targetDir } does not exist!`);
if (!(await fse.pathExists(options.targetDir))) {
throw new Error(`Target directory ${options.targetDir} does not exist!`);
}

await fse.copy(dir, options.targetDir)
await fse.copy(dir, options.targetDir);

logger.info('🚀 Successfully published via @angular-schule/ngx-deploy-starter! Have a nice day!');
}
catch (error) {
logger.info(
'🚀 Successfully published via @angular-schule/ngx-deploy-starter! Have a nice day!'
);
} catch (error) {
logger.error('❌ An error occurred!');
throw error;
}
};
}
23 changes: 15 additions & 8 deletions src/ng-add.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,12 @@ describe('ng-add', () => {
project: PROJECT_NAME
})(tree, {} as SchematicContext);

expect(result.read('angular.json')!.toString()).toEqual(initialAngularJson);
expect(result.read('angular.json')!.toString()).toEqual(
initialAngularJson
);
});

it('overrides existing files', async () => {

const tempTree = ngAdd({
project: PROJECT_NAME
})(tree, {} as SchematicContext);
Expand All @@ -41,7 +42,6 @@ describe('ng-add', () => {

describe('error handling', () => {
it('fails if project not defined', () => {

const tree = Tree.empty();
const angularJSON = generateAngularJson();
delete angularJSON.defaultProject;
Expand All @@ -51,7 +51,9 @@ describe('ng-add', () => {
ngAdd({
project: ''
})(tree, {} as SchematicContext)
).toThrowError('No Angular project selected and no default project in the workspace');
).toThrowError(
'No Angular project selected and no default project in the workspace'
);
});

it('Should throw if angular.json not found', async () => {
Expand Down Expand Up @@ -81,7 +83,9 @@ describe('ng-add', () => {
ngAdd({
project: PROJECT_NAME
})(tree, {} as SchematicContext)
).toThrowError('The specified Angular project is not defined in this workspace');
).toThrowError(
'The specified Angular project is not defined in this workspace'
);
});

it('Should throw if specified project is not application', async () => {
Expand All @@ -97,7 +101,9 @@ describe('ng-add', () => {
ngAdd({
project: PROJECT_NAME
})(tree, {} as SchematicContext)
).toThrowError('Deploy requires an Angular project type of "application" in angular.json');
).toThrowError(
'Deploy requires an Angular project type of "application" in angular.json'
);
});

it('Should throw if app does not have architect configured', async () => {
Expand All @@ -113,7 +119,9 @@ describe('ng-add', () => {
ngAdd({
project: PROJECT_NAME
})(tree, {} as SchematicContext)
).toThrowError('Cannot read the output path (architect.build.options.outputPath) of the Angular project "pie-ka-chu" in angular.json');
).toThrowError(
'Cannot read the output path (architect.build.options.outputPath) of the Angular project "pie-ka-chu" in angular.json'
);
});
});
});
Expand Down Expand Up @@ -215,4 +223,3 @@ const overwriteAngularJson = `{
}
}
}`;

10 changes: 6 additions & 4 deletions src/ng-add.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { SchematicsException, Tree, SchematicContext } from '@angular-devkit/schematics';
import {
SchematicsException,
Tree,
SchematicContext
} from '@angular-devkit/schematics';
import { experimental, JsonParseMode, parseJson } from '@angular-devkit/core';

function getWorkspace(
Expand Down Expand Up @@ -68,9 +72,7 @@ export const ngAdd = (options: NgAddOptions) => (
!project.architect.build.options.outputPath
) {
throw new SchematicsException(
`Cannot read the output path (architect.build.options.outputPath) of the Angular project "${
options.project
}" in angular.json`
`Cannot read the output path (architect.build.options.outputPath) of the Angular project "${options.project}" in angular.json`
);
}

Expand Down
Loading