CreateLayout on macOS produces tar archives that .NET TarReader cannot extract (PAX extended attributes)
- Dominant language
- C#
- Stars
- 6.3k
- Forks
- 991
- Avg merge
- 2d 15h
- Merged PRs (30d)
- 196
Description
## Problem
When building the Aspire CLI bundle on macOS via `tools/CreateLayout`, the archive creation path shells out to system `tar` (`tar -czf ...`). On macOS, `/usr/bin/tar` is `bsdtar` (libarchive). bsdtar emits PAX-format extended-attribute headers (e.g. `SCHILY.fflags`, `LIBARCHIVE.creationtime`) by default, even with `COPYFILE_DISABLE=1`.
At runtime the CLI extracts the embedded `bundle.tar.gz` with `System.Formats.Tar.TarReader`. .NET's TarReader rejects these headers with:
```
System.IO.InvalidDataException: The extended header contains invalid records.
at System.Formats.Tar.TarHeader.ReadExtendedAttributesFromBuffer
at System.Formats.Tar.TarHeader.TryGetNextExtendedAttributesEntry
at System.Formats.Tar.TarReader.GetNextEntryAsync
```
This surfaces to the user as `❌ Bundle extraction failed. Run 'aspire setup --force' to retry, or reinstall the Aspire CLI.`
## Impact
All CLI E2E tests that exercise `aspire init` (which triggers bundle extraction via `AppHostServerSession` → `BundleService.EnsureExtractedAndGetLayoutAsync`) fail on macOS hosts when the bundle is built locally via `localhive.sh`. This includes any developer iterating on JavaScript / TypeScript polyglot CLI work on Apple Silicon or Intel macs, even when targeting Linux containers via Docker Desktop.
The `aspire new` C# starter path does not trigger bundle extraction on first run, so `SmokeTests.CreateAndRunAspireStarterProject` passes; this masked the issue until JS-specific tests were added.
## Repro
```bash
./localhive.sh -o /tmp/aspire-e2e -r linux-arm64 --archive
ASPIRE_E2E_ARCHIVE=/tmp/aspire-e2e.tar.gz dotnet test tests/Aspire.Cli.EndToEnd.Tests \
-- --filter-method "*.InitTypeScriptAppHost_AugmentsExistingViteRepoAtRoot"
```
## Fix (applied)
Use the .NET `System.Formats.Tar.TarWriter` path on macOS as well as Windows in `tools/CreateLayout/Program.cs::CreateArchiveAsync`. .NET's TarWriter produces archives that round-trip cleanly through TarReader.
Branch: `davidfowl/js-monorepo-dockerfile` — commit `c210d7f6d`.
## Workarounds
- Install GNU tar (`brew install gnu-tar`) and arrange for `gtar` to be invoked instead of system `tar`.
- Build the CLI archive on Linux (or in a Linux container) instead of macOS.
Neither workaround is acceptable for routine local development on macOS.
Contributor guide
Assessment
This issue has not been assessed yet.