diff --git a/CHANGELOG.md b/CHANGELOG.md index 29b20fd25a6..074bef81184 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,3 +3,4 @@ - Fix bug in auth emulator in which createdAt was not set for signInWithIdp new users. (#5203) - Default to --no-localhost when calling login from Google Cloud Workstations - Support the x-goog-api-key header in auth emulator. (#5249) +- Fix bug where function deployments using --only filter sometimes failed deployments. (#5280) diff --git a/src/deploy/functions/deploy.ts b/src/deploy/functions/deploy.ts index a432dc4caa5..ecdc7b68050 100644 --- a/src/deploy/functions/deploy.ts +++ b/src/deploy/functions/deploy.ts @@ -112,7 +112,7 @@ export async function deploy( await checkHttpIam(context, options, payload); const uploads: Promise[] = []; for (const [codebase, { wantBackend, haveBackend }] of Object.entries(payload.functions)) { - if (shouldUploadBeSkipped(wantBackend, haveBackend)) { + if (shouldUploadBeSkipped(context, wantBackend, haveBackend)) { continue; } uploads.push(uploadCodebase(context, codebase, wantBackend)); @@ -124,9 +124,15 @@ export async function deploy( * @return True IFF wantBackend + haveBackend are the same */ export function shouldUploadBeSkipped( + context: args.Context, wantBackend: backend.Backend, haveBackend: backend.Backend ): boolean { + // If function targets are specified by --only flag, assume that function will be deployed + // and go ahead and upload the source. + if (context.filters && context.filters.length > 0) { + return false; + } const wantEndpoints = backend.allEndpoints(wantBackend); const haveEndpoints = backend.allEndpoints(haveBackend); diff --git a/src/test/deploy/functions/deploy.spec.ts b/src/test/deploy/functions/deploy.spec.ts index 78e3ab5feaa..1fb4e103090 100644 --- a/src/test/deploy/functions/deploy.spec.ts +++ b/src/test/deploy/functions/deploy.spec.ts @@ -1,5 +1,6 @@ import { expect } from "chai"; +import * as args from "../../../deploy/functions/args"; import * as backend from "../../../deploy/functions/backend"; import * as deploy from "../../../deploy/functions/deploy"; @@ -17,6 +18,11 @@ describe("deploy", () => { ...ENDPOINT_BASE, httpsTrigger: {}, }; + + const CONTEXT: args.Context = { + projectId: "project", + }; + describe("shouldUploadBeSkipped", () => { let endpoint1InWantBackend: backend.Endpoint; let endpoint2InWantBackend: backend.Endpoint; @@ -63,7 +69,7 @@ describe("deploy", () => { endpoint2InHaveBackend.hash = endpoint2InWantBackend.hash; // Execute - const result = deploy.shouldUploadBeSkipped(wantBackend, haveBackend); + const result = deploy.shouldUploadBeSkipped(CONTEXT, wantBackend, haveBackend); // Expect expect(result).to.be.true; @@ -76,7 +82,7 @@ describe("deploy", () => { endpoint2InHaveBackend.hash = "No_match"; // Execute - const result = deploy.shouldUploadBeSkipped(wantBackend, haveBackend); + const result = deploy.shouldUploadBeSkipped(CONTEXT, wantBackend, haveBackend); // Expect expect(result).to.be.false; @@ -92,7 +98,7 @@ describe("deploy", () => { haveBackend = backend.of(endpoint1InHaveBackend); // Execute - const result = deploy.shouldUploadBeSkipped(wantBackend, haveBackend); + const result = deploy.shouldUploadBeSkipped(CONTEXT, wantBackend, haveBackend); // Expect expect(result).to.be.false; @@ -108,7 +114,24 @@ describe("deploy", () => { haveBackend = backend.of(endpoint1InHaveBackend, endpoint2InHaveBackend); // Execute - const result = deploy.shouldUploadBeSkipped(wantBackend, haveBackend); + const result = deploy.shouldUploadBeSkipped(CONTEXT, wantBackend, haveBackend); + + // Expect + expect(result).to.be.false; + }); + + it("should not skip if endpoint filter is specified", () => { + endpoint1InWantBackend.hash = "1"; + endpoint2InWantBackend.hash = "2"; + endpoint1InHaveBackend.hash = endpoint1InWantBackend.hash; + endpoint2InHaveBackend.hash = endpoint2InWantBackend.hash; + + // Execute + const result = deploy.shouldUploadBeSkipped( + { ...CONTEXT, filters: [{ idChunks: ["foobar"] }] }, + wantBackend, + haveBackend + ); // Expect expect(result).to.be.false;