Skip to content

Commit a26c3d0

Browse files
inlinedjoehan
andauthoredMar 26, 2024··
Ignore quota project in GCF source uploads (#6917)
* Ignore quota project in GCF source uploads * Changelog * Remove superfluous change * format + fix tests --------- Co-authored-by: Joe Hanley <joehanley@google.com>
1 parent 476bd33 commit a26c3d0

File tree

5 files changed

+53
-6
lines changed

5 files changed

+53
-6
lines changed
 

‎CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
- Released Firestore Emulator 1.19.4. This version fixes a minor bug with reserve ids and adds a `reset` endpoint for Datastore Mode.
22
- Released PubSub Emulator 0.8.2. This version includes support for `no_wrapper` options.
33
- Fixes issue where GitHub actions service account cannot add preview URLs to Auth authorized domains. (#6895)
4+
- Fixes issue where GOOGLE_CLOUD_QUOTA_PROJECT breaks functions source uploads (#6917)

‎src/apiv2.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ interface BaseRequestOptions<T> extends VerbOptions {
3232
responseType?: "json" | "stream" | "xml";
3333
redirect?: "error" | "follow" | "manual";
3434
compress?: boolean;
35+
ignoreQuotaProject?: boolean;
3536
}
3637

3738
interface RequestOptionsWithSignal<T> extends BaseRequestOptions<T> {
@@ -268,7 +269,11 @@ export class Client {
268269
reqOptions.headers.set("Content-Type", "application/json");
269270
}
270271
}
271-
if (GOOGLE_CLOUD_QUOTA_PROJECT && GOOGLE_CLOUD_QUOTA_PROJECT !== "") {
272+
if (
273+
!reqOptions.ignoreQuotaProject &&
274+
GOOGLE_CLOUD_QUOTA_PROJECT &&
275+
GOOGLE_CLOUD_QUOTA_PROJECT !== ""
276+
) {
272277
reqOptions.headers.set(GOOG_USER_PROJECT_HEADER, GOOGLE_CLOUD_QUOTA_PROJECT);
273278
}
274279
return reqOptions;

‎src/deploy/functions/deploy.ts

+22-5
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import * as clc from "colorette";
33
import * as fs from "fs";
44

55
import { checkHttpIam } from "./checkIam";
6-
import { logSuccess, logWarning } from "../../utils";
6+
import { logLabeledWarning, logSuccess, logWarning } from "../../utils";
77
import { Options } from "../../options";
88
import { configForCodebase } from "../../functions/projectConfig";
99
import * as args from "./args";
@@ -30,9 +30,20 @@ async function uploadSourceV1(
3030
file: source.functionsSourceV1!,
3131
stream: fs.createReadStream(source.functionsSourceV1!),
3232
};
33-
await gcs.upload(uploadOpts, uploadUrl, {
34-
"x-goog-content-length-range": "0,104857600",
35-
});
33+
if (process.env.GOOGLE_CLOUD_QUOTA_PROJECT) {
34+
logLabeledWarning(
35+
"functions",
36+
"GOOGLE_CLOUD_QUTOA_PROJECT is not usable when uploading source for Cloud Functions.",
37+
);
38+
}
39+
await gcs.upload(
40+
uploadOpts,
41+
uploadUrl,
42+
{
43+
"x-goog-content-length-range": "0,104857600",
44+
},
45+
true, // ignoreQuotaProject
46+
);
3647
return uploadUrl;
3748
}
3849

@@ -51,7 +62,13 @@ async function uploadSourceV2(
5162
file: source.functionsSourceV2!,
5263
stream: fs.createReadStream(source.functionsSourceV2!),
5364
};
54-
await gcs.upload(uploadOpts, res.uploadUrl);
65+
if (process.env.GOOGLE_CLOUD_QUOTA_PROJECT) {
66+
logLabeledWarning(
67+
"functions",
68+
"GOOGLE_CLOUD_QUTOA_PROJECT is not usable when uploading source for Cloud Functions.",
69+
);
70+
}
71+
await gcs.upload(uploadOpts, res.uploadUrl, undefined, true /* ignoreQuotaProject */);
5572
return res.storageSource;
5673
}
5774

‎src/gcp/storage.ts

+2
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ export async function upload(
182182
source: any,
183183
uploadUrl: string,
184184
extraHeaders?: Record<string, string>,
185+
ignoreQuotaProject?: boolean,
185186
): Promise<any> {
186187
const url = new URL(uploadUrl);
187188
const localAPIClient = new Client({ urlPrefix: url.origin, auth: false });
@@ -196,6 +197,7 @@ export async function upload(
196197
},
197198
body: source.stream,
198199
skipLog: { resBody: true },
200+
ignoreQuotaProject,
199201
});
200202
return {
201203
generation: res.response.headers.get("x-goog-generation"),

‎src/test/apiv2.spec.ts

+22
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,28 @@ describe("apiv2", () => {
324324
expect(nock.isDone()).to.be.true;
325325
});
326326

327+
it("should allow explicitly ignoring GOOGLE_CLOUD_QUOTA_PROJECT", async () => {
328+
nock("https://example.com")
329+
.get("/path/to/foo")
330+
.reply(function (this: nock.ReplyFnContext): nock.ReplyFnResult {
331+
expect(this.req.headers["x-goog-user-project"]).is.undefined;
332+
return [200, { success: true }];
333+
});
334+
const prev = process.env["GOOGLE_CLOUD_QUOTA_PROJECT"];
335+
process.env["GOOGLE_CLOUD_QUOTA_PROJECT"] = "unit tests, silly";
336+
337+
const c = new Client({ urlPrefix: "https://example.com" });
338+
const r = await c.request({
339+
method: "GET",
340+
path: "/path/to/foo",
341+
ignoreQuotaProject: true,
342+
});
343+
process.env["GOOGLE_CLOUD_QUOTA_PROJECT"] = prev;
344+
345+
expect(r.body).to.deep.equal({ success: true });
346+
expect(nock.isDone()).to.be.true;
347+
});
348+
327349
it("should handle a 204 response with no data", async () => {
328350
nock("https://example.com").get("/path/to/foo").reply(204);
329351

0 commit comments

Comments
 (0)
Please sign in to comment.