Skip to content

Commit 17aaf99

Browse files
committed
Initial commit
0 parents  commit 17aaf99

17 files changed

+4518
-0
lines changed

.gitignore

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
node_modules
2+
.tmp
3+
.sass-cache
4+
app/bower_components
5+
.DS_Store
6+
.bash_history
7+
*.swp
8+
*.swo
9+
10+
*.classpath
11+
*.project
12+
*.settings/
13+
*.classpath
14+
*.project
15+
*.settings/
16+
17+
.vim/bundle
18+
nvim/autoload
19+
nvim/plugged
20+
nvim/doc
21+
nvim/swaps
22+
nvim/colors
23+

.vscode/settings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"editor.formatOnSave": true
3+
}

deploy/actions.spec.ts

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import { JsonObject, logging } from '@angular-devkit/core';
2+
import {
3+
BuilderContext,
4+
BuilderRun,
5+
ScheduleOptions,
6+
Target
7+
} from '@angular-devkit/architect/src/index';
8+
import deploy from './actions';
9+
10+
let context: BuilderContext;
11+
12+
const PROJECT = 'pirojok-project';
13+
14+
describe('Deploy Angular apps', () => {
15+
beforeEach(() => initMocks());
16+
17+
it('should invoke the builder', async () => {
18+
const spy = spyOn(context, 'scheduleTarget').and.callThrough();
19+
await deploy(
20+
{
21+
publish() {}
22+
},
23+
context,
24+
'host'
25+
);
26+
expect(spy).toHaveBeenCalled();
27+
expect(spy).toHaveBeenCalledWith({
28+
target: 'build',
29+
configuration: 'production',
30+
project: PROJECT
31+
});
32+
});
33+
34+
it('should invoke ghpages.publish', async () => {
35+
const mock = {
36+
publish() {}
37+
};
38+
const spy = spyOn(mock, 'publish').and.callThrough();
39+
await deploy(mock, context, 'host');
40+
expect(spy).toHaveBeenCalled();
41+
expect(spy).toHaveBeenCalledWith('host', {}, expect.any(Function));
42+
});
43+
44+
describe('error handling', () => {
45+
it('throws if there is no target project', async () => {
46+
context.target = undefined;
47+
try {
48+
await deploy(
49+
{
50+
publish() {}
51+
},
52+
context,
53+
'host'
54+
);
55+
fail();
56+
} catch (e) {
57+
expect(e.message).toMatch(/Cannot execute the build target/);
58+
}
59+
});
60+
});
61+
});
62+
63+
const initMocks = () => {
64+
context = {
65+
target: {
66+
configuration: 'production',
67+
project: PROJECT,
68+
target: 'foo'
69+
},
70+
builder: {
71+
builderName: 'mock',
72+
description: 'mock',
73+
optionSchema: false
74+
},
75+
currentDirectory: 'cwd',
76+
id: 1,
77+
logger: new logging.NullLogger() as any,
78+
workspaceRoot: 'cwd',
79+
addTeardown: _ => {},
80+
validateOptions: _ => Promise.resolve({} as any),
81+
getBuilderNameForTarget: () => Promise.resolve(''),
82+
analytics: null as any,
83+
getTargetOptions: (_: Target) => Promise.resolve({}),
84+
reportProgress: (_: number, __?: number, ___?: string) => {},
85+
reportStatus: (_: string) => {},
86+
reportRunning: () => {},
87+
scheduleBuilder: (_: string, __?: JsonObject, ___?: ScheduleOptions) =>
88+
Promise.resolve({} as BuilderRun),
89+
scheduleTarget: (_: Target, __?: JsonObject, ___?: ScheduleOptions) =>
90+
Promise.resolve({} as BuilderRun)
91+
};
92+
};

deploy/actions.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { BuilderContext } from '@angular-devkit/architect';
2+
import { GHPages } from '../interfaces';
3+
4+
export default async function deploy(
5+
ghPages: GHPages,
6+
context: BuilderContext,
7+
projectRoot: string
8+
) {
9+
if (!context.target) {
10+
throw new Error('Cannot execute the build target');
11+
}
12+
13+
context.logger.info(`📦 Building "${context.target.project}"`);
14+
15+
const run = await context.scheduleTarget({
16+
target: 'build',
17+
project: context.target.project,
18+
configuration: 'production'
19+
});
20+
await run.result;
21+
22+
try {
23+
const success = ghPages.publish(projectRoot, {}, err => {
24+
if (err) {
25+
context.logger.error(err);
26+
return;
27+
}
28+
console.log(arguments);
29+
context.logger.info(
30+
`🚀 Your application is now available at https://${
31+
success.hosting.split('/')[1]
32+
}.firebaseapp.com/`
33+
);
34+
});
35+
} catch (e) {
36+
context.logger.error(e);
37+
}
38+
}

deploy/builder.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import {
2+
BuilderContext,
3+
BuilderOutput,
4+
createBuilder
5+
} from '@angular-devkit/architect';
6+
import { NodeJsSyncHost } from '@angular-devkit/core/node';
7+
import deploy from './actions';
8+
import { experimental, join, normalize } from '@angular-devkit/core';
9+
const ghpages = require('gh-pages');
10+
11+
// Call the createBuilder() function to create a builder. This mirrors
12+
// createJobHandler() but add typings specific to Architect Builders.
13+
export default createBuilder<any>(
14+
async (_: any, context: BuilderContext): Promise<BuilderOutput> => {
15+
// The project root is added to a BuilderContext.
16+
const root = normalize(context.workspaceRoot);
17+
const workspace = new experimental.workspace.Workspace(
18+
root,
19+
new NodeJsSyncHost()
20+
);
21+
await workspace
22+
.loadWorkspaceFromHost(normalize('angular.json'))
23+
.toPromise();
24+
25+
if (!context.target) {
26+
throw new Error('Cannot deploy the application without a target');
27+
}
28+
29+
const project = workspace.getProject(context.target.project);
30+
31+
try {
32+
await deploy(ghpages, context, join(workspace.root, project.root));
33+
} catch (e) {
34+
console.error('Error when trying to deploy: ');
35+
console.error(e.message);
36+
return { success: false };
37+
}
38+
39+
return { success: true };
40+
}
41+
);

deploy/schema.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"id": "GHPagesDeploySchema",
3+
"title": "GH pages deploy",
4+
"description": "TBD",
5+
"properties": {}
6+
}

index.spec.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import './ng-add.spec';
2+
import './deploy/actions.spec';

index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './public_api';

interfaces.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
export interface GHPages {
2+
publish(dir: string, options: any, callback: any);
3+
}
4+
5+
export interface Project {
6+
name: string;
7+
id: string;
8+
}

0 commit comments

Comments
 (0)