Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
282 commits
Select commit Hold shift + click to select a range
9fc0e9d
Merge branch 'bapi_services_update' into bapi_local_builds
falahat Sep 30, 2026
4ee2069
Use Object.prototype.hasOwnProperty.call when checking autoinitVars keys
falahat Sep 30, 2026
26f92e5
Ensure runtime service account has roles/firebase.sdkAdminServiceAgen…
falahat Sep 30, 2026
beea973
Use ternary instead of numeric length in object spreads
falahat Sep 30, 2026
46a8aea
Add defensive optional chaining in run.ts and runv2.ts
falahat Sep 30, 2026
697a3f1
Merge branch 'bapi_gcp_and_shared' into bapi_experiment
falahat Sep 30, 2026
ed37ac2
Merge branch 'bapi_experiment' into bapi_init_run
falahat Sep 30, 2026
601d6b9
Merge branch 'bapi_init_run' into bapi_deploy_run
falahat Sep 30, 2026
bfb2b1b
Merge branch 'bapi_deploy_run' into bapi_services_update
falahat Sep 30, 2026
67c2c7c
Merge branch 'bapi_services_update' into bapi_local_builds
falahat Sep 30, 2026
da303af
Merge branch 'bapi_local_builds' into bapi_sdk_autoinit
falahat Sep 30, 2026
6fe8427
Remove unused Deployable predeploy/postdeploy from RunSingle
falahat Sep 30, 2026
22aea66
Merge branch 'bapi_firebase_json' into bapi_gcp_and_shared
falahat Sep 30, 2026
5632a25
Merge branch 'bapi_gcp_and_shared' into bapi_experiment
falahat Sep 30, 2026
efd2f58
Merge branch 'bapi_experiment' into bapi_init_run
falahat Sep 30, 2026
cc1ed57
Merge branch 'bapi_init_run' into bapi_deploy_run
falahat Sep 30, 2026
2c28eef
Merge branch 'bapi_deploy_run' into bapi_services_update
falahat Sep 30, 2026
79e1d02
Merge branch 'bapi_services_update' into bapi_local_builds
falahat Sep 30, 2026
c33e6e4
Merge branch 'bapi_local_builds' into bapi_sdk_autoinit
falahat Sep 30, 2026
7524ef3
Merge branch 'main' into bapi_firebase_json
falahat Sep 30, 2026
5b2495f
Merge branch 'bapi_firebase_json' into bapi_gcp_and_shared
falahat Sep 30, 2026
339f5f3
Merge branch 'bapi_gcp_and_shared' into bapi_experiment
falahat Sep 30, 2026
699cf07
Merge branch 'bapi_experiment' into bapi_init_run
falahat Sep 30, 2026
3ba264a
Merge branch 'bapi_init_run' into bapi_deploy_run
falahat Sep 30, 2026
1608f73
Merge branch 'bapi_deploy_run' into bapi_services_update
falahat Sep 30, 2026
ea0afd4
Merge branch 'bapi_services_update' into bapi_local_builds
falahat Sep 30, 2026
a25fd1f
Merge branch 'bapi_local_builds' into bapi_sdk_autoinit
falahat Sep 30, 2026
eaaffe1
Create a basic, initial schema for firebase.json
falahat Sep 28, 2026
03f1e55
improve testing
falahat Sep 29, 2026
a729087
Require region, remove serviceAccount, and register run in Config.KNO…
falahat Sep 30, 2026
ee94ae4
Remove unused Deployable predeploy/postdeploy from RunSingle
falahat Sep 30, 2026
5b7a7a6
Update shared GCP clients (runv2, run, artifactregistry)
falahat Sep 30, 2026
c0bbf78
Add direct_cloud_run experiment flag
falahat Sep 30, 2026
466f1a5
Add defensive optional chaining in run.ts and runv2.ts
falahat Sep 30, 2026
e338677
Rename direct_cloud_run experiment to directcloudrun
falahat Sep 30, 2026
789bf04
Add firebase init run interactive setup
falahat Sep 30, 2026
4a26461
Use directcloudrun experiment and validate rootDir is a directory
falahat Sep 30, 2026
dcd5eaf
Trim baseImage input in init run
falahat Sep 30, 2026
195aa47
Add firebase deploy --only run for remote Cloud Build source deploys
falahat Sep 30, 2026
2fa39f7
Clean up temporary source archive, guard release URI, and use directc…
falahat Sep 30, 2026
69ca644
Avoid empty template.annotations when deploy message is unset
falahat Sep 30, 2026
1086ebe
Simplify template.annotations cleanup when deploy message is unset
falahat Sep 30, 2026
bc390c7
Add firebase run:services:update command
falahat Sep 30, 2026
9a8b7ca
Validate service region and check all matching configs in updateService
falahat Sep 30, 2026
113c80b
Merge branch 'bapi_services_update' into bapi_local_builds
falahat Sep 30, 2026
04723bf
Merge branch 'bapi_local_builds' into bapi_sdk_autoinit
falahat Sep 30, 2026
76388ef
Merge branch 'bapi_init_run' into bapi_deploy_run
falahat Sep 30, 2026
47e179b
Merge branch 'main' into bapi_gcp_and_shared
falahat Sep 30, 2026
9702b99
Merge branch 'bapi_gcp_and_shared' into bapi_experiment
falahat Sep 30, 2026
bd8fa33
Merge branch 'bapi_experiment' into bapi_init_run
falahat Sep 30, 2026
9491467
Merge branch 'bapi_deploy_run' into bapi_services_update
falahat Sep 30, 2026
b0b3e6f
Merge branch 'bapi_services_update' into bapi_local_builds
falahat Sep 30, 2026
879df20
Merge branch 'bapi_local_builds' into bapi_sdk_autoinit
falahat Sep 30, 2026
95442b6
Merge branch 'bapi_init_run' into bapi_deploy_run
falahat Oct 2, 2026
f0b1a7b
Rename masterTimeout option to pollTimeoutMs in runv2
falahat Oct 2, 2026
682c0fd
Merge branch 'bapi_gcp_and_shared' into bapi_experiment
falahat Oct 2, 2026
9079261
Merge branch 'bapi_experiment' into bapi_init_run
falahat Oct 2, 2026
51e7568
Use pollTimeoutMs option when creating and updating Cloud Run services
falahat Oct 2, 2026
506c7ab
Merge branch 'bapi_deploy_run' into bapi_services_update
falahat Oct 2, 2026
87edcae
Merge branch 'bapi_services_update' into bapi_local_builds
falahat Oct 2, 2026
e47a2d7
Merge branch 'bapi_local_builds' into bapi_sdk_autoinit
falahat Oct 2, 2026
6a3ec2d
Make updateMask fallback in updateService more readable
falahat Oct 2, 2026
67f2201
Merge branch 'bapi_gcp_and_shared' into bapi_experiment
falahat Oct 2, 2026
33ee8f8
Merge branch 'bapi_experiment' into bapi_init_run
falahat Oct 2, 2026
6014ef9
Merge branch 'bapi_init_run' into bapi_deploy_run
falahat Oct 2, 2026
c3abacd
Merge branch 'bapi_deploy_run' into bapi_services_update
falahat Oct 2, 2026
36a7b1d
Merge branch 'bapi_services_update' into bapi_local_builds
falahat Oct 2, 2026
1a31af6
Merge branch 'bapi_local_builds' into bapi_sdk_autoinit
falahat Oct 2, 2026
fbbcb6f
Add comment explaining default updateMask calculation in updateService
falahat Oct 2, 2026
d184a26
Merge branch 'bapi_gcp_and_shared' into bapi_experiment
falahat Oct 2, 2026
4d8e032
Merge branch 'bapi_experiment' into bapi_init_run
falahat Oct 2, 2026
da255cb
Merge branch 'bapi_init_run' into bapi_deploy_run
falahat Oct 2, 2026
c1173dc
Merge branch 'bapi_deploy_run' into bapi_services_update
falahat Oct 2, 2026
db9edb6
Merge branch 'bapi_services_update' into bapi_local_builds
falahat Oct 2, 2026
290bb10
Merge branch 'bapi_local_builds' into bapi_sdk_autoinit
falahat Oct 2, 2026
9c7fa98
Type Service.ingress as IngressTraffic union in runv2
falahat Oct 2, 2026
2dede4d
Merge branch 'bapi_gcp_and_shared' into bapi_experiment
falahat Oct 2, 2026
5a9f1f9
Merge branch 'bapi_experiment' into bapi_init_run
falahat Oct 2, 2026
eb2ba81
Merge branch 'bapi_init_run' into bapi_deploy_run
falahat Oct 2, 2026
0c5de81
Merge branch 'bapi_deploy_run' into bapi_services_update
falahat Oct 2, 2026
f59829a
Merge branch 'bapi_services_update' into bapi_local_builds
falahat Oct 2, 2026
149ee84
Merge branch 'bapi_local_builds' into bapi_sdk_autoinit
falahat Oct 2, 2026
dd2973e
Merge branch 'bapi_experiment' into bapi_init_run
falahat Oct 2, 2026
e83b309
Merge branch 'bapi_init_run' into bapi_deploy_run
falahat Oct 2, 2026
6a79374
Format updateMask call with Prettier and guard template literal in runv2
falahat Oct 2, 2026
b9938fd
Merge branch 'bapi_gcp_and_shared' into bapi_experiment
falahat Oct 2, 2026
0b89918
Merge branch 'bapi_deploy_run' into bapi_services_update
falahat Oct 2, 2026
5ad1cbf
Merge branch 'bapi_services_update' into bapi_local_builds
falahat Oct 2, 2026
b6ae2f2
Merge branch 'bapi_local_builds' into bapi_sdk_autoinit
falahat Oct 2, 2026
d3d1f3a
Fix Policy stub type in prepare.spec.ts
falahat Oct 2, 2026
a4430ad
Improve readability of firebase init run and remove mainContainer
falahat Oct 2, 2026
26f8593
Merge branch 'bapi_init_run' into bapi_deploy_run
falahat Oct 2, 2026
6c8fe1b
Merge branch 'bapi_deploy_run' into bapi_services_update
falahat Oct 2, 2026
1b46515
Merge branch 'bapi_services_update' into bapi_local_builds
falahat Oct 2, 2026
8c86fe6
Merge branch 'bapi_local_builds' into bapi_sdk_autoinit
falahat Oct 2, 2026
2915dea
Remove sidecar container from deploy.spec.ts
falahat Oct 2, 2026
ba8bfb3
Merge branch 'bapi_deploy_run' into bapi_services_update
falahat Oct 2, 2026
dcd78b8
Merge branch 'bapi_services_update' into bapi_local_builds
falahat Oct 2, 2026
18d7e3b
Merge branch 'bapi_local_builds' into bapi_sdk_autoinit
falahat Oct 2, 2026
a621639
Use dirExistsSync from fsutils in init run promptRootDir
falahat Oct 3, 2026
527c4a7
Merge branch 'bapi_init_run' into bapi_deploy_run
falahat Oct 3, 2026
a31877e
Merge branch 'bapi_deploy_run' into bapi_services_update
falahat Oct 3, 2026
e7f9781
Merge branch 'bapi_services_update' into bapi_local_builds
falahat Oct 3, 2026
e46f48d
Merge branch 'bapi_local_builds' into bapi_sdk_autoinit
falahat Oct 3, 2026
2736051
Make Cloud Run temp-file cleanup best-effort
falahat Oct 3, 2026
8609bf1
Merge branch 'bapi_deploy_run' into bapi_services_update
falahat Oct 3, 2026
c319224
Merge branch 'bapi_services_update' into bapi_local_builds
falahat Oct 3, 2026
1bf57bd
Make local build scratch dir cleanup best-effort
falahat Oct 3, 2026
16e92c2
Merge branch 'bapi_local_builds' into bapi_sdk_autoinit
falahat Oct 3, 2026
d122b9e
Fail clearly when SDK autoinit can't be set up, and simplify it
falahat Oct 3, 2026
512f9f2
Always refresh FIREBASE_CONFIG from the linked app
falahat Oct 4, 2026
f5ba7ec
Always rebuild in run:services:update, even if nothing changes
falahat Oct 4, 2026
17c4029
Merge branch 'bapi_services_update' into bapi_local_builds
falahat Oct 4, 2026
5922308
Merge branch 'bapi_local_builds' into bapi_sdk_autoinit
falahat Oct 4, 2026
f0427c9
Always rebuild for --app and --clear-app too
falahat Oct 4, 2026
c3427e8
Don't default to a base image in init run
falahat Oct 7, 2026
bb72584
Merge branch 'bapi_init_run' into bapi_deploy_run
falahat Oct 7, 2026
2d44f6d
Merge branch 'bapi_deploy_run' into bapi_services_update
falahat Oct 7, 2026
6007416
Merge branch 'bapi_services_update' into bapi_local_builds
falahat Oct 7, 2026
4c2b0a4
Merge branch 'bapi_local_builds' into bapi_sdk_autoinit
falahat Oct 7, 2026
b03b4c6
Merge remote-tracking branch 'upstream/main' into bapi_gcp_and_shared
falahat Oct 7, 2026
2be84ca
Merge branch 'bapi_gcp_and_shared' into bapi_experiment
falahat Oct 7, 2026
c66847b
Merge branch 'bapi_experiment' into bapi_init_run
falahat Oct 7, 2026
8a6685f
Merge branch 'bapi_init_run' into bapi_deploy_run
falahat Oct 7, 2026
a606029
Merge branch 'bapi_deploy_run' into bapi_services_update
falahat Oct 7, 2026
11191df
Merge branch 'bapi_services_update' into bapi_local_builds
falahat Oct 7, 2026
40df479
Merge branch 'bapi_local_builds' into bapi_sdk_autoinit
falahat Oct 7, 2026
0dca8f4
Merge remote-tracking branch 'upstream/main' into bapi_gcp_and_shared
falahat Oct 7, 2026
e1dae66
Merge branch 'bapi_gcp_and_shared' into bapi_experiment
falahat Oct 7, 2026
4ad29e0
Merge branch 'bapi_experiment' into bapi_init_run
falahat Oct 7, 2026
1405979
Merge branch 'bapi_init_run' into bapi_deploy_run
falahat Oct 7, 2026
8298790
Merge branch 'bapi_deploy_run' into bapi_services_update
falahat Oct 7, 2026
fb1a25f
Merge branch 'bapi_services_update' into bapi_local_builds
falahat Oct 7, 2026
15df5a6
Merge branch 'bapi_local_builds' into bapi_sdk_autoinit
falahat Oct 7, 2026
11f67e1
Add firebase init run interactive setup
falahat Sep 30, 2026
2c9c06e
Use directcloudrun experiment and validate rootDir is a directory
falahat Sep 30, 2026
bd2ff06
Trim baseImage input in init run
falahat Sep 30, 2026
51cca8b
Improve readability of firebase init run and remove mainContainer
falahat Oct 2, 2026
1ca1eb3
Use dirExistsSync from fsutils in init run promptRootDir
falahat Oct 3, 2026
84f2bba
Don't default to a base image in init run
falahat Oct 7, 2026
74f23b7
Make upsertRunConfig easier to read
falahat Oct 8, 2026
250a602
Merge branch 'bapi_init_run' into bapi_deploy_run
falahat Oct 8, 2026
19a3714
Merge branch 'bapi_deploy_run' into bapi_services_update
falahat Oct 8, 2026
625247c
Merge branch 'bapi_services_update' into bapi_local_builds
falahat Oct 8, 2026
740a142
Merge branch 'bapi_local_builds' into bapi_sdk_autoinit
falahat Oct 8, 2026
ada86a4
Make upsertRunConfig easier to read
falahat Oct 8, 2026
292331f
Merge branch 'bapi_init_run' into bapi_deploy_run
falahat Oct 8, 2026
fdf61f9
Merge branch 'bapi_deploy_run' into bapi_services_update
falahat Oct 8, 2026
6d20249
Merge branch 'bapi_services_update' into bapi_local_builds
falahat Oct 8, 2026
18b92a7
Merge branch 'bapi_local_builds' into bapi_sdk_autoinit
falahat Oct 8, 2026
54e9f05
Don't add an ignore list to an existing service in init run
falahat Oct 8, 2026
5167ae7
Merge branch 'bapi_init_run' into bapi_deploy_run
falahat Oct 8, 2026
cb5ec4b
Merge branch 'bapi_deploy_run' into bapi_services_update
falahat Oct 8, 2026
9a9613f
Merge branch 'bapi_services_update' into bapi_local_builds
falahat Oct 8, 2026
e03ec89
Merge branch 'bapi_local_builds' into bapi_sdk_autoinit
falahat Oct 8, 2026
4a117cb
Default init run's root directory to the saved one, matching by servi…
falahat Oct 8, 2026
249478b
Merge branch 'bapi_init_run' into bapi_deploy_run
falahat Oct 8, 2026
9ce5cf5
Merge branch 'bapi_deploy_run' into bapi_services_update
falahat Oct 8, 2026
58bbeff
Merge branch 'bapi_services_update' into bapi_local_builds
falahat Oct 8, 2026
5ee1358
Default init run's build location to the saved localBuild setting
falahat Oct 8, 2026
13b7684
Merge branch 'bapi_local_builds' into bapi_sdk_autoinit
falahat Oct 8, 2026
136598a
Only deploy the service init set up, not same-ID services in other re…
falahat Oct 8, 2026
40958c9
Merge branch 'bapi_deploy_run' into bapi_services_update
falahat Oct 8, 2026
eeac006
Merge branch 'bapi_services_update' into bapi_local_builds
falahat Oct 8, 2026
8a4199a
Merge branch 'bapi_local_builds' into bapi_sdk_autoinit
falahat Oct 8, 2026
c4a99e1
Write firebase.json once, from init, instead of also from init run's …
falahat Oct 8, 2026
5794e91
Merge branch 'bapi_init_run' into bapi_deploy_run
falahat Oct 8, 2026
ae700c3
Merge branch 'bapi_deploy_run' into bapi_services_update
falahat Oct 8, 2026
4501ba7
Merge branch 'bapi_services_update' into bapi_local_builds
falahat Oct 8, 2026
7a7a91a
Merge branch 'bapi_local_builds' into bapi_sdk_autoinit
falahat Oct 8, 2026
ee2298f
Merge remote-tracking branch 'upstream/main' into bapi_init_run
falahat Oct 8, 2026
4e07d95
Merge branch 'bapi_init_run' into bapi_deploy_run
falahat Oct 8, 2026
e4ed51b
Merge branch 'bapi_deploy_run' into bapi_services_update
falahat Oct 8, 2026
fbd2a8f
Merge branch 'bapi_services_update' into bapi_local_builds
falahat Oct 8, 2026
8df8747
Merge branch 'bapi_local_builds' into bapi_sdk_autoinit
falahat Oct 8, 2026
d46821e
Remove the Cloud Run deploy E2E suite
falahat Oct 8, 2026
bbdc425
Merge remote-tracking branch 'upstream/main' into bapi_deploy_run
falahat Oct 8, 2026
bfec6c1
Merge branch 'bapi_deploy_run' into bapi_services_update
falahat Oct 8, 2026
6bfd112
Merge branch 'bapi_services_update' into bapi_local_builds
falahat Oct 8, 2026
712c8e2
Merge branch 'bapi_local_builds' into bapi_sdk_autoinit
falahat Oct 8, 2026
f2df542
Let --only run:<serviceId>:<region> pick one Cloud Run service
falahat Oct 8, 2026
89c4216
Merge branch 'bapi_deploy_run' into bapi_services_update
falahat Oct 8, 2026
4037b81
Make run:services:update change exactly one service
falahat Oct 8, 2026
5924af4
Merge branch 'bapi_services_update' into bapi_local_builds
falahat Oct 8, 2026
dd4d1cc
Merge branch 'bapi_local_builds' into bapi_sdk_autoinit
falahat Oct 8, 2026
83e319f
Make the Cloud Run deploy code and tests easier to read
falahat Oct 9, 2026
e9ddc33
Merge branch 'bapi_deploy_run' into bapi_services_update
falahat Oct 9, 2026
272a9e2
Merge branch 'bapi_services_update' into bapi_local_builds
falahat Oct 9, 2026
fc83bab
Merge branch 'bapi_local_builds' into bapi_sdk_autoinit
falahat Oct 9, 2026
84494af
Make run:services:update easier to read
falahat Oct 9, 2026
ca5c791
Merge branch 'bapi_services_update' into bapi_local_builds
falahat Oct 9, 2026
ac7deb7
Move build env to its own PR
falahat Oct 9, 2026
276b076
Make local builds easier to read
falahat Oct 9, 2026
fd2a3de
Keep localBuild's options on one line
falahat Oct 9, 2026
e39e372
Support build-time env vars and secrets for Cloud Run
falahat Oct 9, 2026
d575126
Merge branch 'bapi_build_env' into bapi_sdk_autoinit
falahat Oct 9, 2026
6666aa1
Make the build env tests easier to read
falahat Oct 9, 2026
f9b0ab7
Make the local build tests easier to read
falahat Oct 9, 2026
663a82a
Merge branch 'bapi_local_builds' into bapi_build_env
falahat Oct 9, 2026
0a39c64
Make the SDK auto-init tests easier to read
falahat Oct 9, 2026
4d1a888
Merge branch 'bapi_build_env' into bapi_sdk_autoinit
falahat Oct 9, 2026
716c4fd
Address review comments on the Cloud Run deploy
falahat Oct 12, 2026
fb87b8f
Merge branch 'bapi_deploy_run' into bapi_services_update
falahat Oct 12, 2026
5f410b5
Merge branch 'bapi_services_update' into bapi_local_builds
falahat Oct 12, 2026
e83ea5c
Merge branch 'bapi_local_builds' into bapi_build_env
falahat Oct 12, 2026
80dd07d
Merge branch 'bapi_build_env' into bapi_sdk_autoinit
falahat Oct 12, 2026
e00f403
Merge remote-tracking branch 'upstream/main' into bapi_deploy_run
falahat Oct 12, 2026
5423457
Merge branch 'bapi_deploy_run' into bapi_services_update
falahat Oct 12, 2026
67bf761
Merge branch 'bapi_services_update' into bapi_local_builds
falahat Oct 12, 2026
b014a4f
Merge branch 'bapi_local_builds' into bapi_build_env
falahat Oct 12, 2026
f597da1
Merge branch 'bapi_build_env' into bapi_sdk_autoinit
falahat Oct 12, 2026
1e3accb
Split run:services:update's service name into serviceId and region
falahat Oct 12, 2026
f0c99c0
Merge branch 'bapi_services_update' into bapi_local_builds
falahat Oct 12, 2026
99519f9
Merge branch 'bapi_local_builds' into bapi_build_env
falahat Oct 12, 2026
3433888
Merge branch 'bapi_build_env' into bapi_sdk_autoinit
falahat Oct 12, 2026
675082b
Say which deploy step sets each ServiceDeploy field
falahat Oct 12, 2026
fe7831e
Merge branch 'bapi_deploy_run' into bapi_services_update
falahat Oct 12, 2026
c379f76
Merge branch 'bapi_services_update' into bapi_local_builds
falahat Oct 12, 2026
f7b5a17
Split Cloud Run deploys into remote and local build paths
falahat Oct 12, 2026
a292c19
Merge branch 'bapi_local_builds' into bapi_build_env
falahat Oct 12, 2026
cca27d7
Merge branch 'bapi_build_env' into bapi_sdk_autoinit
falahat Oct 12, 2026
de55cf2
Merge branch 'bapi_local_builds' into bapi_build_env
falahat Oct 12, 2026
d14bf85
Merge branch 'bapi_build_env' into bapi_sdk_autoinit
falahat Oct 12, 2026
da44ccb
Let a local build's env vars replace the service's values
falahat Oct 12, 2026
cea325c
Use App Hosting's secret format for build secrets
falahat Oct 13, 2026
efdf790
Merge branch 'bapi_build_env' into bapi_sdk_autoinit
falahat Oct 13, 2026
24171b5
Rename plainValues to nonSecretValues
falahat Oct 13, 2026
8eeabfa
Merge branch 'bapi_build_env' into bapi_sdk_autoinit
falahat Oct 13, 2026
6084c5c
Merge remote-tracking branch 'upstream/main' into bapi_deploy_run
falahat Oct 13, 2026
8684afe
Merge branch 'bapi_deploy_run' into bapi_services_update
falahat Oct 13, 2026
0b740f7
Merge branch 'bapi_services_update' into bapi_local_builds
falahat Oct 13, 2026
fa68a23
Merge branch 'bapi_local_builds' into bapi_build_env
falahat Oct 13, 2026
6b149f3
Merge branch 'bapi_build_env' into bapi_sdk_autoinit
falahat Oct 13, 2026
c84fca1
Accept numbers and booleans in the build env annotation, like apphost…
falahat Oct 13, 2026
3eaaf14
Merge branch 'bapi_build_env' into bapi_sdk_autoinit
falahat Oct 13, 2026
b4b4cb3
Check for secrets with isSecretRef instead of typeof string
falahat Oct 13, 2026
1c96a48
Merge branch 'bapi_build_env' into bapi_sdk_autoinit
falahat Oct 13, 2026
881e106
Merge remote-tracking branch 'upstream/main' into bapi_sdk_autoinit
falahat Oct 14, 2026
67a028a
Make the FIREBASE_CONFIG and annotation logic in deploy easier to follow
falahat Oct 14, 2026
8443369
Rename serviceAnnotations to serviceAnnotationsToDeploy
falahat Oct 14, 2026
d1257fa
Fail the deploy if the linked Firebase Web App doesn't exist
falahat Oct 14, 2026
29234ba
Group the linked app's ID and config into ServiceDeploy.autoInit
falahat Oct 15, 2026
0944242
init run: ask which web app to link, and create a new one only in act…
falahat Oct 15, 2026
cfd8c7c
Stop granting roles/firebase.sdkAdminServiceAgent; print the grant co…
falahat Oct 15, 2026
a2910d8
init run: fail instead of deploying unlinked when the web app can't b…
falahat Oct 16, 2026
32b86e7
Add a TODO for handing runtime FIREBASE_CONFIG to Cloud Run
falahat Oct 16, 2026
f357f9d
Shorten the runtime FIREBASE_CONFIG TODO
falahat Oct 16, 2026
59332d4
Reword the FIREBASE_CONFIG TODO to match the agreed behavior
falahat Oct 16, 2026
880c458
Always use the linked app's config at build time too
falahat Oct 16, 2026
859f133
Merge remote-tracking branch 'upstream/main' into bapi_sdk_autoinit
falahat Oct 16, 2026
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
2 changes: 2 additions & 0 deletions src/commands/run-services-update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ export const command = new Command("run:services:update <serviceId>")
"set the base image (e.g. nodejs22) and enable automatic base image updates",
)
.option("--clear-base-image", "clear the base image and disable automatic base image updates")
.option("--app <appId>", "associate a Firebase Web App ID for SDK auto-initialization")
.option("--clear-app", "disassociate the Firebase Web App and disable SDK auto-initialization")
.before(requireConfig)
.before(requirePermissions, TARGET_PERMISSIONS.run)
.action((serviceId: string, options: Options) =>
Expand Down
2 changes: 2 additions & 0 deletions src/deploy/apphosting/prepare.ts
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,8 @@ export async function injectAutoInitEnvVars(
)) as WebConfig;

// We inject autoinit env vars into the build and runtime env vars.
// TODO: Match FAH remote builds by only injecting FIREBASE_CONFIG (and not
// FIREBASE_WEBAPP_CONFIG) into runtimeEnv.
const autoinitVars = getAutoinitEnvVars(webappConfig);
for (const [envVarName, envVarValue] of Object.entries(autoinitVars)) {
buildEnv[cfg.backendId][envVarName] ??= { value: envVarValue };
Expand Down
8 changes: 8 additions & 0 deletions src/deploy/run/args.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ export interface ServiceDeploy {
* this deploy sets or clears it. Undefined means none, so automatic base image updates are off.
*/
baseImage?: string;
/**
* Set by prepare: the linked Firebase Web App, if any. Deploy saves `appId` on the service so
* later deploys reuse it, and sets `firebaseConfig` as the FIREBASE_CONFIG env var, which the
* Admin SDK reads at runtime.
*/
autoInit?: { appId: string; firebaseConfig: string };
/**
* Set by prepare: the build-time env vars from the service's annotation, each a plain value or
* a secret. Only local builds can use secrets: builds on Cloud Build only take plain values.
Expand All @@ -33,4 +39,6 @@ export interface Context {
projectId: string;
/** Overrides the service's base image. null clears it; undefined keeps the current one. */
baseImage?: string | null;
/** Overrides the service's Firebase Web App ID. null clears it; undefined keeps the current one. */
appId?: string | null;
}
100 changes: 99 additions & 1 deletion src/deploy/run/deploy.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

const NODEJS22 = "us-central1-docker.pkg.dev/serverless-runtimes/google-22/runtimes/nodejs22";
const DEPLOY_MESSAGE = "firebase.google.com/deploy-message";
const APP_ID = "firebase.google.com/app-id";

describe("run deploy", () => {
const options = { config: { projectDir: "/project" } } as unknown as Options;
Expand Down Expand Up @@ -76,7 +77,7 @@
await deployOne({ config: web });

// Without a base image, Cloud Build can't turn on automatic base image updates.
const { buildpackBuild } = submitBuildStub.firstCall.args[2];

Check warning on line 80 in src/deploy/run/deploy.spec.ts

View workflow job for this annotation

GitHub Actions / lint (24)

Unsafe assignment of an `any` value
expect(buildpackBuild).not.to.have.property("baseImage");
expect(buildpackBuild).not.to.have.property("enableAutomaticUpdates");
});
Expand All @@ -86,7 +87,7 @@

await deployOne({ config: web, buildEnv });

const { environmentVariables } = submitBuildStub.firstCall.args[2].buildpackBuild;

Check warning on line 90 in src/deploy/run/deploy.spec.ts

View workflow job for this annotation

GitHub Actions / lint (24)

Unsafe member access .buildpackBuild on an `any` value

Check warning on line 90 in src/deploy/run/deploy.spec.ts

View workflow job for this annotation

GitHub Actions / lint (24)

Unsafe assignment of an `any` value
expect(environmentVariables).to.include({ API_URL: "https://api.example.com" });
expect(environmentVariables).not.to.have.property("NPM_TOKEN");
});
Expand All @@ -112,16 +113,65 @@
expect(updateServiceStub).to.have.been.calledOnceWithExactly(
{
name: "projects/my-project/locations/us-central1/services/web",
annotations: {},
template: { containers: [{ name: "web", image }] },
traffic: [
{ type: "TRAFFIC_TARGET_ALLOCATION_TYPE_LATEST", percent: 100 },
{ type: "TRAFFIC_TARGET_ALLOCATION_TYPE_REVISION", revision: "web-000", tag: "preview" },
],
},
{ updateMask: ["template", "traffic"], pollTimeoutMs: 10 * 60 * 1000 },
{ updateMask: ["template", "traffic", "annotations"], pollTimeoutMs: 10 * 60 * 1000 },
);
});

describe("linked Firebase Web App", () => {
const linkedWeb = {
name: "projects/my-project/locations/us-central1/services/web",
annotations: { team: "frontend", [APP_ID]: "1:123:web:abc" },
template: { containers: [{ name: "web", image: "old-image" }] },
} as unknown as runv2.Service;

it("is saved on a new service", async () => {
await deployOne({ config: web, autoInit: { appId: "1:123:web:abc", firebaseConfig: "{}" } });

expect(createServiceStub).to.have.been.calledWithMatch("my-project", "us-central1", "web", {
annotations: { [APP_ID]: "1:123:web:abc" },
});
});

it("replaces the app saved on an existing service", async () => {
await deployOne({
config: web,
existing: linkedWeb,
autoInit: { appId: "1:123:web:def", firebaseConfig: "{}" },
});

expect(updateServiceStub).to.have.been.calledWithMatch(
{ annotations: { team: "frontend", [APP_ID]: "1:123:web:def" } },
{ updateMask: ["template", "traffic", "annotations"] },
);
});

it("is removed when the service is unlinked", async () => {
await deployOne({ config: web, existing: linkedWeb });

expect(updateServiceStub.firstCall.args[0].annotations).to.deep.equal({ team: "frontend" });

Check warning on line 158 in src/deploy/run/deploy.spec.ts

View workflow job for this annotation

GitHub Actions / lint (24)

Unsafe member access .annotations on an `any` value
});

it("keeps the service's annotations as they are if the app didn't change", async () => {
await deployOne({
config: web,
existing: linkedWeb,
autoInit: { appId: "1:123:web:abc", firebaseConfig: "{}" },
});

expect(updateServiceStub.firstCall.args[0].annotations).to.deep.equal({

Check warning on line 168 in src/deploy/run/deploy.spec.ts

View workflow job for this annotation

GitHub Actions / lint (24)

Unsafe member access .annotations on an `any` value
team: "frontend",
[APP_ID]: "1:123:web:abc",
});
});
});

describe("local builds", () => {
const localWeb = { ...web, localBuild: true };
let rmSyncStub: sinon.SinonStub;
Expand Down Expand Up @@ -149,7 +199,7 @@
/** Deploys web with "localBuild": true and returns the container that it rolled out. */
async function deployLocalBuild(): Promise<runv2.Container> {
await deployOne({ config: localWeb, baseImage: NODEJS22 });
return createServiceStub.firstCall.args[3].template.containers[0];

Check warning on line 202 in src/deploy/run/deploy.spec.ts

View workflow job for this annotation

GitHub Actions / lint (24)

Unsafe member access .template on an `any` value

Check warning on line 202 in src/deploy/run/deploy.spec.ts

View workflow job for this annotation

GitHub Actions / lint (24)

Unsafe return of an `any` typed value
}

it("builds on this machine, in a scratch folder that it deletes afterwards", async () => {
Expand Down Expand Up @@ -308,6 +358,54 @@
expect(template).to.deep.equal({ containers: [{ name: "web", image }] });
});

describe("FIREBASE_CONFIG", () => {
/** The live web service, with FIREBASE_CONFIG set to `value`. */
function withConfig(value: string): runv2.Service {
return webRunning({ env: [{ name: "FIREBASE_CONFIG", value }] });
}
const linked = { ...withConfig("old"), annotations: { [APP_ID]: "1:123:web:abc" } };

it("is set from the linked app's current config", () => {
const svc = {
config: web,
existing: linked,
autoInit: { appId: "1:123:web:abc", firebaseConfig: "current" },
};

const template = revisionTemplate(svc, image);

expect(template.containers?.[0].env).to.deep.equal([
{ name: "FIREBASE_CONFIG", value: "current" },
]);
});

it("is removed when the app is unlinked, and the other env vars stay", () => {
const existing = {
...webRunning({
env: [
{ name: "MODE", value: "prod" },
{ name: "FIREBASE_CONFIG", value: "old" },
],
}),
annotations: { [APP_ID]: "1:123:web:abc" },
};

const template = revisionTemplate({ config: web, existing }, image);

expect(template.containers?.[0].env).to.deep.equal([{ name: "MODE", value: "prod" }]);
});

it("is left alone if the user set it on a service that was never linked", () => {
const svc = { config: web, existing: withConfig("mine") };

const template = revisionTemplate(svc, image);

expect(template.containers?.[0].env).to.deep.equal([
{ name: "FIREBASE_CONFIG", value: "mine" },
]);
});
});

describe("localBuildTemplate", () => {
it("runs a local build's output with the build's start command", () => {
// The command is split on whitespace, so stray spaces don't become empty arguments.
Expand Down
82 changes: 57 additions & 25 deletions src/deploy/run/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import { createLocalBuildTarArchive, createSourceDeployArchive } from "../apphosting/util";
Comment thread
falahat marked this conversation as resolved.
import { Context, Payload, ServiceDeploy } from "./args";
import { nonSecretValues, secretNames, toLocalBuildEnv } from "./buildEnv";
import { mainContainer } from "./util";
import { FIREBASE_APP_ANNOTATION, mainContainer } from "./util";

const DEPLOY_MESSAGE_ANNOTATION = "firebase.google.com/deploy-message";
/** Rolling out a revision can take longer than the operation poller's default timeout. */
Expand Down Expand Up @@ -128,7 +128,7 @@
e.value !== undefined &&
(!e.availability || e.availability.includes("RUNTIME")),
)
.map((e) => ({ name: e.variable, value: e.value! }));

Check warning on line 131 in src/deploy/run/deploy.ts

View workflow job for this annotation

GitHub Actions / lint (24)

Forbidden non-null assertion
return { outputFiles, runCommand: buildConfig.runCommand, env };
}

Expand Down Expand Up @@ -265,6 +265,21 @@
} else {
delete container.baseImageUri;
}
// FIREBASE_CONFIG is how the Admin SDK auto-initializes at runtime. The client SDK's
// FIREBASE_WEBAPP_CONFIG is only needed at build time, so it isn't set on the container.
// TODO: Stop setting FIREBASE_CONFIG once Cloud Run injects it from the app-id annotation.
const wasLinked = svc.existing?.annotations?.[FIREBASE_APP_ANNOTATION] !== undefined;
const otherEnv = (container.env || []).filter((e) => e.name !== "FIREBASE_CONFIG");
if (svc.autoInit) {
// An app is linked. Always rewrite FIREBASE_CONFIG from the app's current config, so that
// changes like enabling Storage reach the service.
container.env = [...otherEnv, { name: "FIREBASE_CONFIG", value: svc.autoInit.firebaseConfig }];
} else if (wasLinked) {
// This deploy unlinks the app (--clear-app): the service had an app, and the deploy has none.
// Remove the FIREBASE_CONFIG that was set for the app.
container.env = otherEnv;
}
// Otherwise the service was never linked, so a FIREBASE_CONFIG on it is the user's. It stays.
// The message describes this deploy only, so don't carry over the last one.
if (message) {
template.annotations = { ...template.annotations, [DEPLOY_MESSAGE_ANNOTATION]: message };
Expand All @@ -287,7 +302,7 @@
): runv2.RevisionTemplate {
const template = revisionTemplate(svc, NO_IMAGE, message);
// revisionTemplate has already checked that there's a container.
const container = mainContainer(template)!;

Check warning on line 305 in src/deploy/run/deploy.ts

View workflow job for this annotation

GitHub Actions / lint (24)

Forbidden non-null assertion
container.sourceCode = { cloudStorageSource: builtApp };
// Split on any whitespace, so that stray spaces don't become empty arguments.
const command = build.runCommand?.trim();
Expand All @@ -309,58 +324,75 @@
return template;
}

/**
* Returns the service's annotations after this deploy: its current ones, with the linked Firebase
* Web App's ID set, or removed if no app is linked. Later deploys read the ID back to reuse the app.
*/
Comment thread
falahat marked this conversation as resolved.
function serviceAnnotationsToDeploy(svc: ServiceDeploy): Record<string, string> {
const annotations = { ...svc.existing?.annotations };
if (svc.autoInit) {
annotations[FIREBASE_APP_ANNOTATION] = svc.autoInit.appId;
} else {
delete annotations[FIREBASE_APP_ANNOTATION];
}
return annotations;
}

/** Rolls out the new revision: creates the service if it's new, or updates it. */
function rollOut(
projectId: string,
svc: ServiceDeploy,
template: runv2.RevisionTemplate,
): Promise<runv2.Service> {
const annotations = serviceAnnotationsToDeploy(svc);
if (svc.existing) {
return deployRevision(svc.existing, template);
return deployRevision(svc.existing, template, annotations);
}
return createNewService(projectId, svc.config, template);
return createNewService(projectId, svc.config, template, annotations);
}

/** Creates a new service with its first revision. */
function createNewService(
projectId: string,
config: RunSingle,
template: runv2.RevisionTemplate,
annotations: Record<string, string>,
): Promise<runv2.Service> {
const { serviceId, region } = config;
return runv2.createService(
projectId,
region,
serviceId,
{
name: `projects/${projectId}/locations/${region}/services/${serviceId}`,
template,
client: "cli-firebase",
// Like an App Hosting backend, the service is public.
invokerIamDisabled: true,
ingress: "INGRESS_TRAFFIC_ALL",
},
{ pollTimeoutMs: ROLLOUT_TIMEOUT_MS },
);
const service: Omit<runv2.Service, runv2.ServiceOutputFields> = {
name: `projects/${projectId}/locations/${region}/services/${serviceId}`,
annotations,
template,
client: "cli-firebase",
// Like an App Hosting backend, the service is public.
invokerIamDisabled: true,
ingress: "INGRESS_TRAFFIC_ALL",
};
return runv2.createService(projectId, region, serviceId, service, {
pollTimeoutMs: ROLLOUT_TIMEOUT_MS,
});
}

/** Rolls out a new revision of an existing service and sends it all traffic. */
function deployRevision(
service: runv2.Service,
template: runv2.RevisionTemplate,
annotations: Record<string, string>,
): Promise<runv2.Service> {
// Tagged revisions keep their tags (Hosting's pinned rewrites use them), but no traffic.
const tags = (service.traffic || [])
.filter((t) => t.tag)
.map((t) => ({ type: t.type, revision: t.revision, tag: t.tag }));
return runv2.updateService(
{
name: service.name,
template,
traffic: [{ type: "TRAFFIC_TARGET_ALLOCATION_TYPE_LATEST", percent: 100 }, ...tags],
},
{ updateMask: ["template", "traffic"], pollTimeoutMs: ROLLOUT_TIMEOUT_MS },
);
const update: Omit<runv2.Service, runv2.ServiceOutputFields> = {
name: service.name,
annotations,
template,
traffic: [{ type: "TRAFFIC_TARGET_ALLOCATION_TYPE_LATEST", percent: 100 }, ...tags],
};
return runv2.updateService(update, {
updateMask: ["template", "traffic", "annotations"],
pollTimeoutMs: ROLLOUT_TIMEOUT_MS,
});
}

/** Adapts a Cloud Run config so that it can reuse App Hosting's local build and archive helpers. */
Expand Down
Loading
Loading