Skip to content

Commit a7603b1

Browse files
committed
feat(tool): Speed up tarball creation for releases using pigz if available
- Use pigz if available, otherwise use gzip as before
1 parent 75a31d9 commit a7603b1

2 files changed

Lines changed: 54 additions & 1 deletion

File tree

.github/actions/build-fixtures/action.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ runs:
3232
id: evm-builder
3333
with:
3434
type: ${{ steps.properties.outputs.evm-type }}
35+
- name: Install pigz for parallel tarball compression
36+
shell: bash
37+
run: sudo apt-get install -y pigz
3538
- name: Generate fixtures using fill
3639
shell: bash
3740
run: |

packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/fixture_output.py

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""Fixture output configuration for generated test fixtures."""
22

33
import shutil
4+
import subprocess
45
import tarfile
56
from pathlib import Path
67

@@ -219,11 +220,28 @@ def create_directories(self, is_master: bool) -> None:
219220
parents=True, exist_ok=True
220221
)
221222

223+
@staticmethod
224+
def _pigz_available() -> bool:
225+
"""Check if pigz (parallel gzip) is available on the system."""
226+
return shutil.which("pigz") is not None
227+
222228
def create_tarball(self) -> None:
223-
"""Create tarball of the output directory if configured to do so."""
229+
"""
230+
Create tarball of the output directory if configured to do so.
231+
232+
Automatically uses pigz for parallel compression if available,
233+
otherwise falls back to standard single-threaded gzip.
234+
"""
224235
if not self.is_tarball:
225236
return
226237

238+
if self._pigz_available():
239+
self._create_tarball_with_pigz()
240+
else:
241+
self._create_tarball_standard()
242+
243+
def _create_tarball_standard(self) -> None:
244+
"""Create tarball using Python's tarfile module (single-threaded)."""
227245
with tarfile.open(self.output_path, "w:gz") as tar:
228246
for file in self.directory.rglob("*"):
229247
if file.suffix in {".json", ".ini"}:
@@ -232,6 +250,38 @@ def create_tarball(self) -> None:
232250
)
233251
tar.add(file, arcname=arcname)
234252

253+
def _create_tarball_with_pigz(self) -> None:
254+
"""
255+
Create tarball using Python tarfile + pigz for parallel compression.
256+
257+
This approach uses Python's tarfile to create the uncompressed .tar
258+
(which correctly handles arcnames across all platforms), then uses
259+
pigz for parallel gzip compression with auto-detected core count.
260+
"""
261+
# Create uncompressed tar first (output_path minus .gz suffix)
262+
temp_tar = self.output_path.with_suffix("") # Remove .gz suffix
263+
264+
try:
265+
# Use Python tarfile for cross-platform tar creation with arcnames
266+
with tarfile.open(temp_tar, "w") as tar:
267+
for file in self.directory.rglob("*"):
268+
if file.suffix in {".json", ".ini"}:
269+
arcname = Path("fixtures") / file.relative_to(
270+
self.directory
271+
)
272+
tar.add(file, arcname=arcname)
273+
274+
# Compress with pigz (parallel gzip, auto-detects available cores)
275+
subprocess.run(
276+
["pigz", "-f", str(temp_tar)], check=True, capture_output=True
277+
)
278+
except subprocess.CalledProcessError:
279+
# Clean up temp file if it exists
280+
if temp_tar.exists():
281+
temp_tar.unlink()
282+
# Fall back to standard tarball creation
283+
self._create_tarball_standard()
284+
235285
@classmethod
236286
def from_config(cls, config: pytest.Config) -> "FixtureOutput":
237287
"""Create a FixtureOutput instance from pytest configuration."""

0 commit comments

Comments
 (0)