CI / lint (push) Successful in 2s
CI / extension-version (push) Successful in 3s
extension / lint (push) Successful in 19s
CI / frontend-build (push) Successful in 20s
CI / backend-lint-and-test (push) Successful in 38s
CI / integration (push) Successful in 3m57s
extension / lint (pull_request) Successful in 34s
The XPI-content check added in 1c6452e did its job on its first run: the
archive carried empty `test/` and `scripts/` entries.
`test/**` matches the files inside a directory but not the directory entry
itself, and web-ext writes an entry for the directory separately -- so the
contents were correctly excluded while the empty directories shipped anyway.
Nothing harmful reached users (no dev code, just two empty entries), but our
single declaration claimed these do not ship and something was shipping.
Both forms are now listed per directory. The bare name alone would not do:
minimatch's `test` does not match `test/url.spec.js`, so dropping the glob
would ship the contents instead.
Verified locally: the derived version is unchanged at 1.0.19, confirming the
added entries are redundant for the git pathspec and only affect web-ext.
Refs #2400
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
100 lines
4.0 KiB
Bash
Executable File
100 lines
4.0 KiB
Bash
Executable File
#!/bin/sh
|
|
# Single source of truth for "what ships inside the XPI", plus the version
|
|
# derived from it.
|
|
#
|
|
# Three consumers used to hand-maintain their own copy of this list, and
|
|
# keeping three copies of one fact in sync by hand is how issue #2397 happened:
|
|
#
|
|
# 1. web-ext's --ignore-files (extension/package.json's four scripts)
|
|
# 2. the :(exclude) pathspec (ci.yml's extension-version guard)
|
|
# 3. the rev-list pathspec (the derived version, below)
|
|
#
|
|
# They now all read from here. POSIX sh only — CI's run shell is busybox.
|
|
#
|
|
# -f (no pathname expansion) is set for the whole script and is load-bearing:
|
|
# the lists below are iterated with deliberate word-splitting, and without -f
|
|
# the shell would also GLOB them, expanding `test/**` into whatever files
|
|
# happen to exist and corrupting the output. A caller's own `set -f` does not
|
|
# help here — this runs as a separate sh process and does not inherit it.
|
|
# Callers still need their own `set -f` for the substituted result; the two
|
|
# guards protect different expansions.
|
|
set -euf
|
|
|
|
# Paths under extension/ that are NOT packaged into the XPI.
|
|
#
|
|
# Split by whether git tracks them: node_modules and web-ext-artifacts are
|
|
# build/dependency output that never appears in a commit, so they belong in
|
|
# web-ext's ignore list but would be meaningless in a git pathspec.
|
|
#
|
|
# Directories need BOTH forms. `test/**` matches the files inside, but not the
|
|
# directory entry itself — web-ext writes an entry for the directory too, so
|
|
# with only the glob the XPI ends up carrying empty `test/` and `scripts/`
|
|
# entries (caught by the XPI-content check on 2026-08-03). The bare name alone
|
|
# is not enough either: minimatch's `test` does not match `test/url.spec.js`,
|
|
# so dropping the glob would ship the contents. Keep both.
|
|
NOT_PACKAGED_TRACKED='package.json package-lock.json README.md .gitignore vitest.config.js scripts scripts/** test test/**'
|
|
NOT_PACKAGED_BUILD='web-ext-artifacts node_modules'
|
|
|
|
usage() {
|
|
echo "usage: packaging.sh {ignore|pathspec|version|major-minor|patch}" >&2
|
|
exit 2
|
|
}
|
|
|
|
# web-ext --ignore-files values, space-separated.
|
|
#
|
|
# Callers MUST disable pathname expansion first (`set -f`), or the shell will
|
|
# glob `test/**` against the working tree before web-ext ever sees the pattern
|
|
# and silently narrow it to whatever happens to exist right now.
|
|
cmd_ignore() {
|
|
echo "$NOT_PACKAGED_TRACKED $NOT_PACKAGED_BUILD"
|
|
}
|
|
|
|
# git pathspec excluding the non-packaged tracked files, e.g.
|
|
# :(exclude)extension/package.json :(exclude)extension/test/**
|
|
# Same `set -f` requirement as above.
|
|
cmd_pathspec() {
|
|
for entry in $NOT_PACKAGED_TRACKED; do
|
|
printf ':(exclude)extension/%s ' "$entry"
|
|
done
|
|
echo
|
|
}
|
|
|
|
# MAJOR.MINOR stays hand-set in manifest.json — it's the part that carries
|
|
# deliberate meaning. Only the patch component is derived.
|
|
cmd_major_minor() {
|
|
root=$(git rev-parse --show-toplevel)
|
|
grep -E '"version"' "$root/extension/manifest.json" \
|
|
| head -1 \
|
|
| sed -E 's/.*"version"[[:space:]]*:[[:space:]]*"([0-9]+)\.([0-9]+).*/\1.\2/'
|
|
}
|
|
|
|
# Count of commits that touched a PACKAGED extension file. Monotonic on a
|
|
# branch (the count only grows), which is a correctness requirement, not a
|
|
# nicety: Firefox refuses to install a version lower than the one present.
|
|
#
|
|
# Merge commits need no special handling — git's history simplification already
|
|
# prunes merges that don't change the pathspec, so --no-merges is a no-op here
|
|
# (verified on main: both forms return the same count).
|
|
cmd_patch() {
|
|
root=$(git rev-parse --show-toplevel)
|
|
# Unquoted on purpose: the pathspec must word-split into separate args.
|
|
# Globbing is already off script-wide (set -euf above).
|
|
# shellcheck disable=SC2046
|
|
count=$(cd "$root" && git rev-list --count HEAD -- extension/ $(cmd_pathspec))
|
|
echo "$count"
|
|
}
|
|
|
|
cmd_version() {
|
|
echo "$(cmd_major_minor).$(cmd_patch)"
|
|
}
|
|
|
|
[ $# -ge 1 ] || usage
|
|
case "$1" in
|
|
ignore) cmd_ignore ;;
|
|
pathspec) cmd_pathspec ;;
|
|
version) cmd_version ;;
|
|
major-minor) cmd_major_minor ;;
|
|
patch) cmd_patch ;;
|
|
*) usage ;;
|
|
esac
|