Skip to content

[no-release-notes] update mini sysbench to use kubernetes - #3056

Merged
jycor merged 5 commits into
mainfrom
james/mini
Aug 13, 2026
Merged

[no-release-notes] update mini sysbench to use kubernetes#3056
jycor merged 5 commits into
mainfrom
james/mini

Conversation

@jycor

@jycor jycor commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

No description provided.

@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor
Main PR
Total 42090 42090
Successful 18407 18407
Failures 23683 23683
Partial Successes1 5327 5327
Main PR
Successful 43.7325% 43.7325%
Failures 56.2675% 56.2675%

Footnotes

  1. These are tests that we're marking as Successful, however they do not match the expected output in some way. This is due to small differences, such as different wording on the error messages, or the column names being incorrect while the data itself is correct.

@coffeegoddd

Copy link
Copy Markdown
Contributor

The #benchmark path is already mostly present in this repo, so I don't think mini-sysbench.yml should become an S3 result handler.

The flow we use in dolt is:

  1. performance-benchmarks-pull-report.yaml listens for an issue_comment, validates the commenter / #benchmark, resolves the PR head SHA, and dispatches benchmark-latency.
  2. k8s-benchmark-latency.yaml assumes the GitHub OIDC role and creates the Kubernetes benchmark job.
  3. The Kubernetes job writes its result to performance-benchmarking-github-actions-results and dispatches pull-report.
  4. pull-report.yaml assumes the same OIDC role, downloads the S3 object, and posts it to the PR.

Doltgres already has all three of those workflows, and its benchmark dispatch payload is already correctly Doltgres-specific:

from_server: doltgres
to_server: doltgres
template_script: ./.github/scripts/performance-benchmarking/get-doltgres-doltgres-job-json.sh

Suggested changes for this PR:

  • Keep the validate-commentor.sh allowlist update.
  • Don't add AWS/S3 handling to mini-sysbench.yml. In particular, don't use AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY; those credentials are not the Doltgres CI identity.
  • If the old automatic local mini benchmark is being retired in favor of #benchmark, remove mini-sysbench.yml (or revert its changes) and rely on performance-benchmarks-pull-report.yaml as the entry point.
  • If the goal is to preserve this PR's update-in-place <!-- go-run-output-sysbench --> comment behavior, move that logic into the existing pull-report.yaml instead of creating a second result consumer.
  • Keep S3 auth in pull-report.yaml using the existing OIDC configuration:
permissions:
  id-token: write
  contents: read

- uses: aws-actions/configure-aws-credentials@v4
  with:
    role-session-name: GitHub_to_AWS_via_FederatedOIDC
    role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME_CORP }}
    aws-region: us-west-2

The current mini-sysbench.yml version won't work as written because it is triggered by pull_request but reads github.event.client_payload.bucket, key, issue_number, etc. client_payload only exists on the later repository_dispatch callback. That callback is already handled by pull-report.yaml.

For parity with dolt, it would also be good to update performance-benchmarks-pull-report.yaml from dolthub/pull-request-comment-trigger@master to @v2 and peter-evans/repository-dispatch@v2.0.0 to @v3 while touching this path.

@github-actions

Copy link
Copy Markdown
Contributor

@dolthub dolthub deleted a comment from itoqa Bot Aug 13, 2026
@dolthub dolthub deleted a comment from itoqa Bot Aug 13, 2026
@dolthub dolthub deleted a comment from itoqa Bot Aug 13, 2026

@coffeegoddd coffeegoddd 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.

seems fine to merge and iterate on

@jycor
jycor enabled auto-merge (squash) August 13, 2026 23:09
@jycor
jycor disabled auto-merge August 13, 2026 23:09
@jycor
jycor enabled auto-merge (squash) August 13, 2026 23:10
@jycor jycor changed the title update mini sysbench to use kubernetes [no-release-notes] update mini sysbench to use kubernetes Aug 13, 2026
@jycor
jycor merged commit 55da967 into main Aug 13, 2026
24 checks passed
@jycor
jycor deleted the james/mini branch August 13, 2026 23:14
@itoqa

itoqa Bot commented Aug 13, 2026

Copy link
Copy Markdown

Ito QA test results
Ito Diff Report598850cffc2a0a: 19 test cases ran, 5 new failures ❌, 2 still failing ❌, 8 passing ✅, 4 additional findings ⚠️.

Diff Summary

Coverage spans normal benchmark dispatch and job creation, failure-safe handling of missing inputs and unavailable results, report retrieval and pull-request publication, plus edge cases involving malformed targets, incomplete output, comment updates, and unsafe report content. The run also exercises asynchronous storage behavior and benchmark configuration propagation, revealing broad problems in the changed reporting and job-setup flows.

Not safe to merge yet — several PR-attributable failures affect core benchmark reporting and silently alter requested benchmark settings, including a still-failing publication path that can prevent results from appearing or updating reliably. Unrelated pre-existing storage and resource-validation findings are caveats for later, but the attributable failures alone are merge-blocking.

Tests run by Ito

View full run

Result State Severity Type Description
❌ New Failure Medium severity Comment The report workflow does not fail clearly when its benchmark result is empty or malformed. It reads the downloaded file and publishes its contents as a pull request comment without checking that the content is present, valid, or within a safe size limit.
❌ New Failure Medium severity Comment The workflow finds the marked comment, but the code immediately starts an object fragment with comment_id: comment.id and later contains an unmatched } else {. There is no valid conditional or updateComment request, so an existing marker comment cannot be updated as intended.
❌ New Failure Medium severity Comment The workflow could not safely and reliably publish the result text. The downloaded report is inserted directly into the reviewer-facing comment, and the branch for an existing marked comment is missing its if statement and update call, leaving an orphaned object property before an unmatched else.
❌ New Failure Medium severity Gate The requested benchmark duration reaches the first dispatch payload but is dropped before the Kubernetes job is rendered. The generated job preserves the pull request revisions and other metadata, but it does not contain --sysbench-test-time=20.
❌ New Failure Medium severity Gate Starting a nightly benchmark with TPCC enabled produces a job with --sysbench-test-time=true and no --withTpcc=true option. The launcher accepts and applies the job instead of rejecting the incompatible caller contract.
❌->❌ Still Failing Medium severity Comment The benchmark results are not posted reliably because the workflow's comment-handling code is incomplete.
❌->❌ Still Failing Medium severity Gate The benchmark workflow does not reject invalid issue numbers before the reporting path runs. Missing, empty, and non-numeric values all pass the job condition, and the reporter converts the value with parseInt instead of checking that the complete input is a valid issue number.
Passing Gate A benchmark request with no base revision stops with a clear error before any benchmark job is created.
Passing Gate The benchmark launcher reported the missing template script, exited with an error, and did not create a Kubernetes job.
Passing Gate When Kubernetes rejected the benchmark job, the launcher showed the error, reported that job creation failed, and stopped with a nonzero exit.
Passing Local The comparison completes successfully and marks a baseline test as DNF when the PR results do not contain it.
Passing Local The benchmark job was created successfully, and report publishing stopped when the expected result was unavailable. This prevents an incomplete run from being presented as a finished benchmark.
Passing Storage A denied cloud login stops the report workflow before it can download results or post a pull request comment.
Passing Storage If the new benchmark result is not ready, the workflow stops before posting a report. It does not reuse an older result from a previous run.
Passing Storage If the workflow cannot read the requested result from the storage bucket, it stops before posting anything to the pull request.
⏸️ Skipped Authorization Every listed authorized identity was accepted, including the six newly added names. Each check returned success and produced the expected affirmative result.
⏸️ Skipped Authorization The authorization check rejected both the removed user max-hoffman and an unrelated unknown user without granting access.
⏸️ Skipped Authorization Empty, partial, differently cased, and space-padded names were all denied without producing an authorization result.
⏸️ Skipped Authorization The exact authorized actor was accepted, while case changes, added characters, surrounding spaces, and an empty name were denied.
⏸️ Skipped Comment A completed benchmark result creates one pull-request comment with the marker, actor, format, and result text when no matching comment exists.
⏸️ Skipped Comment An existing benchmark comment keeps its marker and is replaced with the new actor, format, and results. No second comment is created.
⏸️ Skipped Comment If the comment service fails after the report is downloaded, the workflow also fails instead of claiming the report was posted. A later retry checks for the marked comment again and creates or updates one report after the service recovers.
⏸️ Skipped Gate An authorized benchmark request with pull request number 42 was dispatched, accepted by the reporting job, and prepared the result comment for pull request 42.
⏸️ Skipped Gate A benchmark dispatch marked as not belonging to a pull request was recorded, but no reporting job ran and no pull-request comment was created or changed.
⏸️ Skipped Gate A benchmark starts only when an approved person includes the benchmark marker in the comment. Comments without the marker or from an unapproved person do not start a dispatch.
⏸️ Skipped Local When the selected benchmark report was missing, the workflow stopped during download and did not publish a new or empty report. The existing benchmark comment stayed unchanged.
⏸️ Skipped Storage Valid access downloaded the selected fresh result, and the publication step read RESULT-FRESH from results.log.
⏸️ Skipped Storage The workflow downloaded the requested fresh result and published RESULT-FRESH. It did not use the nearby stale result.
⚠️ Additional Finding High severity Storage The workflow accepts resource choices from the dispatch request instead of limiting them to approved storage and benchmark inputs.
⚠️ Additional Finding Medium severity Comment The workflow does not consistently reject malformed issue numbers before it chooses which pull request receives the benchmark comment.
⚠️ Additional Finding Medium severity Storage A result from one pull request is accepted for publication in another pull request's conversation.
⚠️ Additional Finding Medium severity Storage The report job tries to download the benchmark result once. When the producer writes the result after that attempt, the report job has no supported way to wait, poll, or continue, so the pull request is left without the fresh report.
Tests that are no longer relevant

Below are tests that previously ran and are no longer relevant:

Type Test Description
Comment Publish unusual but readable result content safely Dropped because COMMENT-3's content-publication target was the deleted .github/workflows/mini-sysbench.yml implementation. Publication now uses the changed marker/upsert logic in .github/workflows/pull-report.yaml, so retain the replacement content-safety assertion rather than the old implementation's test identity.
Local External report replaces local comparison Dropped because The local execution/comparison sequence asserted by LOCAL-1 was deleted from .github/workflows/mini-sysbench.yml, including the local benchmark runs and testing/go/benchmark invocation; it is not merely renamed or relocated.
Local Failure details stay visible in the report Dropped because The baseline-versus-PR comparison signal was removed from .github/workflows/mini-sysbench.yml when its dual local benchmark and comparison path was deleted; the replacement reports a single external results.log instead.
Storage Reject inaccessible benchmark credentials Dropped because STORAGE-2 targets the deleted static-credential/S3 path in .github/workflows/mini-sysbench.yml, while STORAGE-6 tests the replacement OIDC role-assumption boundary in .github/workflows/pull-report.yaml; the authentication implementation changed, so keep the new path-specific test and retire the old assertion.
Storage Stops when the benchmark object is missing Dropped because STORAGE-3 exercised missing or unauthorized objects through the deleted .github/workflows/mini-sysbench.yml consumer; STORAGE-8 covers the corresponding unauthorized-bucket failure in the replacement OIDC-backed .github/workflows/pull-report.yaml consumer.
Additional Findings Details

These findings are unrelated to the current changes but were observed during testing.

🟠 Untrusted requests can redirect benchmark work
  • Severity: High High severity
  • Description: The workflow accepts resource choices from the dispatch request instead of limiting them to approved storage and benchmark inputs.
  • Impact: An untrusted request can redirect privileged jobs to read from an unintended storage location or process unintended code and revisions. This can expose protected data or run the wrong benchmark work under the job's trusted access.
  • Steps to Reproduce:
    1. Submit a repository-dispatch request with a valid event type but an unapproved S3 bucket and key, template path, or revision values.
    2. Allow the report workflow to run and inspect the S3 request, or allow the benchmark workflow to create its Kubernetes job.
    3. Check whether the workflow rejects the values before reading the object or rendering the job.
  • Stub / mock content: The recorded target was a local Doltgres metrics service rather than a GitHub Actions, S3, or Kubernetes simulator, so no workflow requests or resource redirections were executed. No stubs, mocks, or bypasses were applied to the application behavior.
  • Code Analysis: The local workflow target could not execute this scenario: the assigned service exposed only Doltgres metrics and returned 404 for repository-dispatch and OIDC routes. Source inspection independently establishes the defect. In .github/workflows/pull-report.yaml:27-30, the shell step passes github.event.client_payload.bucket and github.event.client_payload.key directly to aws s3api get-object. There is no fixed bucket check, key-prefix check, or payload validation before the job uses its OIDC-configured AWS identity. In .github/workflows/k8s-benchmark-latency.yaml:42-56, FROM_VERSION, TO_VERSION, and TEMPLATE_SCRIPT are copied directly from client_payload into the benchmark launcher environment. In .github/scripts/performance-benchmarking/run-benchmarks.sh:72-85, source "$TEMPLATE_SCRIPT" executes the supplied path and the supplied FROM_VERSION and TO_VERSION values are passed into that script to render the Kubernetes job. No approved template allowlist, revision format/allowlist, or resource binding ties the request to the intended repository and benchmark. The smallest practical fix is to ignore caller-supplied bucket/key/template selectors in these privileged workflows and derive them from constants or a server-side mapping; validate revisions against an approved repository and expected ref/SHA format before starting the job.
Evidence Package
🟡 Malformed issue numbers can target reports incorrectly
  • Severity: Medium Medium severity
  • Description: The workflow does not consistently reject malformed issue numbers before it chooses which pull request receives the benchmark comment.
  • Impact: A malformed issue number can cause benchmark results to be posted to a different pull request, or make the workflow send invalid API requests. This can confuse reviewers and attach results to the wrong issue.
  • Steps to Reproduce:
    1. Send a report workflow payload with issue_number set to 12.5.
    2. Observe that the job condition rejects only the numeric value -1, so 12.5 is allowed to run.
    3. Observe that the comment script applies parseInt to 12.5 and uses issue 12 for the GitHub comment API calls.
    4. Repeat with abc12, an empty string, or NaN and observe that parsing produces NaN without an integer validation failure.
  • Stub / mock content: No stubs, mocks, or bypasses were applied for this test in the recorded run.
  • Code Analysis: In .github/workflows/pull-report.yaml:15, the report job condition is ${{ github.event.client_payload.issue_number != -1 }}. This comparison excludes only the numeric sentinel -1; it does not require a present, decimal-only integer string, so values such as 12.5, abc12, an empty string, and NaN can pass the job gate. In the github-script at lines 36-38, ISSUE_NUMBER is read from the client payload and converted with parseInt(ISSUE_NUMBER, 10). JavaScript converts 12.5 to 12, which can direct the subsequent issues.listComments call at lines 46-50 and the issues.createComment call at lines 61-66 to a different issue than the payload named. Nonnumeric or empty values become NaN and are still passed into those API request objects instead of causing an explicit validation error. The smallest practical fix is to validate the raw payload once at the job/script boundary with an integer-only rule such as a non-empty decimal-string check plus a positive-integer range check, then stop the workflow before any GitHub API call when validation fails.
Evidence Package
🟡 A benchmark result can reach the wrong pull request
  • Severity: Medium Medium severity
  • Description: A result from one pull request is accepted for publication in another pull request's conversation.
  • Impact: A benchmark report can be posted to the wrong pull request when the event names one issue but points to another issue's result. This can mislead reviewers and attach incorrect performance information to a code change.
  • Steps to Reproduce:
    1. Create two benchmark runs for two different pull requests, with separate result objects.
    2. Send the report event with pull request A's issue number but pull request B's bucket and result key.
    3. Let the report workflow download the object and inspect the pull request comments.
    4. Observe that the downloaded result is used to build a comment for pull request A instead of being rejected as a mismatch.
  • Stub / mock content: No stubs, mocks, or bypasses were applied for this test in the recorded run.
  • Code Analysis: The workflow gate at .github/workflows/pull-report.yaml:15 only checks that client_payload.issue_number is not -1. The S3 step at lines 25-30 downloads results.log using client_payload.bucket and client_payload.key, while the GitHub Script independently parses client_payload.issue_number at line 38. Lines 46-49 then list comments for that issue, and lines 57 and 61-65 construct the update/create publication body from the downloaded results.log. No code reads result metadata, derives an expected issue or run identity from the object key, or compares the object's identity with issue_number before calling the GitHub API. The producer at .github/workflows/performance-benchmarks-pull-report.yaml:60-64 supplies issue_number as dispatch metadata, but the consumer still accepts that value and the object selectors as independent inputs. The PR diff for pull-report.yaml changes the publication implementation from callback-based creation to intended marker-based upsert logic; it does not add the missing binding and the prior implementation already used the issue number separately from the payload-selected S3 object. The smallest practical fix is to carry a signed or otherwise trusted run identity in the result and dispatch payload, validate that identity against the requested issue before reading or publishing, and stop the job on a mismatch. The same changed block also contains malformed syntax around lines 53-60, which would need correction for the intended update path to execute, but that is separate from the cross-issue identity defect.
Evidence Package
🟡 Delayed benchmark results never get picked up
  • Severity: Medium Medium severity
  • Description: The report job tries to download the benchmark result once. When the producer writes the result after that attempt, the report job has no supported way to wait, poll, or continue, so the pull request is left without the fresh report.
  • Impact: When the benchmark result is written late, the completed benchmark is not posted to the pull request. The team must manually rerun the workflow to publish the report.
  • Steps to Reproduce:
    1. Start a benchmark that will write its result to the configured storage location later.
    2. Start the report workflow before that result object exists.
    3. Allow the first download attempt to fail because the object is missing.
    4. Write the correct result object after the failed attempt and inspect the workflow and pull request comments.
    5. Observe that no retry or polling step publishes the result; only an external manual workflow rerun can try the download again.
  • Stub / mock content: No stubs, mocks, or bypasses were applied for this test in the recorded run.
  • Code Analysis: In .github/workflows/pull-report.yaml:25-30, the Get benchmark results step runs exactly one aws s3api get-object --bucket="$BUCKET" --key="$KEY" results.log command. The step uses the default shell error behavior, so a missing object terminates the job before the Post results to PR step at lines 31-71. There is no loop, delay, polling condition, artifact handoff, or later event that resumes the same report request when the asynchronous producer eventually writes the object. The PR diff confirms that pull-report.yaml changes the publication script around lines 34 onward, while the one-shot retrieval lines are unchanged; therefore this is a pre-existing workflow limitation rather than a regression caused by the PR. The smallest practical fix is to add bounded polling with a clear timeout around the existing get-object command, or provide a supported producer-triggered retry that preserves the original issue number, bucket, and key.
Evidence Package

Tip

Reply with @itoqa to send us feedback on this test run.


const commentMarker = '<!-- go-run-output-sysbench -->';

// List comments on the PR

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🆕 New Failure: identified in this diff run

Medium severity Existing benchmark comments cannot be updated

What failed: The workflow finds the marked comment, but the code immediately starts an object fragment with comment_id: comment.id and later contains an unmatched } else {. There is no valid conditional or updateComment request, so an existing marker comment cannot be updated as intended.

Impact · Steps · Stub / mock · Analysis · Why this is likely a bug
  • Severity: Medium Medium severity
  • Impact: When a report comment already exists, later benchmark results may fail to publish or may not update that comment. Users may miss the latest report until the workflow is fixed or the old comment is handled manually.
  • Steps to Reproduce:
    1. Run the pull-report workflow with a valid benchmark result and a pull request that already has a comment containing the benchmark marker.
    2. Let the workflow list the pull request comments and find the marked comment.
    3. Inspect the publication step and the pull request conversation for the new result.
  • Stub / mock content: No stubs, mocks, or bypasses were applied for this test in the recorded run.
  • Code Analysis: In /tmp/output-agent-workspace/repo/.github/workflows/pull-report.yaml, the PR changes the publication script at lines 53-67. Line 53 assigns comment from comments.find(...), but line 54 begins comment_id: comment.id without an if (comment) block or an await github.rest.issues.updateComment({ call. Lines 54-58 are therefore not a valid statement, and line 59 adds } else { without a matching opening conditional. The only complete API call in this section is the create-comment call at lines 61-66, which is reached only through the malformed branch. The smallest fix is to wrap lines 54-58 in if (comment) { and add the missing await github.rest.issues.updateComment({ issue_number, comment_id: comment.id, owner, repo, body }); retain the existing create call in the else branch.
  • Why this is likely a bug: The defect is in production workflow code, not the unavailable local simulator: the source has an orphaned object-property fragment and an unmatched else in the exact path that handles an existing marker comment. This prevents the intended update-in-place behavior from executing for normal repeat benchmark reports. The PR diff directly changed this block, so the targeted fix is to restore the missing conditional and updateComment call rather than redesigning report publication.
Relevant code

.github/workflows/pull-report.yaml:45-67

const { data: comments } = await github.rest.issues.listComments({ ... });

// Check if a comment already exists
const comment = comments.find(comment => comment.body.includes(commentMarker))
    comment_id: comment.id,
    owner: context.repo.owner,
    repo: context.repo.repo,
    body: `${commentMarker}\n@${ACTOR} ${FORMAT}\n${resData}`
  })
} else {
  // Create a new comment
  await github.rest.issues.createComment({ ... });

.github/workflows/pull-report.yaml:28-41

env:
  KEY: ${{ github.event.client_payload.key }}
  BUCKET: ${{ github.event.client_payload.bucket }}
...
const issue_number = parseInt(ISSUE_NUMBER, 10);
const fs = require('fs').promises;
const resData = await fs.readFile(`${GITHUB_WORKSPACE}/results.log`, 'utf8');
Evidence Package
Copy prompt for an agent
Ito QA identified the following failure during automated PR testing. Please investigate and propose a fix.

**Medium severity — Existing benchmark comments cannot be updated**

**What failed:** The workflow finds the marked comment, but the code immediately starts an object fragment with `comment_id: comment.id` and later contains an unmatched `} else {`. There is no valid conditional or `updateComment` request, so an existing marker comment cannot be updated as intended.

- **Impact:** When a report comment already exists, later benchmark results may fail to publish or may not update that comment. Users may miss the latest report until the workflow is fixed or the old comment is handled manually.
- **Steps to reproduce:**
  1. Run the pull-report workflow with a valid benchmark result and a pull request that already has a comment containing the benchmark marker.
  2. Let the workflow list the pull request comments and find the marked comment.
  3. Inspect the publication step and the pull request conversation for the new result.
- **Stub / mock content:** No stubs, mocks, or bypasses were applied for this test in the recorded run.
- **Code analysis:** In `/tmp/output-agent-workspace/repo/.github/workflows/pull-report.yaml`, the PR changes the publication script at lines 53-67. Line 53 assigns `comment` from `comments.find(...)`, but line 54 begins `comment_id: comment.id` without an `if (comment)` block or an `await github.rest.issues.updateComment({` call. Lines 54-58 are therefore not a valid statement, and line 59 adds `} else {` without a matching opening conditional. The only complete API call in this section is the create-comment call at lines 61-66, which is reached only through the malformed branch. The smallest fix is to wrap lines 54-58 in `if (comment) {` and add the missing `await github.rest.issues.updateComment({ issue_number, comment_id: comment.id, owner, repo, body })`; retain the existing create call in the `else` branch.
- **Why this is likely a bug:** The defect is in production workflow code, not the unavailable local simulator: the source has an orphaned object-property fragment and an unmatched else in the exact path that handles an existing marker comment. This prevents the intended update-in-place behavior from executing for normal repeat benchmark reports. The PR diff directly changed this block, so the targeted fix is to restore the missing conditional and `updateComment` call rather than redesigning report publication.

**Relevant code:**

`.github/workflows/pull-report.yaml:45-67`

~~~yaml
const { data: comments } = await github.rest.issues.listComments({ ... });

// Check if a comment already exists
const comment = comments.find(comment => comment.body.includes(commentMarker))
    comment_id: comment.id,
    owner: context.repo.owner,
    repo: context.repo.repo,
    body: `${commentMarker}\n@${ACTOR} ${FORMAT}\n${resData}`
  })
} else {
  // Create a new comment
  await github.rest.issues.createComment({ ... });
~~~

`.github/workflows/pull-report.yaml:28-41`

~~~yaml
env:
  KEY: ${{ github.event.client_payload.key }}
  BUCKET: ${{ github.event.client_payload.bucket }}
...
const issue_number = parseInt(ISSUE_NUMBER, 10);
const fs = require('fs').promises;
const resData = await fs.readFile(`${GITHUB_WORKSPACE}/results.log`, 'utf8');
~~~

});
const issue_number = parseInt(ISSUE_NUMBER, 10);

const fs = require('fs').promises;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🆕 New Failure: identified in this diff run

Medium severity Untrusted report text can break review comments

What failed: The workflow could not safely and reliably publish the result text. The downloaded report is inserted directly into the reviewer-facing comment, and the branch for an existing marked comment is missing its if statement and update call, leaving an orphaned object property before an unmatched else.

Impact · Steps · Stub / mock · Analysis · Why this is likely a bug
  • Severity: Medium Medium severity
  • Impact: Pull request reports may fail to appear or update, and untrusted report text may trigger unwanted mentions or mislead reviewers through rendered Markdown.
  • Steps to Reproduce:
    1. Provide a results.log file containing an @mention, Markdown or HTML comment text, and more text than the expected report size.
    2. Trigger the pull-report workflow with a valid pull request number and result object.
    3. Observe the github-script step while it searches for the report marker and builds the comment body; then inspect whether a comment is created or updated and how the result text is rendered.
  • Stub / mock content: No stubs, mocks, or bypasses were applied for this test in the recorded run.
  • Code Analysis: The PR changes .github/workflows/pull-report.yaml from a simple createComment call to a marker-based update-or-create flow. At lines 40-41, fs.promises.readFile loads results.log into resData without a size limit, validation, or a policy for handling mention-like or comment-like content. At lines 53-58, comments.find(...) is followed immediately by comment_id, owner, repo, body, and a closing }); there is no if (comment) statement and no github.rest.issues.updateComment call. Line 59 then starts } else {, which has no matching conditional in the script as written. The createComment object at lines 61-66 repeats direct ${resData} interpolation. The result is a source-level syntax/control-flow defect that can prevent the github-script step from executing, plus an unsafe publication path that would allow untrusted result text to affect notifications and rendered comment structure if the branch were repaired without adding bounded content handling. The smallest practical fix is to restore a valid if (comment) { await github.rest.issues.updateComment({ comment_id: comment.id, owner, repo, body }) } else { await github.rest.issues.createComment({ issue_number, owner, repo, body }) } structure, and apply a narrowly scoped maximum size and safe rendering/mention policy to resData before constructing body.
  • Why this is likely a bug: The expected behavior requires adversarial report text to remain bounded and not control mentions, marker selection, or comment structure. The source always places the complete downloaded file into the comment body, so an @mention can notify an unintended user and Markdown or HTML comment syntax can change what reviewers see. Independently, the malformed lines 53-59 prevent the existing-marker path from being a valid JavaScript conditional and omit the required updateComment request, so repeated reports cannot reliably update the intended comment. The local simulator was unavailable, but this conclusion does not depend on that environment because the defect is visible in the production workflow source and the PR diff directly changed these lines.
Relevant code

.github/workflows/pull-report.yaml:40-43

const fs = require('fs').promises;
const resData = await fs.readFile(`${GITHUB_WORKSPACE}/results.log`, 'utf8');

const commentMarker = '<!-- go-run-output-sysbench -->';

.github/workflows/pull-report.yaml:52-67

// Check if a comment already exists
const comment = comments.find(comment => comment.body.includes(commentMarker))
    comment_id: comment.id,
    owner: context.repo.owner,
    repo: context.repo.repo,
    body: `${commentMarker}\n@${ACTOR} ${FORMAT}\n${resData}`
  })
} else {
  // Create a new comment
  await github.rest.issues.createComment({
    issue_number: issue_number,
    owner: context.repo.owner,
    repo: context.repo.repo,
    body: `${commentMarker}\n@${ACTOR} ${FORMAT}\n${resData}`
  });
}
Evidence Package
Copy prompt for an agent
Ito QA identified the following failure during automated PR testing. Please investigate and propose a fix.

**Medium severity — Untrusted report text can break review comments**

**What failed:** The workflow could not safely and reliably publish the result text. The downloaded report is inserted directly into the reviewer-facing comment, and the branch for an existing marked comment is missing its if statement and update call, leaving an orphaned object property before an unmatched else.

- **Impact:** Pull request reports may fail to appear or update, and untrusted report text may trigger unwanted mentions or mislead reviewers through rendered Markdown.
- **Steps to reproduce:**
  1. Provide a results.log file containing an @mention, Markdown or HTML comment text, and more text than the expected report size.
  2. Trigger the pull-report workflow with a valid pull request number and result object.
  3. Observe the github-script step while it searches for the report marker and builds the comment body; then inspect whether a comment is created or updated and how the result text is rendered.
- **Stub / mock content:** No stubs, mocks, or bypasses were applied for this test in the recorded run.
- **Code analysis:** The PR changes .github/workflows/pull-report.yaml from a simple createComment call to a marker-based update-or-create flow. At lines 40-41, fs.promises.readFile loads results.log into resData without a size limit, validation, or a policy for handling mention-like or comment-like content. At lines 53-58, comments.find(...) is followed immediately by comment_id, owner, repo, body, and a closing `})`; there is no `if (comment)` statement and no `github.rest.issues.updateComment` call. Line 59 then starts `} else {`, which has no matching conditional in the script as written. The createComment object at lines 61-66 repeats direct `${resData}` interpolation. The result is a source-level syntax/control-flow defect that can prevent the github-script step from executing, plus an unsafe publication path that would allow untrusted result text to affect notifications and rendered comment structure if the branch were repaired without adding bounded content handling. The smallest practical fix is to restore a valid `if (comment) { await github.rest.issues.updateComment({ comment_id: comment.id, owner, repo, body }) } else { await github.rest.issues.createComment({ issue_number, owner, repo, body }) }` structure, and apply a narrowly scoped maximum size and safe rendering/mention policy to resData before constructing body.
- **Why this is likely a bug:** The expected behavior requires adversarial report text to remain bounded and not control mentions, marker selection, or comment structure. The source always places the complete downloaded file into the comment body, so an @mention can notify an unintended user and Markdown or HTML comment syntax can change what reviewers see. Independently, the malformed lines 53-59 prevent the existing-marker path from being a valid JavaScript conditional and omit the required updateComment request, so repeated reports cannot reliably update the intended comment. The local simulator was unavailable, but this conclusion does not depend on that environment because the defect is visible in the production workflow source and the PR diff directly changed these lines.

**Relevant code:**

`.github/workflows/pull-report.yaml:40-43`

~~~yaml/javascript
const fs = require('fs').promises;
const resData = await fs.readFile(`${GITHUB_WORKSPACE}/results.log`, 'utf8');

const commentMarker = '<!-- go-run-output-sysbench -->';
~~~

`.github/workflows/pull-report.yaml:52-67`

~~~yaml/javascript
// Check if a comment already exists
const comment = comments.find(comment => comment.body.includes(commentMarker))
    comment_id: comment.id,
    owner: context.repo.owner,
    repo: context.repo.repo,
    body: `${commentMarker}\n@${ACTOR} ${FORMAT}\n${resData}`
  })
} else {
  // Create a new comment
  await github.rest.issues.createComment({
    issue_number: issue_number,
    owner: context.repo.owner,
    repo: context.repo.repo,
    body: `${commentMarker}\n@${ACTOR} ${FORMAT}\n${resData}`
  });
}
~~~

// The latest commit on the PR branch.
const toSha = context.payload.pull_request.head.sha;

const payload = {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🆕 New Failure: identified in this diff run

Medium severity Benchmark duration is lost before the job starts

What failed: The requested benchmark duration reaches the first dispatch payload but is dropped before the Kubernetes job is rendered. The generated job preserves the pull request revisions and other metadata, but it does not contain --sysbench-test-time=20.

Impact · Steps · Stub / mock · Analysis · Why this is likely a bug
  • Severity: Medium Medium severity
  • Impact: Benchmark runs can use a different duration than the one requested. This can make performance results unreliable and lead maintainers to make decisions from mismatched data.
  • Steps to Reproduce:
    1. Open or synchronize a pull request with different known base and head commit SHAs.
    2. Run the automatic benchmark workflow and inspect its repository-dispatch payload; confirm it includes sysbench_test_time=20.
    3. Follow the payload into the Kubernetes benchmark workflow and render the job using run-benchmarks.sh.
    4. Inspect the rendered container arguments and confirm that --sysbench-test-time=20 is absent and the TPCC position is being used as the duration position.
  • Stub / mock content: No stubs, mocks, or bypasses were applied for this test in the recorded run.
  • Code Analysis: The new payload in .github/workflows/sysbench-performance.yaml lines 30-40 sets sysbench_test_time to "20". However, .github/workflows/k8s-benchmark-latency.yaml lines 41-56 exports the other client_payload fields to run-benchmarks.sh and has no SYSBENCH_TEST_TIME entry. Even if that environment mapping were added, run-benchmarks.sh lines 72-85 still calls the template with init-big-repo at argument 10, NOMS_BIN_FORMAT at argument 11, and WITH_TPCC at argument 12; it supplies no duration argument. The changed template in get-doltgres-doltgres-job-json.sh lines 5-22 now treats argument 12 as sysbenchTestTime and argument 13 as withTpcc, and lines 33-39 only emit --sysbench-test-time when argument 12 is non-empty. Consequently, the existing caller's TPCC value is interpreted as duration, while the requested 20-second value is never passed. The smallest practical fix is to map github.event.client_payload.sysbench_test_time to SYSBENCH_TEST_TIME in k8s-benchmark-latency.yaml and pass "$SYSBENCH_TEST_TIME" before "$WITH_TPCC" in run-benchmarks.sh, keeping the template's new positional contract consistent.
  • Why this is likely a bug: The test's rendered job contract independently confirms that the duration requested by the pull-request workflow is absent, and source inspection explains the exact positional shift that causes it. This is not a test-only setup issue: the production GitHub Actions and shell files contain the missing handoff. The benchmark can therefore report results for a different duration than the workflow explicitly requested. The direct fix is limited to forwarding the existing payload field and restoring the intended duration-before-TPCC argument order.
Relevant code

.github/workflows/sysbench-performance.yaml:30-40

const payload = {
  from_server: "doltgres",
  from_version: fromSha,
  to_server: "doltgres",
  to_version: toSha,
  mode: "pullRequest",
  issue_number: String(context.issue.number),
  init_big_repo: "true",
  actor: context.actor,
  sysbench_test_time: "20",
  template_script: "./.github/scripts/performance-benchmarking/get-doltgres-doltgres-job-json.sh",
};

.github/workflows/k8s-benchmark-latency.yaml:41-56

- name: Create Sysbench Performance Benchmarking K8s Job
  run: ./.github/scripts/performance-benchmarking/run-benchmarks.sh
  env:
    FROM_SERVER: ${{ github.event.client_payload.from_server }}
    FROM_VERSION: ${{ github.event.client_payload.from_version }}
    TO_SERVER: ${{ github.event.client_payload.to_server }}
    TO_VERSION: ${{ github.event.client_payload.to_version }}
    MODE: ${{ github.event.client_payload.mode }}
    ISSUE_NUMBER: ${{ github.event.client_payload.issue_number }}
    ACTOR: ${{ github.event.client_payload.actor }}
    TEMPLATE_SCRIPT: ${{ github.event.client_payload.template_script }}

.github/scripts/performance-benchmarking/run-benchmarks.sh:72-85

source \
  "$TEMPLATE_SCRIPT" \
  "$jobname" \
  "$FROM_SERVER" \
  "$FROM_VERSION" \
  "$TO_SERVER" \
  "$TO_VERSION" \
  "$timeprefix" \
  "$actorprefix" \
  "$format" \
  "$issuenumber" \
  "$INIT_BIG_REPO" \
  "$NOMS_BIN_FORMAT" \
  "$WITH_TPCC" > job.json

.github/scripts/performance-benchmarking/get-doltgres-doltgres-job-json.sh:18-38

initBigRepo="${10}"
nomsBinFormat="${11}"
sysbenchTestTime="${12}"
withTpcc="${13}"
...
if [ -n "$sysbenchTestTime" ]; then
  sysbenchTestTime="\"--sysbench-test-time=$sysbenchTestTime\","
fi
Evidence Package
Copy prompt for an agent
Ito QA identified the following failure during automated PR testing. Please investigate and propose a fix.

**Medium severity — Benchmark duration is lost before the job starts**

**What failed:** The requested benchmark duration reaches the first dispatch payload but is dropped before the Kubernetes job is rendered. The generated job preserves the pull request revisions and other metadata, but it does not contain --sysbench-test-time=20.

- **Impact:** Benchmark runs can use a different duration than the one requested. This can make performance results unreliable and lead maintainers to make decisions from mismatched data.
- **Steps to reproduce:**
  1. Open or synchronize a pull request with different known base and head commit SHAs.
  2. Run the automatic benchmark workflow and inspect its repository-dispatch payload; confirm it includes sysbench_test_time=20.
  3. Follow the payload into the Kubernetes benchmark workflow and render the job using run-benchmarks.sh.
  4. Inspect the rendered container arguments and confirm that --sysbench-test-time=20 is absent and the TPCC position is being used as the duration position.
- **Stub / mock content:** No stubs, mocks, or bypasses were applied for this test in the recorded run.
- **Code analysis:** The new payload in .github/workflows/sysbench-performance.yaml lines 30-40 sets sysbench_test_time to "20". However, .github/workflows/k8s-benchmark-latency.yaml lines 41-56 exports the other client_payload fields to run-benchmarks.sh and has no SYSBENCH_TEST_TIME entry. Even if that environment mapping were added, run-benchmarks.sh lines 72-85 still calls the template with init-big-repo at argument 10, NOMS_BIN_FORMAT at argument 11, and WITH_TPCC at argument 12; it supplies no duration argument. The changed template in get-doltgres-doltgres-job-json.sh lines 5-22 now treats argument 12 as sysbenchTestTime and argument 13 as withTpcc, and lines 33-39 only emit --sysbench-test-time when argument 12 is non-empty. Consequently, the existing caller's TPCC value is interpreted as duration, while the requested 20-second value is never passed. The smallest practical fix is to map github.event.client_payload.sysbench_test_time to SYSBENCH_TEST_TIME in k8s-benchmark-latency.yaml and pass "$SYSBENCH_TEST_TIME" before "$WITH_TPCC" in run-benchmarks.sh, keeping the template's new positional contract consistent.
- **Why this is likely a bug:** The test's rendered job contract independently confirms that the duration requested by the pull-request workflow is absent, and source inspection explains the exact positional shift that causes it. This is not a test-only setup issue: the production GitHub Actions and shell files contain the missing handoff. The benchmark can therefore report results for a different duration than the workflow explicitly requested. The direct fix is limited to forwarding the existing payload field and restoring the intended duration-before-TPCC argument order.

**Relevant code:**

`.github/workflows/sysbench-performance.yaml:30-40`

~~~yaml
const payload = {
  from_server: "doltgres",
  from_version: fromSha,
  to_server: "doltgres",
  to_version: toSha,
  mode: "pullRequest",
  issue_number: String(context.issue.number),
  init_big_repo: "true",
  actor: context.actor,
  sysbench_test_time: "20",
  template_script: "./.github/scripts/performance-benchmarking/get-doltgres-doltgres-job-json.sh",
};
~~~

`.github/workflows/k8s-benchmark-latency.yaml:41-56`

~~~yaml
- name: Create Sysbench Performance Benchmarking K8s Job
  run: ./.github/scripts/performance-benchmarking/run-benchmarks.sh
  env:
    FROM_SERVER: ${{ github.event.client_payload.from_server }}
    FROM_VERSION: ${{ github.event.client_payload.from_version }}
    TO_SERVER: ${{ github.event.client_payload.to_server }}
    TO_VERSION: ${{ github.event.client_payload.to_version }}
    MODE: ${{ github.event.client_payload.mode }}
    ISSUE_NUMBER: ${{ github.event.client_payload.issue_number }}
    ACTOR: ${{ github.event.client_payload.actor }}
    TEMPLATE_SCRIPT: ${{ github.event.client_payload.template_script }}
~~~

`.github/scripts/performance-benchmarking/run-benchmarks.sh:72-85`

~~~shell
source \
  "$TEMPLATE_SCRIPT" \
  "$jobname" \
  "$FROM_SERVER" \
  "$FROM_VERSION" \
  "$TO_SERVER" \
  "$TO_VERSION" \
  "$timeprefix" \
  "$actorprefix" \
  "$format" \
  "$issuenumber" \
  "$INIT_BIG_REPO" \
  "$NOMS_BIN_FORMAT" \
  "$WITH_TPCC" > job.json
~~~

`.github/scripts/performance-benchmarking/get-doltgres-doltgres-job-json.sh:18-38`

~~~shell
initBigRepo="${10}"
nomsBinFormat="${11}"
sysbenchTestTime="${12}"
withTpcc="${13}"
...
if [ -n "$sysbenchTestTime" ]; then
  sysbenchTestTime="\"--sysbench-test-time=$sysbenchTestTime\","
fi
~~~

@@ -18,7 +18,8 @@ format="$8"
issueNumber="$9"
initBigRepo="${10}"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🆕 New Failure: identified in this diff run

Medium severity Nightly benchmarks use the wrong settings

What failed: Starting a nightly benchmark with TPCC enabled produces a job with --sysbench-test-time=true and no --withTpcc=true option. The launcher accepts and applies the job instead of rejecting the incompatible caller contract.

Impact · Steps · Stub / mock · Analysis · Why this is likely a bug
  • Severity: Medium Medium severity
  • Impact: Nightly benchmarks that enable TPCC run with the wrong duration setting and without TPCC. The job still starts, so teams may trust results that do not match the requested benchmark.
  • Steps to Reproduce:
    1. Run the benchmark launcher with the existing twelve-value caller contract and set TPCC to true.
    2. Capture the generated Kubernetes Job JSON before applying it.
    3. Inspect the workload arguments and compare the duration and TPCC options with the requested settings.
  • Stub / mock content: A local kubectl simulator captured the generated job without contacting a cluster; no production services, credentials, or application data were used.
  • Code Analysis: The existing caller in .github/scripts/performance-benchmarking/run-benchmarks.sh:72-85 invokes TEMPLATE_SCRIPT with twelve positional values after the script name, placing NOMS_BIN_FORMAT at position 11 and WITH_TPCC at position 12. The PR changes .github/scripts/performance-benchmarking/get-doltgres-doltgres-job-json.sh:21-22 so position 12 is assigned to sysbenchTestTime and position 13 is assigned to withTpcc. Its rendering logic at :33-39 turns a non-empty sysbenchTestTime into --sysbench-test-time= and only renders --withTpcc when position 13 is present. Therefore the unchanged legacy invocation supplies true to the new duration slot and supplies no TPCC value. The direct reproduction rendered --sysbench-test-time=true, omitted --withTpcc=true, and still returned a successful job creation path. The PR diff explicitly introduced the new positional mapping and rendering; a targeted fix is to update callers to provide both new values or add an arity/contract check that fails clearly before generating the job.
  • Why this is likely a bug: This is a production automation defect rather than a harness artifact: the source paths have incompatible positional contracts, and a local direct rendering with the legacy invocation reproduces the exact wrong options. The failure is silent because kubectl accepts the generated job and the launcher reports success, while the benchmark workload no longer matches the caller's request. The fix is narrow: align the caller and template argument positions, or fail early when the old arity is used; no broad benchmark redesign is required.
Relevant code

.github/scripts/performance-benchmarking/run-benchmarks.sh:72-85

source "$TEMPLATE_SCRIPT" ... "$NOMS_BIN_FORMAT" \
  "$WITH_TPCC" > job.json

.github/scripts/performance-benchmarking/get-doltgres-doltgres-job-json.sh:19-22

initBigRepo="${10}"
nomsBinFormat="${11}"
sysbenchTestTime="${12}"
withTpcc="${13}"

.github/scripts/performance-benchmarking/get-doltgres-doltgres-job-json.sh:33-39

if [ -n "$sysbenchTestTime" ]; then
  sysbenchTestTime="\"--sysbench-test-time=$sysbenchTestTime\","
fi

if [ -n "$withTpcc" ]; then
  withTpcc="\"--withTpcc=$withTpcc\","

.github/scripts/performance-benchmarking/get-doltgres-doltgres-job-json.sh:101-107

"--results-prefix='$actorPrefix'",
              '"$sysbenchTestTime"'
              '"$withTpcc"'
              '"$initBigRepo"'
              '"$nomsBinFormat"'
Evidence Package
Copy prompt for an agent
Ito QA identified the following failure during automated PR testing. Please investigate and propose a fix.

**Medium severity — Nightly benchmarks use the wrong settings**

**What failed:** Starting a nightly benchmark with TPCC enabled produces a job with --sysbench-test-time=true and no --withTpcc=true option. The launcher accepts and applies the job instead of rejecting the incompatible caller contract.

- **Impact:** Nightly benchmarks that enable TPCC run with the wrong duration setting and without TPCC. The job still starts, so teams may trust results that do not match the requested benchmark.
- **Steps to reproduce:**
  1. Run the benchmark launcher with the existing twelve-value caller contract and set TPCC to true.
  2. Capture the generated Kubernetes Job JSON before applying it.
  3. Inspect the workload arguments and compare the duration and TPCC options with the requested settings.
- **Stub / mock content:** A local kubectl simulator captured the generated job without contacting a cluster; no production services, credentials, or application data were used.
- **Code analysis:** The existing caller in .github/scripts/performance-benchmarking/run-benchmarks.sh:72-85 invokes TEMPLATE_SCRIPT with twelve positional values after the script name, placing NOMS_BIN_FORMAT at position 11 and WITH_TPCC at position 12. The PR changes .github/scripts/performance-benchmarking/get-doltgres-doltgres-job-json.sh:21-22 so position 12 is assigned to sysbenchTestTime and position 13 is assigned to withTpcc. Its rendering logic at :33-39 turns a non-empty sysbenchTestTime into --sysbench-test-time=<value> and only renders --withTpcc when position 13 is present. Therefore the unchanged legacy invocation supplies true to the new duration slot and supplies no TPCC value. The direct reproduction rendered --sysbench-test-time=true, omitted --withTpcc=true, and still returned a successful job creation path. The PR diff explicitly introduced the new positional mapping and rendering; a targeted fix is to update callers to provide both new values or add an arity/contract check that fails clearly before generating the job.
- **Why this is likely a bug:** This is a production automation defect rather than a harness artifact: the source paths have incompatible positional contracts, and a local direct rendering with the legacy invocation reproduces the exact wrong options. The failure is silent because kubectl accepts the generated job and the launcher reports success, while the benchmark workload no longer matches the caller's request. The fix is narrow: align the caller and template argument positions, or fail early when the old arity is used; no broad benchmark redesign is required.

**Relevant code:**

`.github/scripts/performance-benchmarking/run-benchmarks.sh:72-85`

~~~sh
source "$TEMPLATE_SCRIPT" ... "$NOMS_BIN_FORMAT" \
  "$WITH_TPCC" > job.json
~~~

`.github/scripts/performance-benchmarking/get-doltgres-doltgres-job-json.sh:19-22`

~~~sh
initBigRepo="${10}"
nomsBinFormat="${11}"
sysbenchTestTime="${12}"
withTpcc="${13}"
~~~

`.github/scripts/performance-benchmarking/get-doltgres-doltgres-job-json.sh:33-39`

~~~sh
if [ -n "$sysbenchTestTime" ]; then
  sysbenchTestTime="\"--sysbench-test-time=$sysbenchTestTime\","
fi

if [ -n "$withTpcc" ]; then
  withTpcc="\"--withTpcc=$withTpcc\","
~~~

`.github/scripts/performance-benchmarking/get-doltgres-doltgres-job-json.sh:101-107`

~~~sh
"--results-prefix='$actorPrefix'",
              '"$sysbenchTestTime"'
              '"$withTpcc"'
              '"$initBigRepo"'
              '"$nomsBinFormat"'
~~~

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.

2 participants