Skip to content

Instantly share code, notes, and snippets.

@mike-hogan
Last active March 11, 2021 14:53
Show Gist options
  • Save mike-hogan/336de1a55ad1a776398ea85c2691dfd2 to your computer and use it in GitHub Desktop.
Save mike-hogan/336de1a55ad1a776398ea85c2691dfd2 to your computer and use it in GitHub Desktop.
Prep a rushjs project for deployment in Firebase Functions
/**
* This script will makes a rushjs project ready for deployment in Firebase Cloud Functions.
*
* It creates a staging directory with rewritten package.json files, and all local rushjs dependencies copied.
*
* It requires ./firebase-files to contain:
* .firebaserc
* .firebase.json
* functions/tsconfig.json
*
* These three files should be exactly as "firebase init functions" created them.
*
* Store this file as scripts/deploy.ts
*
* You run it using "npx ts-node scripts/deploy.ts"
*
* Then:
*
* cd staging/functions
* npm i
* npm run build
* cd ..
* firebase deploy --only function
*/
import rush from '../../../rush.json'
import pkg from '../package.json'
import {exec} from "child_process";
import * as fs from "fs";
import stripAnsi = require("strip-ansi");
// Change this
const organisation = "@docsndata"
function shell(line: string): Promise<string> {
return new Promise<string>((resolve, reject) => {
exec(line, (error, stdout, stderr) => {
if (error) {
reject(error)
}
if (stdout !== "") {
console.log(stdout)
}
if (stderr !== "") {
console.log(stderr)
}
console.log(`Done: ${line}`)
resolve(stdout)
})
})
}
export type RushProject = { packageName: string, projectFolder: string }
function copyPackageDotJson(project: RushProject, allProjects: RushProject[], ) {
const packageDotJson:any = JSON.parse(fs.readFileSync(`../../${project.projectFolder}/package.json`, 'utf8'))
const rewrittenPackageDotJson = allProjects.reduce((acc:any, current) => {
if(acc.dependencies && acc.dependencies[current.packageName]) {
acc.dependencies[current.packageName] = `file:../../${current.projectFolder}`
}
return acc
}, packageDotJson)
fs.writeFileSync(`staging/functions/local_deps/${project.projectFolder}/package.json`, JSON.stringify(rewrittenPackageDotJson, null, 2))
}
async function main() {
await shell("mkdir -p staging/functions/local_deps")
const localDeps = stripAnsi(await shell("rush build -t ."))
.split("\n")
.filter(line => line.startsWith(organisation + "/"))
.filter(line => line !== pkg.name)
const referencedProjects = rush.projects.filter(p => localDeps.includes(p.packageName))
const mkdirLines = referencedProjects.map(rp => `mkdir -p staging/functions/local_deps/${rp.projectFolder}`)
await Promise.all(mkdirLines.map(shell))
const copyDistLines = referencedProjects.map(rp => `cp -r ../../${rp.projectFolder}/dist staging/functions/local_deps/${rp.projectFolder}/`)
await Promise.all(copyDistLines.map(shell))
referencedProjects.map(rp => copyPackageDotJson(rp, referencedProjects))
await Promise.all([
shell("cp -r firebase-files/* staging/"),
shell("cp firebase-files/.firebaserc staging/"),
shell("cp -r src staging/functions")
])
const rewrittenDependencies: { [key: string]: string } = {...pkg.dependencies}
for (const localDep of localDeps) {
const rushDef = referencedProjects.find(rp => rp.packageName === localDep)!
rewrittenDependencies[localDep] = `file:./local_deps/${rushDef.projectFolder}`
}
// @ts-ignore
pkg.dependencies = rewrittenDependencies
fs.writeFileSync(`staging/functions/package.json`, JSON.stringify(pkg, null, 2))
}
main().catch(err => console.error(err))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment