Deploy drops directories preserved via `.keep` + gitignore negation patterns
miren deploy drops directories that are kept in source control via the common pattern of "ignore the directory contents but keep the directory itself with a .keep file." This breaks Ruby/Rails-style apps that rely on tmp/pids/, log/, etc. existing at runtime.
Repro
A vanilla bridgetown new app ships with this .gitignore:
/tmp/*
!/tmp/.keep
/tmp/pids/*
!/tmp/pids/
!/tmp/pids/.keep
…and config/puma.rb writes its pidfile to tmp/pids/server.pid. Deploy succeeds, but Puma fails to boot:
puma/launcher.rb:328: No such file or directory @ rb_sysopen - tmp/pids/server.pid (Errno::ENOENT)
Originally reported by Javier Cervantes against solojavier/mysite. Reproduced end-to-end against the local dev server, plus a failing unit test (TestMakeTarBridgetownTmpPids in pkg/tarx/tarx_test.go) that pins the bug at the tar layer.
Root cause
In pkg/tarx/tarx.go:48-78, isGitignored for directories tries both forms of the path:
paths := []string{relPath}
if isDir {
paths = append(paths, relPath+"/")
}
for _, checkPath := range paths {
ignore, _ := pathspec.GitIgnore(patterns, checkPath)
if ignore {
return true, nil // short-circuits
}
}
For tmp/pids (no slash), /tmp/* matches and the trailing-slash negation !/tmp/pids/ does not. The loop short-circuits before checking the trailing-slash form, the walker hits filepath.SkipDir at tarx.go:313, and .keep is never visited. The directory is absent from the deploy tar.
Fix shape
For directories, only check the trailing-slash form (the canonical form for gitignore directory matching). Negation patterns ending in / are explicitly directory-only and are how you re-include directories.
Impact
Affects any app following the Rails/Bridgetown convention of preserving runtime directories with .keep plus a re-include negation. Easy to hit on first-time deploy, hard to debug from runtime logs alone.