Skip to content

fix(dryrun): Run authenticated dryrun queries in mozdata rather than the target project - #9845

Merged
sean-rose merged 2 commits into
mainfrom
fix-dryrun-project
Sep 8, 2026
Merged

fix(dryrun): Run authenticated dryrun queries in mozdata rather than the target project#9845
sean-rose merged 2 commits into
mainfrom
fix-dryrun-project

Conversation

@sean-rose

Copy link
Copy Markdown
Contributor

Description

Because not everyone has permission to run queries in the target projects like moz-fx-data-shared-prod.

Related Tickets & Documents

Reviewer, please follow this checklist

@sean-rose
sean-rose requested a review from a team as a code owner September 4, 2026 21:09
github-actions[bot]

This comment was marked as outdated.

@scholtzan

This comment has been minimized.

Since deploys for targets might use custom service accounts that don't have permission to run queries in `mozdata`.
@scholtzan

Copy link
Copy Markdown
Collaborator

Integration report

@sean-rose

Copy link
Copy Markdown
Contributor Author

@claude what do you think now?

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR splits the dry_run config's default_projects into cloud_function_billing_projects (random pick, cloud-function path) and a new default_billing_project: mozdata for the authenticated path, stops mutating self.client.project in favour of client.query(..., project=...), and — in the follow-up commit — threads an explicit billing_project through the three deploy-path dry runs.

Re: the earlier --target concern, the follow-up commit resolves it. I traced the flow: prepare_target_directory builds sql/<effective_project>/... where effective_project = target.project_id or source_project (bigquery_etl/util/target.py:1130-1138), and project_id is a required field on Target (bigquery_etl/util/target.py:101), so the project component of the copied artifact path is always a real GCP project the sandbox SA can create jobs in. deploy is also the only command that forces use_cloud_function=False for targets (bigquery_etl/cli/deploy.py:497-498), and all three authenticated dry runs reachable from it now pass the artifact's project. The other Schema.from_query_file / Schema.for_table call sites in the deploy flow (bigquery_etl/cli/deploy.py:813, bigquery_etl/cli/deploy.py:834, bigquery_etl/view/__init__.py:216, bigquery_etl/util/target.py:641) all leave use_cloud_function at its True default, so they're unaffected. Client.query treats project=None as "use the client's project", so the None branches are safe, and the default_projects rename has no remaining references in the repo.

Remaining comments are minor and inline.

Comment thread bigquery_etl/dryrun.py
self.dataset = dataset
self.table = table
self.billing_project = billing_project
# if using cloud function and billing project isn't set, randomly select project to use

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: the comment now only describes the use_cloud_function half of the branch it sits above. Suggest something like # if the billing project isn't set, use the configured default (a random cloud function project, or default_billing_project for authenticated dry runs).

tmp_dataset="tmp", # Default dataset for temporary tables during schema updates
tmp_tables={},
use_cloud_function=options["use_cloud_function"],
billing_project=(project_id if not options["use_cloud_function"] else None),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: this (<artifact project> if not use_cloud_function else None) expression is now duplicated at three deploy call sites — here, bigquery_etl/cli/deploy.py:1280, and bigquery_etl/deploy.py:107 — and each derives the project differently (extract_from_query_path here vs. file_path.parent.parent.parent.name in the other two).

Since correct --target behaviour now depends on every authenticated dry run in the deploy path carrying this argument, a future deploy-path dry run that omits it will silently bill to mozdata and 403 for sandbox service accounts. Consider a single helper (e.g. dryrun_billing_project(project, use_cloud_function) in bigquery_etl/dryrun.py) that the three sites call, so the policy lives in one place.

@sean-rose
sean-rose added this pull request to the merge queue Sep 8, 2026
Merged via the queue into main with commit 6c2813c Sep 8, 2026
30 checks passed
@sean-rose
sean-rose deleted the fix-dryrun-project branch September 8, 2026 16:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants