Skip to content

Commit 266f2ec

Browse files
feat(ng-deploy): add option for buildTarget (#2281)
Co-authored-by: James Daniels <[email protected]>
1 parent 5ccf5db commit 266f2ec

File tree

5 files changed

+41
-18
lines changed

5 files changed

+41
-18
lines changed

src/schematics/deploy/actions.spec.ts

+16-7
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,15 @@ let firebaseMock: FirebaseTools;
99

1010
const FIREBASE_PROJECT = 'ikachu-aa3ef';
1111
const PROJECT = 'pirojok-project';
12+
const BUILD_TARGET = `${PROJECT}:build:production`;
1213

1314
describe('Deploy Angular apps', () => {
1415
beforeEach(() => initMocks());
1516

1617
it('should check if the user is authenticated by invoking list', async () => {
1718
const spy = spyOn(firebaseMock, 'list');
1819
const spyLogin = spyOn(firebaseMock, 'login');
19-
await deploy(firebaseMock, context, 'host', FIREBASE_PROJECT);
20+
await deploy(firebaseMock, context, 'host', BUILD_TARGET, FIREBASE_PROJECT);
2021
expect(spy).toHaveBeenCalled();
2122
expect(spyLogin).not.toHaveBeenCalled();
2223
});
@@ -25,14 +26,14 @@ describe('Deploy Angular apps', () => {
2526
firebaseMock.list = () => Promise.reject();
2627
const spy = spyOn(firebaseMock, 'list').and.callThrough();
2728
const spyLogin = spyOn(firebaseMock, 'login');
28-
await deploy(firebaseMock, context, 'host', FIREBASE_PROJECT);
29+
await deploy(firebaseMock, context, 'host', BUILD_TARGET, FIREBASE_PROJECT);
2930
expect(spy).toHaveBeenCalled();
3031
expect(spyLogin).toHaveBeenCalled();
3132
});
3233

3334
it('should invoke the builder', async () => {
3435
const spy = spyOn(context, 'scheduleTarget').and.callThrough();
35-
await deploy(firebaseMock, context, 'host', FIREBASE_PROJECT);
36+
await deploy(firebaseMock, context, 'host', BUILD_TARGET, FIREBASE_PROJECT);
3637
expect(spy).toHaveBeenCalled();
3738
expect(spy).toHaveBeenCalledWith({
3839
target: 'build',
@@ -41,9 +42,17 @@ describe('Deploy Angular apps', () => {
4142
});
4243
});
4344

45+
it('should allow the buildTarget to be specified', async () => {
46+
const buildTarget = `${PROJECT}:prerender`;
47+
const spy = spyOn(context, 'scheduleTarget').and.callThrough();
48+
await deploy(firebaseMock, context, 'host', buildTarget, FIREBASE_PROJECT);
49+
expect(spy).toHaveBeenCalled();
50+
expect(spy).toHaveBeenCalledWith({ target: 'prerender', project: PROJECT });
51+
});
52+
4453
it('should invoke firebase.deploy', async () => {
4554
const spy = spyOn(firebaseMock, 'deploy').and.callThrough();
46-
await deploy(firebaseMock, context, 'host', FIREBASE_PROJECT);
55+
await deploy(firebaseMock, context, 'host', BUILD_TARGET, FIREBASE_PROJECT);
4756
expect(spy).toHaveBeenCalled();
4857
expect(spy).toHaveBeenCalledWith({
4958
cwd: 'host', only: 'hosting:' + PROJECT
@@ -53,7 +62,7 @@ describe('Deploy Angular apps', () => {
5362
describe('error handling', () => {
5463
it('throws if there is no firebase project', async () => {
5564
try {
56-
await deploy(firebaseMock, context, 'host')
65+
await deploy(firebaseMock, context, 'host', BUILD_TARGET)
5766
fail();
5867
} catch (e) {
5968
expect(e.message).toMatch(/Cannot find firebase project/);
@@ -63,7 +72,7 @@ describe('Deploy Angular apps', () => {
6372
it('throws if there is no target project', async () => {
6473
context.target = undefined;
6574
try {
66-
await deploy(firebaseMock, context, 'host', FIREBASE_PROJECT)
75+
await deploy(firebaseMock, context, 'host', BUILD_TARGET, FIREBASE_PROJECT)
6776
fail();
6877
} catch (e) {
6978
expect(e.message).toMatch(/Cannot execute the build target/);
@@ -103,4 +112,4 @@ const initMocks = () => {
103112
scheduleBuilder: (_: string, __?: JsonObject, ___?: ScheduleOptions) => Promise.resolve({} as BuilderRun),
104113
scheduleTarget: (_: Target, __?: JsonObject, ___?: ScheduleOptions) => Promise.resolve({} as BuilderRun)
105114
};
106-
};
115+
};

src/schematics/deploy/actions.ts

+4-7
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
import { BuilderContext } from "@angular-devkit/architect";
1+
import { BuilderContext, targetFromTargetString } from "@angular-devkit/architect";
22
import { FirebaseTools } from "../interfaces";
33

44
export default async function deploy(
55
firebaseTools: FirebaseTools,
66
context: BuilderContext,
77
projectRoot: string,
8-
firebaseProject?: string
8+
buildTarget: string,
9+
firebaseProject?: string,
910
) {
1011
if (!firebaseProject) {
1112
throw new Error("Cannot find firebase project for your app in .firebaserc");
@@ -25,11 +26,7 @@ export default async function deploy(
2526

2627
context.logger.info(`📦 Building "${context.target.project}"`);
2728

28-
const run = await context.scheduleTarget({
29-
target: "build",
30-
project: context.target.project,
31-
configuration: "production"
32-
});
29+
const run = await context.scheduleTarget(targetFromTargetString(buildTarget));
3330
await run.result;
3431

3532
try {

src/schematics/deploy/builder.ts

+8-2
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,17 @@ import {
55
} from "@angular-devkit/architect";
66
import { NodeJsSyncHost } from "@angular-devkit/core/node";
77
import deploy from "./actions";
8-
import { experimental, normalize } from "@angular-devkit/core";
8+
import { experimental, normalize, json } from "@angular-devkit/core";
9+
import { DeployBuilderSchema } from '../interfaces';
910
import * as path from "path";
1011
import { getFirebaseProjectName } from "../utils";
1112

13+
type DeployBuilderOptions = DeployBuilderSchema & json.JsonObject;
14+
1215
// Call the createBuilder() function to create a builder. This mirrors
1316
// createJobHandler() but add typings specific to Architect Builders.
1417
export default createBuilder<any>(
15-
async (_: any, context: BuilderContext): Promise<BuilderOutput> => {
18+
async (options: DeployBuilderOptions, context: BuilderContext): Promise<BuilderOutput> => {
1619
// The project root is added to a BuilderContext.
1720
const root = normalize(context.workspaceRoot);
1821
const workspace = new experimental.workspace.Workspace(
@@ -34,11 +37,14 @@ export default createBuilder<any>(
3437
context.target.project
3538
);
3639

40+
const buildTarget = options.buildTarget || `build:${context.target.project}:production`;
41+
3742
try {
3843
await deploy(
3944
require("firebase-tools"),
4045
context,
4146
path.join(context.workspaceRoot, project.root),
47+
buildTarget,
4248
firebaseProject
4349
);
4450
} catch (e) {

src/schematics/deploy/schema.json

+9-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
{
2+
"$schema": "http://json-schema.org/draft-07/schema",
23
"id": "FirebaseDeploySchema",
34
"title": "Firebase Deploy",
4-
"description": "TBD",
5-
"properties": {}
5+
"description": "Ng Deploy target options for Firebase.",
6+
"properties": {
7+
"buildTarget": {
8+
"type": "string",
9+
"description": "Target to build.",
10+
"pattern": "^[^:\\s]+:[^:\\s]+(:[^\\s]+)?$"
11+
}
12+
}
613
}

src/schematics/interfaces.ts

+4
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,7 @@ export interface FirebaseRcTarget {
4242
export interface FirebaseRc {
4343
targets?: Record<string, FirebaseRcTarget>;
4444
}
45+
46+
export interface DeployBuilderSchema {
47+
buildTarget?: string;
48+
}

0 commit comments

Comments
 (0)