Unfortunately some pluginPlugin A plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party authors accidentally create tag-inception by copying their entire plugins repo into a tag (ie. copy /name/
to /name/tags/1.0/
) which results in nested tags (/name/tags/1.0/tags/0.9/
, etc). Doing this multiple times causes the SVNSVN Apache Subversion (often abbreviated SVN, after its command name svn) is a software versioning and revision control system. Software developers use Subversion to maintain current and historical versions of files such as source code, web pages, and documentation. Its goal is to be a mostly compatible successor to the widely used Concurrent Versions System (CVS). WordPress core and the wordpress.org released code are all centrally managed through SVN. https://subversion.apache.org/. path to ballon in size (each tagged version it effectively doubles in size) causing plugin export issues / server resource issues eventually.
For some background on this, see this private slack discussion: https://wordpress.slack.com/archives/G02QCEMRY/p1740180642033019
There have been numerous plugins that have run into this, so it’s not just a single author.
To reduce the impact of this, I’ve added a check on the code side to abort when a tag does not contain any files. See https://meta.trac.wordpress.org/changeset/14432
To completely prevent this, can we please add a pre-commit hook to blockBlock Block is the abstract term used to describe units of markup that, composed together, form the content or layout of a webpage using the WordPress editor. The idea combines concepts of what in the past may have achieved with shortcodes, custom HTML, and embed discovery into a single consistent API and user experience. it entirely?
Some lightly tested rules I’ve put together follow.. I do not know how expensive the svnlook tree
commands are within a pre-commit rule. Now that I look at it again, I could’ve probably used --full-paths
or --non-recursive
potentially to reduce complexity.
# Iterate over all the added tags in the commit, checking each one for various common issues.
$SVNLOOK changed -t "$TXN" "$REPOS" | \
grep -Eoi "^A\s+[^/]+/tags/[^/]+" | \
sort | \
uniq | \
while read TAGSTATUS TAGPATH
do
TREE=$($SVNLOOK tree -t "$TXN" "$REPOS" "$TAGPATH")
# Perform some basic checks that the created tag looks valid.
# grep || () is used as it'll match the tag folder itself if invert is used.
# grep -E "^[ ] matches immediate files within the tag folder, not in child folders.
# 1. Look for a readme.txt file in the created tag at the root-level of the tag.
echo "$TREE" | \
grep -Ei "^[ ]readme.(md|txt)$" || ( \
echo "Malformed tag detected, It looks like you're creating a tag ($TAGPATH) without a readme file present." >&2 && \
exit 1
)
# 2. The tag MUST have at least one PHP file in the root.
echo "$TREE" | \
grep -Ei "^[ ][^ ].+\.php$" || ( \
echo "Malformed tag detected, It looks like you're creating a tag ($TAGPATH) without any PHP files." >&2 && \
exit 1
)
# 3. Check for a nested tags folder inside a tagged version.
# folders called 'tags' are allowed within sub-folders of the plugin, just not at the tag level.
# Not allowed: plugin-name/tags/1.0/tags/
# Allowed: plugin-name/tags/1.0/features/tags/index.php
echo "$TREE" | \
grep -Ei "^[ ]tags/" && \
echo "Malformed tag detected, Please don't nest tags within a tag ($TAGPATH/tags/)." >&2 && \
exit 1
done
I would personally just go with 1 & 2, but 3 is possible to prevent issues.
– 1 & 2 just check that there’s a readme and php file present in the tag, this should prevent 99% of invalid tag creations. This enforces that the tags created actually have content.
– 3 is probably not needed with the above (This was my first attempt at a rule) but it prevents a nested tags folder inside a tag. There’s a slim chance of blocking a valid commit with a plugin with a folder called ‘tags’ but might be worth it to prevent this kind of thing in the future.