diff --git a/.github/workflows/ci-macos.yml b/.github/workflows/ci-macos.yml index c31104eb983e..6b438375cb88 100644 --- a/.github/workflows/ci-macos.yml +++ b/.github/workflows/ci-macos.yml @@ -942,7 +942,19 @@ jobs: # COPYFILE_DISABLE: see the matching note in test-e2e.yml. gzip -1 # takes about a third of the default level's time on this product # for an archive about 11% larger. - COPYFILE_DISABLE=1 tar -chf - -C "$CMUX_COMPILE_ADMISSION_DERIVED_DATA" Build/Products | gzip -1 > "$archive" + # Build/Products reaches each framework binary through Versions/Current + # symlinks, and product extractors accept no symlinks, so `tar -h` stored + # every framework binary three times: 1.9 GB on disk became 2.7 GB of + # tar and 830 MB gzipped. Stage the tree as hard links with the symlinks + # followed (the same tree `tar -h` wrote, beside the DerivedData so the + # links stay on one volume); tar then stores each file once and every + # other path as a hard link, which tar -x, aa and + # reuse_app_host_products.py all extract. Same files, 572 MB, packed + # faster. + stage="$(mktemp -d "${CMUX_COMPILE_ADMISSION_DERIVED_DATA%/*}/.product-pack.XXXXXX")" + trap 'rm -rf "$stage"' EXIT + (cd "$CMUX_COMPILE_ADMISSION_DERIVED_DATA" && pax -rwlL Build/Products "$stage") + COPYFILE_DISABLE=1 tar -cf - -C "$stage" Build/Products | gzip -1 > "$archive" echo "sha256=$(shasum -a 256 "$archive" | awk '{print $1}')" >> "$GITHUB_OUTPUT" - name: Upload compiled app-host test product diff --git a/.github/workflows/seed-derived-data.yml b/.github/workflows/seed-derived-data.yml index 316e24b0f389..c313aa1a9017 100644 --- a/.github/workflows/seed-derived-data.yml +++ b/.github/workflows/seed-derived-data.yml @@ -396,7 +396,19 @@ jobs: python3 scripts/ci/app_host_test_products.py stamp "$CMUX_COMPILE_ADMISSION_DERIVED_DATA" python3 scripts/ci/reuse_app_host_products.py seal "$CMUX_COMPILE_ADMISSION_DERIVED_DATA" archive="$RUNNER_TEMP/app-host-products.tar.gz" - COPYFILE_DISABLE=1 tar -chf - -C "$CMUX_COMPILE_ADMISSION_DERIVED_DATA" Build/Products | gzip -1 > "$archive" + # Build/Products reaches each framework binary through Versions/Current + # symlinks, and product extractors accept no symlinks, so `tar -h` stored + # every framework binary three times: 1.9 GB on disk became 2.7 GB of + # tar and 830 MB gzipped. Stage the tree as hard links with the symlinks + # followed (the same tree `tar -h` wrote, beside the DerivedData so the + # links stay on one volume); tar then stores each file once and every + # other path as a hard link, which tar -x, aa and + # reuse_app_host_products.py all extract. Same files, 572 MB, packed + # faster. + stage="$(mktemp -d "${CMUX_COMPILE_ADMISSION_DERIVED_DATA%/*}/.product-pack.XXXXXX")" + trap 'rm -rf "$stage"' EXIT + (cd "$CMUX_COMPILE_ADMISSION_DERIVED_DATA" && pax -rwlL Build/Products "$stage") + COPYFILE_DISABLE=1 tar -cf - -C "$stage" Build/Products | gzip -1 > "$archive" echo "sha256=$(shasum -a 256 "$archive" | awk '{print $1}')" >> "$GITHUB_OUTPUT" # Three days, as admission keeps its own: a pull request only matches diff --git a/.github/workflows/test-e2e.yml b/.github/workflows/test-e2e.yml index c581b9a1e24f..f538e912b779 100644 --- a/.github/workflows/test-e2e.yml +++ b/.github/workflows/test-e2e.yml @@ -644,7 +644,19 @@ jobs: # (Build/._Products) for Xcode's xattrs. macOS tar folds them back # in on extract, so the test job never noticed, but cross-run reuse # extracts with Python and rejects them as unscoped paths. - COPYFILE_DISABLE=1 tar -chf - -C "$CMUX_DERIVED_DATA_PATH" Build/Products | gzip -1 > "$archive" + # Build/Products reaches each framework binary through Versions/Current + # symlinks, and product extractors accept no symlinks, so `tar -h` stored + # every framework binary three times: 1.9 GB on disk became 2.7 GB of + # tar and 830 MB gzipped. Stage the tree as hard links with the symlinks + # followed (the same tree `tar -h` wrote, beside the DerivedData so the + # links stay on one volume); tar then stores each file once and every + # other path as a hard link, which tar -x, aa and + # reuse_app_host_products.py all extract. Same files, 572 MB, packed + # faster. + stage="$(mktemp -d "${CMUX_DERIVED_DATA_PATH%/*}/.product-pack.XXXXXX")" + trap 'rm -rf "$stage"' EXIT + (cd "$CMUX_DERIVED_DATA_PATH" && pax -rwlL Build/Products "$stage") + COPYFILE_DISABLE=1 tar -cf - -C "$stage" Build/Products | gzip -1 > "$archive" echo "sha256=$(shasum -a 256 "$archive" | awk '{print $1}')" >> "$GITHUB_OUTPUT" echo "bytes=$(wc -c < "$archive" | tr -d ' ')" >> "$GITHUB_OUTPUT"