From 6bf3d5acc7ba8ba259d9d9b937cf24a9e2cc59d7 Mon Sep 17 00:00:00 2001 From: Brian Shand Date: Wed, 15 Oct 2025 13:44:10 +0100 Subject: [PATCH] Capistrano: Do not include macOS extended attributes in tar files --- CHANGELOG.md | 3 +- .../capistrano/macos_bsdtar.rb | 33 +++++++++++++++++++ lib/ndr_dev_support/capistrano/ndr_model.rb | 1 + 3 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 lib/ndr_dev_support/capistrano/macos_bsdtar.rb diff --git a/CHANGELOG.md b/CHANGELOG.md index 87cf022..31fc87b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## [Unreleased] -*no unreleased changes* +### Fixed +* Capistrano: Do not include macOS extended attributes in tar files ## 7.3.4 / 2025-09-26 ### Fixed diff --git a/lib/ndr_dev_support/capistrano/macos_bsdtar.rb b/lib/ndr_dev_support/capistrano/macos_bsdtar.rb new file mode 100644 index 0000000..472e31e --- /dev/null +++ b/lib/ndr_dev_support/capistrano/macos_bsdtar.rb @@ -0,0 +1,33 @@ +require 'capistrano/recipes/deploy/strategy/copy' + +# Do not include macOS extended attributes in capistrano tar files +# +# Without this, the system default tar (bsdtar) creates AppleDouble files with a +# ._ prefix, and the linux default tar (gnutar) generates many warnings such as: +# tar: Ignoring unknown extended header keyword 'LIBARCHIVE.xattr.com.apple.provenance' +# +# This fix works because we compress files only locally, for capistrano deployments. +# If we were compressing files remotely too, we would instead need to selectively +# redefine behaviour for local tar usage vs remote usage, e.g. by adding a +# :copy_local_tar_options variable, similar to :copy_local_tar +module CopyMacosTarSupport + private + + def compress(directory, file) + if compression.compress_command[0] == 'tar' && local_tar_is_macos_bsdtar? + return macos_bsdtar_compress(directory, file) + end + + super + end + + def local_tar_is_macos_bsdtar? + RUBY_PLATFORM =~ /darwin/ && system('tar --version | grep -q ^bsdtar') + end + + def macos_bsdtar_compress(directory, file) + compression.compress_command + [file, '--no-xattr', '--no-mac-metadata', directory] + end +end + +Capistrano::Deploy::Strategy::Copy.prepend(CopyMacosTarSupport) diff --git a/lib/ndr_dev_support/capistrano/ndr_model.rb b/lib/ndr_dev_support/capistrano/ndr_model.rb index 41a642c..7d25618 100644 --- a/lib/ndr_dev_support/capistrano/ndr_model.rb +++ b/lib/ndr_dev_support/capistrano/ndr_model.rb @@ -4,6 +4,7 @@ require_relative 'assets' require_relative 'deploy_secrets' require_relative 'install_ruby' +require_relative 'macos_bsdtar' require_relative 'preinstall' require_relative 'restart' require_relative 'revision_logger'