Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Support migration #148

Merged
merged 9 commits into from
Sep 22, 2023
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
16 changes: 13 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@

All notable changes to this project will be documented in this file.

This plugin was completely rewritten since V2.x to use esbuild for bundling cloud functions. For documentation of the legacy v1.x plugin version see [here](https://github.com/simondotm/nx-firebase/tree/release/v1.1.0).

- [@simondotm/nx-firebase Changelog](#simondotmnx-firebase-changelog)
- [v2.1.0](#v210)
- [v2.0.0](#v200)
- [v2.0.0-beta.1](#v200-beta1)
- [v2.0.0-beta.0](#v200-beta0)
Expand All @@ -19,6 +22,15 @@ All notable changes to this project will be documented in this file.
- [v0.2.3](#v023)
- [v0.2.2 - Initial Release](#v022---initial-release)

## v2.1.0

* Added support for [environment variables](docs/nx-firebase-functions-environment.md)
* Added support for [secrets](docs/nx-firebase-functions-environment.md#environment-file-types)
* Added a custom `serve` executor that exits the Firebase Emulator suite properly
* Fixes to `sync` generator to update firebase app and firebase function project targets when they are renamed
* Added a custom `migrate` generator to ensure workspace configurations match the latest plugin version schemas
* Updated plugin to be built against Nx 16.6.0

## v2.0.0

Official v2 release
Expand All @@ -35,7 +47,7 @@ Official v2 release

Initial beta of plugin version 2.0.

Users of earlier plugin versions must read [here for plugin v1 -> v2 migration instructions](docs/nx-firebase-v2-migration.md)
Users of earlier plugin versions must read [here for plugin v1 -> v2 migration instructions](docs/nx-firebase-migrations.md)

> **Please note that legacy v1 versions of the plugin are no longer supported from this point on, so only take this update if you are prepared to migrate your workspace and Firebase projects**

Expand All @@ -50,8 +62,6 @@ Users of earlier plugin versions must read [here for plugin v1 -> v2 migration i
* Minimum Nx version is now 16.1.1
* Watch mode build of function code & libraries is now fully supported when running Firebase emulator



## v1.1.0

No changes from beta.
Expand Down
41 changes: 24 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,44 +6,51 @@ A plugin for [Nx](https://nx.dev) v16.1.1+ that provides support for Firebase pr

See [CHANGELOG](https://github.com/simondotm/nx-firebase/blob/main/CHANGELOG.md) for release notes.

This plugin was completely rewritten since V2.x to use esbuild for bundling cloud functions. For documentation of the legacy v1.x plugin version see [here](https://github.com/simondotm/nx-firebase/tree/release/v1.1.0).

## Overview

Nx provides a great way to manage monorepo workflows and this plugin helps make it easy to integrate Firebase projects with Nx.

Features:

* Supports single or multiple firebase projects/apps within an Nx workspace
* Generates Firebase application projects, with default `firebase.json` configurations, rules and indexes for each Firebase app
* Generates Firebase functions using customised Typescript Nx node applications
* Bundling of functions using `esbuild` for extremely fast compilation & tree-shaking for faster cold starts
* Easily import Typescript code libraries in your Firebase functions for code sharing
* Supports function environment variables and secrets
* Nx's automatic dependency checking for no-fuss builds, and per-project or per-function deployments
* Use the Firebase Emulator suite whilst developing locally - all functions are watched and updated live while you work
* Workspace management with the `sync` generator keeps your `firebase.json` configs automatically updated when renaming or deleting functions
* Only very lightly opinionated about your Firebase configurations and workspace layouts; you can use Nx or the Firebase CLI
### Features

* **Firebase Apps**
* Generates Firebase application projects, with default `firebase.json` configurations, rules and indexes for each Firebase app
* **Firebase Functions**
* Generates Firebase function apps based on Typescript Nx node applications
* Bundling of Firebase functions using `esbuild` for extremely fast compilation & tree-shaking for optimal function cold starts
* Easily import Typescript Nx libraries from your Nx workspace into your Firebase functions for code sharing across projects
* Supports function environment variables and secrets
* **Firebase Features**
* Use the Firebase Emulator suite whilst developing locally - all functions are watched and updated live while you work
* Use Firebase hosting with Nx to easily build & deploy web apps
* **Workspace Management**
* Nx's automatic dependency checking for no-fuss builds, and per-project or per-function deployments
* Supports single or multiple firebase projects/apps within an Nx workspace
* Nx workspace management with the `sync` generator keeps your project & `firebase.json` configs automatically updated when renaming or deleting Firebase apps & functions
* Only very lightly opinionated about your Firebase configurations and workspace layouts; you can use Nx or the Firebase CLI

# User Guide

- **[Quick Start](docs/quick-start.md)**
- [Migrating from plugin v1.x to v2.x](docs/nx-firebase-v2-migration.md)
- [Migrating to new plugin versions](docs/nx-firebase-migrations.md)

**Nx Firebase Generators**

- [Firebase Applications](docs/nx-firebase-applications.md)
- [Firebase Functions](docs/nx-firebase-functions.md)
- [Firebase Functions - Environment Variables](docs/nx-firebase-functions-environment.md)
- [Firebase Sync](docs/nx-firebase-sync.md)

**Nx Firebase**

- [Firebase Hosting](docs/nx-firebase-hosting.md)
- [Firebase Emulators](docs/nx-firebase-emulators.md)
- [Firebase Databases](docs/nx-firebase-databases.md)
- [Firebase Projects](docs/nx-firebase-projects.md)
- [Project Schemas](docs/nx-firebase-project-structure.md)

**Nx Firebase Workspace Management**

- [Nx-Firebase Sync](docs/nx-firebase-sync.md)
- [Nx-Firebase Project Schemas](docs/nx-firebase-project-structure.md)


**Nx Workspace**

Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,58 @@
# Migration to plugin v2.x from v1.x
# Nx-Firebase Plugin Migrations

Newer versions of the plugin occasionally need to update the workspace configurations, and this page documents the strategies available across these versions.

Please note that these migrations are provided on a 'best effort' basis, due to the fact that workspaces are quite complex and often customised.

- [Nx-Firebase Plugin Migrations](#nx-firebase-plugin-migrations)
- [Migrating to plugin v2.1 from v2.0](#migrating-to-plugin-v21-from-v20)
- [Migration to plugin v2.x from v1.x](#migration-to-plugin-v2x-from-v1x)
- [1. Workspace Migration](#1-workspace-migration)
- [2. Firebase Project Migration](#2-firebase-project-migration)
- [3. Firebase Application Migration](#3-firebase-application-migration)
- [4. Firebase Functions Migration](#4-firebase-functions-migration)
- [5. Library updates](#5-library-updates)
- [6. Check Migration](#6-check-migration)




## Migrating to plugin v2.1 from v2.0

Plugin version 2.1 [added some new features](../CHANGELOG.md#v210) that required changes to the project configurations.

To help with this & future updates, an automatic migration generator has been added:

* Update to the latest plugin using `npm i @simondotm/nx-firebase@latest --save-dev`
* Run **npx nx g @simondotm/nx-firebase:migrate**

This tool will run checks on your workspace firebase apps, functions and configurations and try to ensure they are correctly configured for compatibility with the plugin version you are using.

> Please note, this generator is not the same as Nx's own migration tool, so always review the changes it makes to ensure they are appropriate for your workspace.

## Migration to plugin v2.x from v1.x

Version 2.x of this plugin has been completely rewritten, and uses a completely new approach to building & deploying, so migrating an existing Nx workspace using V1 of the plugin to use V2 requires some manual migration procedures.

## 1. Workspace Migration
### 1. Workspace Migration

* First of all, your workspace will need to be migrated to at least Nx 16.1.1.

* Next, update the `@simondotm/nx-firebase` plugin package to the latest v2.x version.

## 2. Firebase Project Migration
### 2. Firebase Project Migration

Run the following steps 3-5 in order, for each separate Firebase application project in your workspace.

## 3. Firebase Application Migration
### 3. Firebase Application Migration

* Next, you can either [generate a new firebase v2 application](./nx-firebase-applications.md) project and copy across your Firebase rules, indexes, storage rules etc. to the new firebase application project folder

OR

* you can manually modify your existing Firebase `project.json` to be structured [as shown here](./nx-firebase-project-structure.md#firebase-applications).

## 4. Firebase Functions Migration
### 4. Firebase Functions Migration

If you are using Firebase functions in your project, the migration process is as follows:

Expand All @@ -42,15 +74,15 @@ If you are using Firebase functions in your project, the migration process is as

Check the [Nx-Firebase project schemas](./nx-firebase-project-structure.md) document for more information about the v2 plugin generators project layouts.

## 5. Library updates
### 5. Library updates

The previous version of the plugin required that all Nx libraries imported by firebase functions were buildable.

With v2 of the plugin, this is no longer the case and Nx libraries can be buildable or non-buildable, since `esbuild` builds from Typescript source files, not compiled JS.

Nx Typescript libraries can be converted to non-buildable by simply removing the `build` target from their `project.json` files.

## 6. Check Migration
### 6. Check Migration

Run `nx build your-firebase-project-name` to compile & bundle your functions.

Expand Down
166 changes: 91 additions & 75 deletions e2e/nx-firebase-e2e/test-utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@ export async function syncGeneratorAsync(params: string = '') {
return await safeRunNxCommandAsync(`g @simondotm/nx-firebase:sync ${params}`)
}

export async function migrateGeneratorAsync(params: string = '') {
return await safeRunNxCommandAsync(`g @simondotm/nx-firebase:migrate ${params}`)
}

export async function libGeneratorAsync(projectData: ProjectData, params: string = '') {
return await safeRunNxCommandAsync(`g @nx/js:lib ${projectData.name} ${params}`)
}
Expand Down Expand Up @@ -133,6 +137,12 @@ export function expectStrings(input: string, contains: string[]) {
})
}

export function expectNoStrings(input: string, contains: string[]) {
contains.forEach((item) => {
expect(input).not.toContain(item)
})
}

/**
* Generate test project data
* Note: call this function AFTER initial app firebase.json has been created in order to have a
Expand Down Expand Up @@ -205,87 +215,93 @@ export function addImport(mainTs: string, addition: string) {
return replaced
}


export function expectedAppProjectTargets(projectDir: string, projectName: string) {
return {
build: {
executor: 'nx:run-commands',
options: {
command: `echo Build succeeded.`,
},
},
watch: {
executor: 'nx:run-commands',
options: {
command: `nx run-many --targets=build --projects=tag:firebase:dep:${projectName} --parallel=100 --watch`,
},
},
lint: {
executor: 'nx:run-commands',
options: {
command: `nx run-many --targets=lint --projects=tag:firebase:dep:${projectName} --parallel=100`,
},
},
test: {
executor: 'nx:run-commands',
options: {
command: `nx run-many --targets=test --projects=tag:firebase:dep:${projectName} --parallel=100`,
},
},
firebase: {
executor: 'nx:run-commands',
options: {
command: `firebase --config=firebase.json`,
},
configurations: {
production: {
command: `firebase --config=firebase.json`,
},
},
},
killports: {
executor: 'nx:run-commands',
options: {
command: `kill-port --port 9099,5001,8080,9000,5000,8085,9199,9299,4000,4400,4500`,
},
},
getconfig: {
executor: 'nx:run-commands',
options: {
command: `nx run ${projectName}:firebase functions:config:get > ${projectDir}/environment/.runtimeconfig.json`,
},
},
emulate: {
executor: 'nx:run-commands',
options: {
commands: [
`nx run ${projectName}:killports`,
`nx run ${projectName}:firebase emulators:start --import=${projectDir}/.emulators --export-on-exit`,
],
parallel: false,
},
},
serve: {
executor: '@simondotm/nx-firebase:serve',
options: {
commands: [
`nx run ${projectName}:watch`,
`nx run ${projectName}:emulate`,
],
},
},
deploy: {
executor: 'nx:run-commands',
dependsOn: ['build'],
options: {
command: `nx run ${projectName}:firebase deploy`,
},
},
}
}

export function validateProjectConfig(projectDir: string, projectName: string) {
const project = readJson(
`${projectDir}/project.json`,
)
// expect(project.root).toEqual(`apps/${projectName}`)
expect(project.targets).toEqual(
expect.objectContaining({
build: {
executor: 'nx:run-commands',
options: {
command: `echo Build succeeded.`,
},
},
watch: {
executor: 'nx:run-commands',
options: {
command: `nx run-many --targets=build --projects=tag:firebase:dep:${projectName} --parallel=100 --watch`,
},
},
lint: {
executor: 'nx:run-commands',
options: {
command: `nx run-many --targets=lint --projects=tag:firebase:dep:${projectName} --parallel=100`,
},
},
test: {
executor: 'nx:run-commands',
options: {
command: `nx run-many --targets=test --projects=tag:firebase:dep:${projectName} --parallel=100`,
},
},
firebase: {
executor: 'nx:run-commands',
options: {
command: `firebase --config=firebase.json`,
},
configurations: {
production: {
command: `firebase --config=firebase.json`,
},
},
},
killports: {
executor: 'nx:run-commands',
options: {
command: `kill-port --port 9099,5001,8080,9000,5000,8085,9199,9299,4000,4400,4500`,
},
},
getconfig: {
executor: 'nx:run-commands',
options: {
command: `nx run ${projectName}:firebase functions:config:get > ${projectDir}/environment/.runtimeconfig.json`,
},
},
emulate: {
executor: 'nx:run-commands',
options: {
commands: [
`nx run ${projectName}:killports`,
`nx run ${projectName}:firebase emulators:start --import=${projectDir}/.emulators --export-on-exit`,
],
parallel: false,
},
},
serve: {
executor: '@simondotm/nx-firebase:serve',
options: {
commands: [
`nx run ${projectName}:watch`,
`nx run ${projectName}:emulate`,
],
},
},
deploy: {
executor: 'nx:run-commands',
dependsOn: ['build'],
options: {
command: `nx run ${projectName}:firebase deploy`,
},
},
}),
expect.objectContaining(expectedAppProjectTargets(projectDir, projectName)),
)
}


Loading
Loading