-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(schematics): ng deploy schematic (#2046)
- Loading branch information
1 parent
c34c0f3
commit be0a1fb
Showing
25 changed files
with
3,156 additions
and
177 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
# Deploy your application on Firebase Hosting | ||
|
||
In this guide, we'll look at how to use `@angular/fire` to automatically deploy an Angular application to Firebase hosting by using the Angular CLI. | ||
|
||
## Step 1: add `@angular/fire` to your project | ||
|
||
First, you need to add the `@angular/fire` package to your project. In your Angular CLI project run: | ||
|
||
```shell | ||
ng add @angular/fire | ||
``` | ||
|
||
*Note that the command above assumes you have global Angular CLI installed. To install Angular CLI globally run `npm i -g @angular/cli`.* | ||
|
||
The command above will trigger the `@angular/fire` `ng-add` schematics. The schematics will open a web browser and guide you through the Firebase authentication flow (if you're not signed in already). After you authenticate, you'll see a prompt to select a Firebase hosting project. | ||
|
||
The schematics will do the following: | ||
|
||
- Add `@angular/fire` to your list of dependencies | ||
- Create `firebase.json`, `.firebaserc` files in the root of your workspace. You can use them to configure your firebase hosting deployment. Find more about them [here](https://firebase.google.com/docs/hosting/full-config) | ||
- Update your workspace file (`angular.json`) by inserting the `deploy` builder | ||
|
||
In the end, your `angular.json` project will look like below: | ||
|
||
```json | ||
{ | ||
"$schema": "./node_modules/@angular/cli/lib/config/schema.json", | ||
"version": 1, | ||
"newProjectRoot": "projects", | ||
"projects": { | ||
"sample-app": { | ||
// ... | ||
"deploy": { | ||
"builder": "@angular/fire:deploy", | ||
"options": {} | ||
} | ||
} | ||
} | ||
// ... | ||
}, | ||
"defaultProject": "sample-app" | ||
} | ||
``` | ||
|
||
If you want to add deployment capabilities to a different project in your workspace, you can run: | ||
|
||
``` | ||
ng add @angular/fire --project=[PROJECT_NAME] | ||
``` | ||
|
||
## Step 2: deploying the project | ||
|
||
As the second step, to deploy your project run: | ||
|
||
``` | ||
ng run [ANGULAR_PROJECT_NAME]:deploy | ||
``` | ||
|
||
The command above will trigger: | ||
|
||
1. Production build of your application | ||
2. Deployment of the produced assets to the firebase hosting project you selected during `ng add` | ||
|
||
## Step 3: customization | ||
|
||
To customize the deployment flow, you can use the configuration files you're already familiar with from `firebase-tools`. You can find more in the [firebase documentation](https://firebase.google.com/docs/hosting/full-config). |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{ | ||
"$schema": "@angular-devkit/architect/src/builders-schema.json", | ||
"builders": { | ||
"deploy": { | ||
"implementation": "./schematics/deploy/builder", | ||
"schema": "./schematics/deploy/schema.json", | ||
"description": "Deploy builder" | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"$schema": "@angular-devkit/schematics/collection-schema.json", | ||
"schematics": { | ||
"ng-add": { | ||
"description": "Add firebase deploy schematic", | ||
"factory": "./schematics/index#ngDeploy" | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
import { JsonObject, logging } from '@angular-devkit/core'; | ||
import { BuilderContext, BuilderRun, ScheduleOptions, Target, } from '@angular-devkit/architect/src/index2'; | ||
import { FirebaseTools, FirebaseDeployConfig } from 'schematics/interfaces'; | ||
import deploy from './actions'; | ||
|
||
|
||
let context: BuilderContext; | ||
let firebaseMock: FirebaseTools; | ||
|
||
const FIREBASE_PROJECT = 'ikachu-aa3ef'; | ||
const PROJECT = 'pirojok-project'; | ||
|
||
describe('Deploy Angular apps', () => { | ||
beforeEach(() => initMocks()); | ||
|
||
it('should check if the user is authenticated by invoking list', async () => { | ||
const spy = spyOn(firebaseMock, 'list'); | ||
const spyLogin = spyOn(firebaseMock, 'login'); | ||
await deploy(firebaseMock, context, 'host', FIREBASE_PROJECT); | ||
expect(spy).toHaveBeenCalled(); | ||
expect(spyLogin).not.toHaveBeenCalled(); | ||
}); | ||
|
||
it('should invoke login if list rejects', async () => { | ||
firebaseMock.list = () => Promise.reject(); | ||
const spy = spyOn(firebaseMock, 'list').and.callThrough(); | ||
const spyLogin = spyOn(firebaseMock, 'login'); | ||
await deploy(firebaseMock, context, 'host', FIREBASE_PROJECT); | ||
expect(spy).toHaveBeenCalled(); | ||
expect(spyLogin).toHaveBeenCalled(); | ||
}); | ||
|
||
it('should invoke the builder', async () => { | ||
const spy = spyOn(context, 'scheduleTarget').and.callThrough(); | ||
await deploy(firebaseMock, context, 'host', FIREBASE_PROJECT); | ||
expect(spy).toHaveBeenCalled(); | ||
expect(spy).toHaveBeenCalledWith({ | ||
target: 'build', | ||
configuration: 'production', | ||
project: PROJECT | ||
}); | ||
}); | ||
|
||
it('should invoke firebase.deploy', async () => { | ||
const spy = spyOn(firebaseMock, 'deploy').and.callThrough(); | ||
await deploy(firebaseMock, context, 'host', FIREBASE_PROJECT); | ||
expect(spy).toHaveBeenCalled(); | ||
expect(spy).toHaveBeenCalledWith({ | ||
cwd: 'host', only: 'hosting:' + PROJECT | ||
}); | ||
}); | ||
|
||
describe('error handling', () => { | ||
it('throws if there is no firebase project', async () => { | ||
try { | ||
await deploy(firebaseMock, context, 'host') | ||
fail(); | ||
} catch (e) { | ||
expect(e.message).toMatch(/Cannot find firebase project/); | ||
} | ||
}); | ||
|
||
it('throws if there is no target project', async () => { | ||
context.target = undefined; | ||
try { | ||
await deploy(firebaseMock, context, 'host', FIREBASE_PROJECT) | ||
fail(); | ||
} catch (e) { | ||
expect(e.message).toMatch(/Cannot execute the build target/); | ||
} | ||
}); | ||
}); | ||
}); | ||
|
||
const initMocks = () => { | ||
firebaseMock = { | ||
login: () => Promise.resolve(), | ||
list: () => Promise.resolve([]), | ||
deploy: (_: FirebaseDeployConfig) => Promise.resolve(), | ||
use: () => Promise.resolve() | ||
}; | ||
|
||
context = { | ||
target: { | ||
configuration: 'production', | ||
project: PROJECT, | ||
target: 'foo' | ||
}, | ||
builder: { | ||
builderName: 'mock', | ||
description: 'mock', | ||
optionSchema: false | ||
}, | ||
currentDirectory: 'cwd', | ||
id: 1, | ||
logger: new logging.NullLogger() as any, | ||
workspaceRoot: 'cwd', | ||
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) | ||
}; | ||
}; |
Oops, something went wrong.