-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Remove 'Original Filename' metadata from Windows executables #22389
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
When creating single-file executables on Windows, the 'Original Filename' field was showing 'bun.exe' regardless of the actual executable name. This change automatically removes this field by setting it to an empty string in the rescle metadata update process. The fix modifies rescle__setWindowsMetadata() to automatically clear the OriginalFilename field when updating Windows executable metadata. Tests added to verify the field is properly removed in all scenarios. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Updated 7:37 PM PT - Sep 3rd, 2025
❌ @autofix-ci[bot], your commit bdca2b9 has some failures in 🧪 To try this PR locally: bunx bun-pr 22389 That installs a local version of the PR into your bun-22389 --bun |
WalkthroughClears the Windows VersionInfo OriginalFilename by setting RU_VS_ORIGINAL_FILENAME to an empty string in the metadata binding, returning -13 on failure, before committing. Adds tests that build Windows executables and assert VersionInfo.OriginalFilename is empty for minimal and full metadata; the test block is duplicated. No public signatures changed. Changes
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 💡 Knowledge Base configuration:
You can enable these sources in your CodeRabbit configuration. 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
✨ Finishing Touches
🧪 Generate unit tests
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (4)
test/bundler/compile-windows-metadata.test.ts (4)
352-395
: Harden the assertion to avoid false positives and sanity-check metadata read.getMetadata() returns "" on PowerShell errors, which could mask failures. Also assert ProductName to ensure the VersionInfo read worked, and prefer length-check for clarity.
- const originalFilename = getMetadata("OriginalFilename"); - expect(originalFilename).toBe(""); - expect(originalFilename).not.toBe("bun.exe"); + // Sanity check that we're actually reading VersionInfo + expect(getMetadata("ProductName")).toBe("Test Application"); + + const originalFilename = getMetadata("OriginalFilename"); + expect(originalFilename).toHaveLength(0); + expect(originalFilename).not.toBe("bun.exe");
396-452
: Mirror the stronger checks in the full-metadata case.Same rationale as above.
- // But Original Filename should still be empty - const originalFilename = getMetadata("OriginalFilename"); - expect(originalFilename).toBe(""); - expect(originalFilename).not.toBe("bun.exe"); + // But Original Filename should still be empty + expect(getMetadata("ProductName")).toBe("Complete App"); + const originalFilename = getMetadata("OriginalFilename"); + expect(originalFilename).toHaveLength(0); + expect(originalFilename).not.toBe("bun.exe");
352-452
: DRY the PowerShell accessor.getMetadata is duplicated; consider extracting a single helper at top-level for reuse in this file.
Example helper (place near cleanup()):
function getVersionInfoField(outfile: string, field: string): string { try { return execSync(`powershell -Command "(Get-ItemProperty '${outfile}').VersionInfo.${field}"`, { encoding: "utf8" }).trim(); } catch { return ""; } }Then replace local getMetadata calls with getVersionInfoField(outfile, "...").
396-452
: Add API-path coverage for OriginalFilename.We verify CLI; also add a Bun.build() test asserting OriginalFilename is empty to cover the API code path.
Example:
test("Original Filename empty via Bun.build()", async () => { const dir = tempDirWithFiles("windows-original-api", { "app.js": `console.log("api");` }); const result = await Bun.build({ entrypoints: [join(dir, "app.js")], outdir: dir, compile: { target: "bun-windows-x64", outfile: "api-original.exe", windows: { title: "API OFN" } }, }); expect(result.success).toBe(true); const outfile = result.outputs[0].path; await using _cleanup = cleanup(outfile); const get = (f: string) => execSync(`powershell -Command "(Get-ItemProperty '${outfile}').VersionInfo.${f}"`, { encoding: "utf8" }).trim(); expect(get("ProductName")).toBe("API OFN"); expect(get("OriginalFilename")).toHaveLength(0); expect(get("OriginalFilename").toLowerCase()).not.toBe("bun.exe"); });
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (2)
src/bun.js/bindings/windows/rescle-binding.cpp
(1 hunks)test/bundler/compile-windows-metadata.test.ts
(1 hunks)
🧰 Additional context used
📓 Path-based instructions (11)
**/*.{cpp,h}
📄 CodeRabbit inference engine (.cursor/rules/javascriptcore-class.mdc)
**/*.{cpp,h}
: When exposing a JS class with public Constructor and Prototype, define three C++ types: class Foo : public JSC::DestructibleObject (if it has C++ fields), class FooPrototype : public JSC::JSNonFinalObject, and class FooConstructor : public JSC::InternalFunction
If the class has C++ data members, inherit from JSC::DestructibleObject and provide proper destruction; if it has no C++ fields (only JS properties), avoid a class and use JSC::constructEmptyObject(vm, structure) with putDirectOffset
Prefer placing the subspaceFor implementation in the .cpp file rather than the header when possible
Files:
src/bun.js/bindings/windows/rescle-binding.cpp
**/*.cpp
📄 CodeRabbit inference engine (.cursor/rules/javascriptcore-class.mdc)
**/*.cpp
: Include "root.h" at the top of C++ binding files to satisfy lints
Define prototype properties using a const HashTableValue array and declare accessors/functions with JSC_DECLARE_* macros
Prototype classes should subclass JSC::JSNonFinalObject, provide create/createStructure, DECLARE_INFO, finishCreation that reifies static properties, and set mayBePrototype on the Structure
Custom getters should use JSC_DEFINE_CUSTOM_GETTER, jsDynamicCast to validate this, and throwThisTypeError on mismatch
Custom setters should use JSC_DEFINE_CUSTOM_SETTER, validate this via jsDynamicCast, and store via WriteBarrier/set semantics
Prototype functions should use JSC_DEFINE_HOST_FUNCTION, validate this with jsDynamicCast, and return encoded JSValue
Constructors should subclass JSC::InternalFunction, return internalFunctionSpace in subspaceFor, set the prototype property as non-configurable/non-writable, and provide create/createStructure
Provide a setup function that builds the Prototype, Constructor, and Structure, and assigns them to the LazyClassStructure initializer
Use the cached Structure via globalObject->m_.get(globalObject) when constructing instances
Expose constructors to Zig via an extern "C" function that returns the constructor from the LazyClassStructure
Provide an extern "C" Bun____toJS function that creates an instance using the cached Structure and returns an EncodedJSValue
Files:
src/bun.js/bindings/windows/rescle-binding.cpp
src/bun.js/bindings/**/*.cpp
📄 CodeRabbit inference engine (CLAUDE.md)
src/bun.js/bindings/**/*.cpp
: When implementing a JS class with a public constructor in C++ bindings, create Foo, FooPrototype, and FooConstructor classes
Define JS-visible properties using HashTableValue arrays
Add iso subspaces for classes with C++ fields
Cache class structures in ZigGlobalObject for bindings
Files:
src/bun.js/bindings/windows/rescle-binding.cpp
**/*.{cpp,hpp,h,cc,cxx}
📄 CodeRabbit inference engine (CLAUDE.md)
Run clang-format to format C/C++ files (bun run clang-format)
Files:
src/bun.js/bindings/windows/rescle-binding.cpp
test/**
📄 CodeRabbit inference engine (.cursor/rules/writing-tests.mdc)
Place all tests under the test/ directory
Files:
test/bundler/compile-windows-metadata.test.ts
test/bundler/**/*
📄 CodeRabbit inference engine (.cursor/rules/writing-tests.mdc)
Place bundler/transpiler/CSS/bun build tests under test/bundler/
Files:
test/bundler/compile-windows-metadata.test.ts
test/**/*.{js,ts}
📄 CodeRabbit inference engine (.cursor/rules/writing-tests.mdc)
test/**/*.{js,ts}
: Write tests in JavaScript or TypeScript using Bun’s Jest-style APIs (test, describe, expect) and run with bun test
Prefer data-driven tests (e.g., test.each) to reduce boilerplate
Use shared utilities from test/harness.ts where applicable
Files:
test/bundler/compile-windows-metadata.test.ts
test/**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
test/**/*.test.{ts,tsx}
: Tests must be named with the suffix .test.ts or .test.tsx and live under the test/ directory
In tests, always use port: 0 and never hardcode ports or use custom random-port utilities
Prefer snapshot tests using normalizeBunSnapshot(...) over direct string equality on stdout/stderr
Do not write tests that assert absence of 'panic', 'uncaught exception', or similar strings in output
Avoid shelling out to tools like find or grep in tests; use Bun.Glob and built-in utilities
Files:
test/bundler/compile-windows-metadata.test.ts
test/bundler/**
📄 CodeRabbit inference engine (CLAUDE.md)
Place bundler and transpiler tests under test/bundler/
Files:
test/bundler/compile-windows-metadata.test.ts
**/*.{ts,tsx,js}
📄 CodeRabbit inference engine (CLAUDE.md)
Run Prettier to format JS/TS files (bun run prettier)
Files:
test/bundler/compile-windows-metadata.test.ts
test/**/*.test.ts
📄 CodeRabbit inference engine (test/CLAUDE.md)
test/**/*.test.ts
: Name test files*.test.ts
and usebun:test
Do not write flaky tests: never wait for arbitrary time; wait for conditions instead
Never hardcode port numbers in tests; useport: 0
to get a random port
When spawning Bun in tests, usebunExe()
andbunEnv
fromharness
Preferasync/await
in tests; for a single callback, usePromise.withResolvers()
Do not set explicit test timeouts; rely on Bun’s built-in timeouts
UsetempDir
/tempDirWithFiles
fromharness
for temporary files and directories in tests
For large/repetitive strings in tests, preferBuffer.alloc(count, fill).toString()
over"A".repeat(count)
Import common test utilities fromharness
(e.g.,bunExe
,bunEnv
,tempDirWithFiles
,tmpdirSync
, platform checks, GC helpers)
In error tests, assert non-zero exit codes for failing processes and usetoThrow
for synchronous errors
Usedescribe
blocks for grouping,describe.each
for parameterized tests, snapshots withtoMatchSnapshot
, and lifecycle hooks (beforeAll
,beforeEach
,afterEach
); track resources for cleanup inafterEach
Useusing
/await using
with Bun resources (e.g., Bun.listen/connect/spawn/serve) to ensure cleanup in tests
Files:
test/bundler/compile-windows-metadata.test.ts
🧠 Learnings (1)
📚 Learning: 2025-08-30T00:09:39.100Z
Learnt from: CR
PR: oven-sh/bun#0
File: .cursor/rules/dev-server-tests.mdc:0-0
Timestamp: 2025-08-30T00:09:39.100Z
Learning: Applies to test/bake/dev/bundle.test.ts : bundle.test.ts should contain DevServer-specific bundling tests
Applied to files:
test/bundler/compile-windows-metadata.test.ts
🧬 Code graph analysis (1)
test/bundler/compile-windows-metadata.test.ts (1)
test/harness.ts (1)
tempDirWithFiles
(258-265)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Format
🔇 Additional comments (2)
src/bun.js/bindings/windows/rescle-binding.cpp (2)
90-94
: Good call: explicitly clearing VersionInfo.OriginalFilename.This directly addresses the “bun.exe” mislabel and aligns with the new tests.
90-94
: Clear InternalName and document new error code
- In
src/bun.js/bindings/windows/rescle-binding.cpp
, append:// Also clear "InternalName" to avoid "bun.exe" showing in some shells/inspectors if (!updater.SetVersionString(RU_VS_INTERNAL_NAME, L"")) return -14;- No in-repo callers or docs reference codes -12/-13; update any external error-code documentation or consumer logic to include the new -14 code.
Summary
Problem
When creating single-file executables on Windows, the "Original Filename" metadata field was showing "bun.exe" regardless of the actual executable name. This was confusing for users and incorrect from a metadata perspective.
Solution
Modified
rescle__setWindowsMetadata()
insrc/bun.js/bindings/windows/rescle-binding.cpp
to automatically clear theOriginalFilename
field by setting it to an empty string whenever Windows metadata is updated during executable creation.Test Plan
test/bundler/compile-windows-metadata.test.ts
to verify:bun run zig:check-all
- all platforms compile successfullyThe tests will run on Windows CI to verify the behavior is correct.
🤖 Generated with Claude Code