@actions/glob 0.6.1 silently fails to match Windows paths when bundled as ESM with Rollup
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 5.9k
- Forks
- 1.8k
- PR merge metrics
- No merged PRs in 30d
Description
Description
@actions/glob@0.6.1 can silently fail to match valid Windows paths when it is bundled into an ES module using Rollup and @rollup/plugin-commonjs.
The same code works when executed directly with Node, but returns no matches after being bundled.
This also affects custom JavaScript actions using @actions/cache@6.2.0, because it depends on:
@actions/glob@^0.6.1minimatch@^3.0.4
The failure ultimately causes @actions/cache.saveCache() to report:
Path Validation Error: Path(s) specified in the action for caching do(es) not exist
even though the path exists and can be read by Node.
Environment
- OS: Windows
- Node.js: 24.6.0
@actions/cache: 6.2.0@actions/glob: 0.6.1minimatch: 3.1.5- Rollup: 4.62.3
@rollup/plugin-commonjs: 29.0.3@rollup/plugin-node-resolve: 16.0.3- Bundle format: ESM
Minimal reproduction
Install the dependencies:
npm install @actions/glob@0.6.1
npm install --save-dev rollup @rollup/plugin-commonjs @rollup/plugin-node-resolve
Create test.js:
import * as glob from '@actions/glob';
const pattern = 'C:\\Windows';
const globber = await glob.create(pattern, {
implicitDescendants: false,
});
console.log(await globber.glob());
Running it directly succeeds:
node test.js
Output:
[ 'C:\\Windows' ]
Create rollup.config.js:
import commonjs from '@rollup/plugin-commonjs';
import { nodeResolve } from '@rollup/plugin-node-resolve';
export default {
input: 'test.js',
output: {
file: 'bundle.js',
format: 'es',
},
plugins: [
commonjs(),
nodeResolve({ preferBuiltins: true }),
],
};
Bundle and execute it:
npx rollup --config rollup.config.js
node bundle.js
Output:
[]
With debug logging enabled, the bundled version reports the search path but never reports a match:
Search path 'C:\Windows'
A real GitHub Actions failure using @actions/cache@6.2.0 produced:
Search path 'C:\Program Files\My Software'
Cache Paths:
[]
Path Validation Error: Path(s) specified in the action for caching do(es) not exist
Root cause
@actions/glob@0.6.1 depends on minimatch@3. That version of minimatch detects the platform separator using:
var path = (function () {
try {
return require('path');
} catch (e) {}
})() || {
sep: '/',
};
@rollup/plugin-commonjs defaults ignoreTryCatch to true. Therefore, it does not convert the require('path') call because it appears inside a try block.
The resulting ESM bundle still contains:
try {
return require('path');
} catch (e) {}
Because require is unavailable in ESM, the resulting ReferenceError is caught and minimatch silently falls back to:
{ sep: '/' }
On Windows, @actions/glob converts its pattern to forward slashes, but the filesystem item passed to minimatch.match() remains backslash-delimited.
As a result, Pattern.match() returns MatchKind.None, and internal-globber silently discards the existing path here:
const match = patternHelper.match(patterns, item.path);
const partialMatch =
!!match || patternHelper.partialMatch(patterns, item.path);
if (!match && !partialMatch) {
continue;
}
Confirmed workaround
Configuring the CommonJS plugin to convert only require('path') calls inside try blocks fixes the bundled output:
commonjs({
ignoreTryCatch: id => id !== 'path',
})
After rebuilding with that configuration, the bundled reproduction correctly reports:
Matched: C:/Windows
Cache Paths:
["C:/Windows"]
The same fix allowed @actions/cache to resolve and archive an absolute path on C: while GITHUB_WORKSPACE was on D:, confirming that separate Windows drives were not the cause.
Expected behavior
Bundling a consumer of @actions/glob should not change whether valid Windows paths match.
At minimum, the package should not silently interpret Windows paths using POSIX separator behavior merely because it was included in an ESM bundle.
Suggested resolution
It appears that @actions/glob@0.7.0 has already moved from minimatch@3 to minimatch@10.
Could the maintainers please confirm whether 0.7.0 resolves this bundling issue and, if so:
- Update toolkit consumers such as
@actions/cacheto depend on@actions/glob@0.7.0. - Add a Windows regression test that executes a Rollup-generated ESM bundle.
- Consider documenting that
@actions/glob@0.6.1is unsafe when bundled this way.
Since @actions/cache@6.2.0 currently uses @actions/glob@^0.6.1, its semver range will not select 0.7.0.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the @actions/glob internal-globber path matching and its minimatch dependency, then run the test.js and rollup.config.js reproduction on Windows. Check the bundled ESM output and verify that valid backslash-delimited paths still match; done means a regression test covers the Rollup bundle and the affected dependency behavior is resolved or documented.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- nodejs, rollup, typescript
- Domain
- build-system, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100