Skip to content

test(gax): verify handwritten lifecycle hooks and gaxios @types/bun - #9729

Draft
danieljbruce wants to merge 1 commit into
fix/b578005287-spanner-otel-bun-releasefrom
fix/b578004580-bun-handwritten-lifecycle-gaxios
Draft

danieljbruce wants to merge 1 commit into
fix/b578005287-spanner-otel-bun-releasefrom
fix/b578004580-bun-handwritten-lifecycle-gaxios

Conversation

@danieljbruce

Copy link
Copy Markdown
Contributor

Description

Adds tests verifying handwritten lifecycle hooks and gaxios @types/bun FetchCompliance compatibility.

Impact

Prevents regressions in bun install lifecycle scripts and @types/bun typechecking.

Changes

  • Add automated verification suite core/packages/gax/test/unit/bunHandwrittenLifecycleAndTypes.ts covering all 14 handwritten/* client libraries and 14 core/* packages:
    • Verifies that every handwritten and core package.json defines deterministic prepare compilation hooks without unapproved postinstall lifecycle scripts that would be blocked by Bun v1.1+ default trustedDependencies policies (explicitly accounting for @google-cloud/profiler's V8-native pprof addon).
    • Verifies that gaxios (FetchCompliance and GaxiosOptions['fetchImplementation']) type-checks cleanly when globalThis.fetch includes @types/bun's static fetch.preconnect namespace property with skipLibCheck: false.

Testing

  • Steps to Reproduce (in terminal):
    • Run python3 .agents/skills/cistack/scripts/cistack.py --repo-root . --base-ref fix/b578005287-spanner-otel-bun-release --branches test/b578004580-bun-handwritten-lifecycle-gaxios --mode preflight-push2 and bun --bun bin/run-test.cjs --no-c8 core/packages/gax/build/test/unit/streamArrayParser.js.
  • Executed core/packages/gax/build/test/unit/bunHandwrittenLifecycleAndTypes.js under both Node.js and Bun (JS_RUNTIME=bun).
  • Verified node ./bin/linter.mjs --strict passes with zero errors.

Alternatives

  • Rely solely on external ad-hoc Gist scripts (b/576206722) without in-repo regression tests; rejected because in-repo unit tests catch lifecycle script or FetchCompliance type regressions in CI before release.
  • Run live network bun install across all 14 handwritten libraries on every unit test invocation; rejected for unit tests because network registry installs are slow and flaky in offline/hermetic CI environments.
  • Do not add verification tests, risking regressions in handwritten library prepare/postinstall scripts or @types/bun declaration compatibility.

Fixes b/578004580
For b/576206722

@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 a new unit test file bunHandwrittenLifecycleAndTypes.ts to verify handwritten libraries' lifecycle hooks and ensure gaxios fetch compliance types are correctly defined. The review feedback suggests normalizing whitespace in the source files before asserting on code snippets to prevent the tests from being fragile to formatting changes.

Comment on lines +106 to +120
assert.ok(
gaxiosSrc.includes(
'fetch: (...args: Parameters<typeof fetch>) => ReturnType<typeof fetch>;',
),
'Expected FetchCompliance in gaxios.ts to use the callable fetch signature instead of typeof fetch',
);
assert.ok(
commonSrc.includes(
'fetchImplementation?: (\n ...args: Parameters<typeof fetch>\n ) => ReturnType<typeof fetch>;',
) ||
commonSrc.includes(
'(...args: Parameters<typeof fetch>) => ReturnType<typeof fetch>',
),
'Expected GaxiosOptions.fetchImplementation in common.ts to use the callable fetch signature',
);

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.

medium

Asserting exact multi-line strings with specific indentation and line breaks (like \n ...) is highly fragile and prone to breaking if code formatters (e.g., Prettier) are run or updated.

To make the test robust against formatting changes, normalize the whitespace of the source files before performing the substring checks.

    const normalizedGaxiosSrc = gaxiosSrc.replace(/\s+/g, ' ');
    assert.ok(
      normalizedGaxiosSrc.includes(
        'fetch: (...args: Parameters<typeof fetch>) => ReturnType<typeof fetch>',
      ),
      'Expected FetchCompliance in gaxios.ts to use the callable fetch signature instead of typeof fetch',
    );

    const normalizedCommonSrc = commonSrc.replace(/\s+/g, ' ');
    assert.ok(
      normalizedCommonSrc.includes(
        'fetchImplementation?: (...args: Parameters<typeof fetch>) => ReturnType<typeof fetch>',
      ) ||
        normalizedCommonSrc.includes(
          '(...args: Parameters<typeof fetch>) => ReturnType<typeof fetch>',
        ),
      'Expected GaxiosOptions.fetchImplementation in common.ts to use the callable fetch signature',
    );

'Expected GaxiosOptions.fetchImplementation in common.ts to use the callable fetch signature',
);
});
});

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

[Generated] Add regression unit test suite verifying all 14 handwritten/* client libraries define clean prepare scripts without bun install trustedDependencies-blocked postinstall hooks and verifying gaxios narrows FetchCompliance to (...args: Parameters<typeof fetch>) => ReturnType<typeof fetch> for @types/bun compatibility.

@danieljbruce
danieljbruce force-pushed the fix/b578004580-bun-handwritten-lifecycle-gaxios branch from 2e92698 to 72877ed Compare October 27, 2026 16:55
@danieljbruce
danieljbruce force-pushed the fix/b578005287-spanner-otel-bun-release branch from 557b47e to 5e19a64 Compare October 27, 2026 16:55
@danieljbruce

Copy link
Copy Markdown
Contributor Author

/gemini review

@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 introduces a new test suite, bunHandwrittenLifecycleAndTypes.ts, to verify that handwritten libraries define clean prepare scripts without blocked postinstall hooks under Bun, and that gaxios correctly narrows fetch signatures for @types/bun. The feedback recommends dynamically resolving the repository root to support running tests from both compiled JS and source TS directories, and normalizing line endings to LF when reading source files to prevent test failures on Windows due to CRLF line endings.

import * as path from 'path';
import {describe, it} from 'mocha';

const REPO_ROOT = path.resolve(__dirname, '../../../../../..');

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.

medium

To ensure the tests can be run directly from the TypeScript source files (e.g., via ts-node or bun directly on the .ts file) as well as from the compiled JavaScript in the build directory, resolve the repository root dynamically by checking for the existence of a known directory like handwritten.

const REPO_ROOT = (() => {
  const paths = [
    path.resolve(__dirname, '../../../../../..'), // from build/test/unit (compiled JS)
    path.resolve(__dirname, '../../../../..'),    // from test/unit (source TS)
  ];
  for (const p of paths) {
    if (fs.existsSync(path.join(p, 'handwritten'))) {
      return p;
    }
  }
  throw new Error('Could not resolve repository root');
})();

Comment on lines +103 to +104
const gaxiosSrc = fs.readFileSync(gaxiosSrcPath, 'utf8');
const commonSrc = fs.readFileSync(commonSrcPath, 'utf8');

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.

medium

On Windows platforms, git may checkout files with CRLF (\r\n) line endings. Since the assertion on commonSrc contains explicit \n characters, this test will fail on Windows. Normalizing the line endings to \n after reading the files prevents this issue.

Suggested change
const gaxiosSrc = fs.readFileSync(gaxiosSrcPath, 'utf8');
const commonSrc = fs.readFileSync(commonSrcPath, 'utf8');
const gaxiosSrc = fs.readFileSync(gaxiosSrcPath, 'utf8').replace(/\r\n/g, '\n');
const commonSrc = fs.readFileSync(commonSrcPath, 'utf8').replace(/\r\n/g, '\n');

This branch has not been deployed

No deployments
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.

1 participant