Skip to content

Send who requested the build in the metrics payload - #4574

Open
migueldalberto wants to merge 8 commits into
The-OpenROAD-Project:masterfrom
The-OpenROAD-Project-staging:upload-build-requester
Open

migueldalberto wants to merge 8 commits into
The-OpenROAD-Project:masterfrom
The-OpenROAD-Project-staging:upload-build-requester

Conversation

@migueldalberto

@migueldalberto migueldalberto commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

Why

The QoR dashboard wants a "my branches / my builds" view. The only identity it has today is the commit's git author, fetched best-effort from GitHub. That misses builds a user started by hand on someone else's commit, and commits enrichment never reaches.

What

Two optional flags on flow/util/uploadMetadata.py:

Flag Payload key Jenkins source
--buildUserEmail build_user_email BUILD_USER_EMAIL — user who started the build by hand
--changeAuthorEmail change_author_email CHANGE_AUTHOR_EMAIL — PR author on PR builds
  • Sent at the top level on every schema version, including the v1 per-design fallback.
  • Blank values are left out.
  • They describe the build, not the payload's shape, so payload_schema_version is unchanged.
  • Without the flags the payload is byte-for-byte what it was.

jenkins-ci passes them from orfsUploadMetadata, probing for --buildUserEmail support like it does for --provenanceFile, so older ORFS branches keep uploading.

@migueldalberto migueldalberto self-assigned this Sep 28, 2026

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request adds support for capturing build requester information by introducing --buildUserEmail and --changeAuthorEmail command-line arguments to uploadMetadata.py. It includes a helper function resolve_requester to parse and clean these fields, which are then added to the pipeline and per-design payloads. The review feedback suggests two valuable improvements: simplifying the resolve_requester function using a dictionary comprehension for cleaner code, and hoisting the resolve_requester call outside the loop in publish_v1_per_design to prevent redundant executions and improve performance.

Comment thread flow/util/uploadMetadata.py
Comment thread flow/util/uploadMetadata.py Outdated
Adds --buildUserEmail and --changeAuthorEmail to uploadMetadata.py, sent
as the top-level build_user_email and change_author_email keys on every
schema version, v1 per-design fallback included. Blank values are left
out. The dashboard stores them on the build and attributes the build to
the user who started it, so a "my branches" view can include builds a
user started by hand.

They describe the build rather than the payload's shape, so they do not
bump payload_schema_version. The backend must already register them as
metadata before this lands: a v1 message carries metrics at its root, and
an older backend would ingest the keys as metrics.

Signed-off-by: Miguel Dalberto Pedro <miguel.pedro@precisioninno.com>
@openroad-ci
openroad-ci force-pushed the upload-build-requester branch from fcd9748 to 23a2a2c Compare September 28, 2026 23:27
@openroad-ci

openroad-ci commented Sep 29, 2026 •

Copy link
Copy Markdown
Member

🔍 QoR check

Metrics reflect the PR merge build — i.e. what will land on the target branch.

Commit 471ab74 · Jenkins build #9 · Baseline: build · View build on dashboard

62 design(s) checked — 0 with regression(s), 0 without a comparable baseline.

Signed-off-by: Miguel Dalberto Pedro <miguel.pedro@precisioninno.com>

# Conflicts:
#	flow/util/uploadMetadata.py

@vvbandeira vvbandeira left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks. With no flags the payload does not change, and the code looks correct. Some items before merge:

  1. Tests. Please add tests through build_pipeline_payload and publish_v1_per_design: both flags set, one blank or whitespace-only, and both absent. The last case must prove that the payload is the same as before this PR.
  2. Linked changes. Please link the backend change that reads build_user_email / change_author_email and the jenkins-ci orfsUploadMetadata change, so we can check the key names and the case where a key is absent.
  3. Value check. resolve_requester (line 224) accepts any non-blank string. An unset Groovy variable gives the string "null", which would be stored as an email. Please treat null/None as blank, or require an @.
  4. Console log. A Jenkins sh step prints its command with -x, so --buildUserEmail <addr> puts the Jenkins user's email in the build log. Could the script read BUILD_USER_EMAIL / CHANGE_AUTHOR_EMAIL from the environment instead, or could the caller use set +x?
  5. Data access. BUILD_USER_EMAIL can be a private address. Who can read the Pub/Sub topic and the dashboard?
  6. Nit: in publish_v1_per_design, payload.update(requester) runs before payload.update(d["metrics"]), so a metric with the same name would replace it. A comment, or applying the requester keys last, would make this clear.

Heads-up: #4646 conflicts in two places with this PR, so the second one to merge will need a rebase.

@migueldalberto
migueldalberto requested review from vvbandeira and removed request for vvbandeira October 21, 2026 17:11
uploadMetadata.py does its work at import time, so the tests run it as a
subprocess against a temporary reports/ tree, with stub google.cloud
modules recording each published message.

They cover both requester flags set, one blank, and both absent, on the
pipeline payload and on the per-design v1 fallback messages. The absent
case compares the whole payload, which proves that a build without the
flags publishes exactly what it did before the flags existed.

Signed-off-by: Miguel Dalberto Pedro <miguel.pedro@precisioninno.com>
An unset Groovy variable interpolates as the string "null", which
resolve_requester used to accept as an email because it only rejected
blank values. A value without an "@" is now dropped with a warning.

The requester is resolved once in the main flow and passed to both
payload builders. Resolving it inside each builder made the warning
print twice when the pipeline payload exceeded the size cap and the
script fell back to per-design v1 messages.

Signed-off-by: Miguel Dalberto Pedro <miguel.pedro@precisioninno.com>
A Jenkins sh step echoes its command line under sh -x, so passing
--buildUserEmail puts the user's address in the console log. When a
requester flag is absent, the value now comes from UPLOAD_BUILD_USER_EMAIL
or UPLOAD_CHANGE_AUTHOR_EMAIL, so the caller can keep the address out of
the command line.

An empty flag counts as given and suppresses the variable. Values from
the environment go through the same blank and "@" checks as the flags.

Signed-off-by: Miguel Dalberto Pedro <miguel.pedro@precisioninno.com>
A v1 message flattens the metrics onto the message root, so a metric
named like a requester key replaced who asked for the build. The
requester keys now go on last. The pipeline payload nests the metrics
under each design and cannot collide.

Signed-off-by: Miguel Dalberto Pedro <miguel.pedro@precisioninno.com>
Signed-off-by: Miguel Dalberto Pedro <miguel.pedro@precisioninno.com>
Merging master put a REQUESTER_ENV assignment in the middle of
test_v1_fallback_warns_that_design_count_is_dropped and left its
comment unindented, so the black check failed. The test is master's
again, and black also drops the extra blank lines between the new tests.

Signed-off-by: Miguel Dalberto Pedro <miguel.pedro@precisioninno.com>
@migueldalberto

Copy link
Copy Markdown
Contributor Author

Thanks for the review. I pushed fixes in four commits.

  1. Tests. flow/test/test_uploadMetadata.py runs the script against a stub publisher and covers both flags set, one blank, and both absent, on the pipeline payload and on the v1 fallback messages. The absent case compares the whole payload, so it shows a build without the flags publishes what it did before.
  2. Linked changes. The consumer of build_user_email / change_author_email and the Jenkins library change live in private repositories, so I can't link them here. The consumer reads both keys by presence and treats a missing key as "no requester". I'll share the key names and a sample payload with you directly.
  3. Value check. A value without an @ is now dropped with a warning, so the "null" from an unset Groovy variable is never stored. The requester is resolved once and passed to both payload builders, so the warning prints once on the v1 fallback.
  4. Console log. When a flag is absent, the script reads UPLOAD_BUILD_USER_EMAIL / UPLOAD_CHANGE_AUTHOR_EMAIL. An empty flag suppresses the variable. The Jenkins library already exports those names. It still passes the flags today, so the address would reach the log. A follow-up there will stop passing them.
  5. Data access. Only the CI publisher, the consuming service and infrastructure administrators can read the topic. The stored emails are not returned by any API response. They are used server-side to decide whose builds an author filter matches. One open point: that filter is reachable without signing in, so someone who guesses an address can tell whether builds are attributed to it. I'm raising that separately.
  6. Nit. In the v1 messages the requester keys are now applied after the metrics. A test covers a metric with the same name.

Also fixed merge conflicts.

@vvbandeira vvbandeira left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

approved from devops team side

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