Skip to content

Have CI deploy rules/functions to test project as needed #6531

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

Merged
merged 2 commits into from
Aug 25, 2022
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
32 changes: 32 additions & 0 deletions .github/workflows/deploy-config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Deploy Project Config

on: pull_request

# Detects if any project config files (rules or functions) have changed,
# and deploys them to the test project used for CI if so.
# Run this in its own workflow instead of as a step before each test
# workflow to avoid too many deploys, possibly causing race conditions.
# Since the build step of each test workflow takes a long time, this
# this should finish before the tests begin running.

jobs:
test:
name: Deploy Firebase Project Rules and Functions
runs-on: ubuntu-latest

steps:
- name: Checkout Repo
uses: actions/checkout@master
with:
# This makes Actions fetch all Git history so run-changed script can diff properly.
fetch-depth: 0
- name: Set up Node (14)
uses: actions/setup-node@v2
with:
node-version: 14.x
- name: Yarn install
run: yarn
- name: Deploy project config if needed
run: yarn ts-node scripts/ci-test/deploy-if-needed.ts
env:
FIREBASE_CLI_TOKEN: ${{secrets.FIREBASE_CLI_TOKEN}}
95 changes: 95 additions & 0 deletions scripts/ci-test/deploy-if-needed.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/**
* @license
* Copyright 2022 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import { resolve } from 'path';
import chalk from 'chalk';
import simpleGit from 'simple-git';
import { exec } from 'child-process-promise';
const firebaseTools = require('firebase-tools');

const root = resolve(__dirname, '../..');
const config = require(resolve(root, 'config/ci.config.json'));
const git = simpleGit(root);

interface DeployOptions {
project: string;
token: string;
cwd: string;
only?: string;
}

/**
* Changes to these files require redeployment to the project backend.
*/
const projectConfigGroups = [
{ file: 'config/firebase.json', flag: 'all' },
{ file: 'config/firestore.rules', flag: 'firestore' },
{ file: 'config/firestore.indexes.json', flag: 'firestore' },
{ file: 'config/database.rules.json', flag: 'database' },
{ file: 'config/functions/index.js', flag: 'functions' }
];

/**
* Deploy Firebase project config files (functions, rules) to CI
* test project if there have been any changes to them.
*/
async function deployIfNeeded() {
const token = process.env.FIREBASE_CLI_TOKEN;
if (!token) {
throw new Error('No FIREBASE_CLI_TOKEN found, exiting.');
}
const diff = await git.diff(['--name-only', 'origin/master...HEAD']);
const changedFiles = diff.split('\n');
let flags: string[] = [];
for (const group of projectConfigGroups) {
if (changedFiles.includes(group.file)) {
if (group.flag === 'all') {
flags = ['all'];
break;
}
flags.push(group.flag);
}
}
const deployOptions: DeployOptions = {
project: config.projectId,
token,
cwd: resolve(root, 'config')
};
if (flags.length === 0) {
console.log(
chalk`{green No changes detected in project config files. Not deploying. }`
);
return;
}
if (flags[0] !== 'all') {
deployOptions.only = flags.join(',');
console.log(chalk`{blue Deploying to ${flags.toString()} }`);
} else {
console.log(
chalk`{blue firebase.json changed - deploying full config directory. }`
);
}
if (flags[0] === 'all' || flags.includes('functions')) {
// npm install the dependencies for functions
await exec('npm install', {
cwd: resolve(root, 'config/functions')
});
}
await firebaseTools.deploy(deployOptions);
}

deployIfNeeded();