@@ -128,7 +128,7 @@ jobs:
128128 run : |
129129 set -eux
130130 # Ubuntu's default apt nodejs is 18 — too old for our
131- # `Depends: nodejs (>= 22 )`. Add NodeSource's apt repo
131+ # `Depends: nodejs (>= 24 )`. Add NodeSource's apt repo
132132 # explicitly (key + sources.list) instead of `curl | sudo bash`
133133 # so we don't execute network-fetched code as root.
134134 NODE_MAJOR=24
@@ -137,7 +137,7 @@ jobs:
137137 # existing nodesource entries so the only Node candidate apt sees
138138 # is our node_24.x repo. Otherwise `apt-get install -y nodejs`
139139 # picks the higher-version 20.x build that's already cached and
140- # `dpkg -i` then fails on `Depends: nodejs (>= 22 )`.
140+ # `dpkg -i` then fails on `Depends: nodejs (>= 24 )`.
141141 sudo rm -f /etc/apt/sources.list.d/nodesource.list \
142142 /etc/apt/sources.list.d/nodesource.sources \
143143 /etc/apt/preferences.d/nodesource \
@@ -172,10 +172,14 @@ jobs:
172172 sudo test -L /opt/etherpad/settings.json
173173 sudo test -L /opt/etherpad/var
174174 [ "$(sudo readlink /opt/etherpad/var)" = "/var/lib/etherpad/var" ]
175- sudo test -L /opt/etherpad/src/plugin_packages
176- [ "$(sudo readlink /opt/etherpad/src/plugin_packages)" = "/var/lib/etherpad/plugin_packages" ]
177- sudo test -d /var/lib/etherpad/plugin_packages
178- [ "$(sudo stat -c '%U' /var/lib/etherpad/plugin_packages)" = "etherpad" ]
175+ # plugin_packages must stay in-tree -- Node.js resolves symlinks
176+ # to realpath before walking node_modules, so symlinking it
177+ # outside /opt broke require("ep_etherpad-lite/...") in
178+ # admin-installed plugins (ether/ep_comments_page#416).
179+ sudo test -d /opt/etherpad/src/plugin_packages
180+ sudo test ! -L /opt/etherpad/src/plugin_packages
181+ [ "$(sudo stat -c '%G' /opt/etherpad/src/plugin_packages)" = "etherpad" ]
182+ [ "$(sudo stat -c '%a' /opt/etherpad/src/plugin_packages)" = "2775" ]
179183 [ "$(stat -c '%G' /opt/etherpad/src/node_modules)" = "etherpad" ]
180184 sudo test -f /var/lib/etherpad/var/installed_plugins.json
181185 sudo grep -q '"ep_etherpad-lite"' /var/lib/etherpad/var/installed_plugins.json
@@ -197,8 +201,71 @@ jobs:
197201 exit 1
198202 fi
199203 sudo systemctl stop etherpad
204+ # Regression: simulate a pre-fix install (plugin_packages as a
205+ # symlink to /var/lib/etherpad/plugin_packages, with a marker
206+ # plugin inside) and re-run the postinst. The new postinst must
207+ # migrate the contents back in-tree and drop the symlink so
208+ # admin-installed plugins keep resolving ep_etherpad-lite
209+ # (ether/ep_comments_page#416).
210+ sudo rm -rf /opt/etherpad/src/plugin_packages
211+ sudo mkdir -p /var/lib/etherpad/plugin_packages/.versions/ep_migration_marker
212+ echo '{"name":"ep_migration_marker"}' | \
213+ sudo tee /var/lib/etherpad/plugin_packages/.versions/ep_migration_marker/package.json >/dev/null
214+ sudo chown -R etherpad:etherpad /var/lib/etherpad/plugin_packages
215+ sudo ln -sfn /var/lib/etherpad/plugin_packages /opt/etherpad/src/plugin_packages
216+ sudo dpkg-reconfigure etherpad
217+ sudo test -d /opt/etherpad/src/plugin_packages
218+ sudo test ! -L /opt/etherpad/src/plugin_packages
219+ sudo test -f /opt/etherpad/src/plugin_packages/.versions/ep_migration_marker/package.json
220+ [ "$(sudo stat -c '%a' /opt/etherpad/src/plugin_packages)" = "2775" ]
221+
222+ # Regression: stage the ep_layout_trip_wire test fixture into
223+ # plugin_packages and confirm etherpad loads it. The fixture's
224+ # index.js does the require('ep_etherpad-lite/...') calls that
225+ # broke under the old symlinked layout (#416). If the layout
226+ # ever regresses, the marker line never reaches the journal
227+ # and this step fails.
228+ PLUGIN_DIR=/opt/etherpad/src/plugin_packages
229+ FIXTURE_DIR=$GITHUB_WORKSPACE/packaging/test-fixtures/ep_layout_trip_wire
230+ sudo install -d -o etherpad -g etherpad -m 2775 "${PLUGIN_DIR}/.versions"
231+ sudo cp -a "${FIXTURE_DIR}" "${PLUGIN_DIR}/.versions/ep_layout_trip_wire@1.0.0"
232+ sudo ln -sfn .versions/ep_layout_trip_wire@1.0.0 "${PLUGIN_DIR}/ep_layout_trip_wire"
233+ sudo ln -sfn ../plugin_packages/ep_layout_trip_wire \
234+ /opt/etherpad/src/node_modules/ep_layout_trip_wire
235+ sudo chown -R etherpad:etherpad "${PLUGIN_DIR}/.versions/ep_layout_trip_wire@1.0.0" \
236+ "${PLUGIN_DIR}/ep_layout_trip_wire" \
237+ /opt/etherpad/src/node_modules/ep_layout_trip_wire
238+ echo '{"plugins":[{"name":"ep_etherpad-lite","version":"0.0.0"},{"name":"ep_layout_trip_wire","version":"1.0.0"}]}' \
239+ | sudo tee /var/lib/etherpad/var/installed_plugins.json >/dev/null
240+ sudo chown etherpad:etherpad /var/lib/etherpad/var/installed_plugins.json
241+ sudo systemctl start etherpad
242+ ok=
243+ for i in $(seq 1 30); do
244+ if curl -fsS http://127.0.0.1:9001/health; then ok=1; break; fi
245+ sleep 2
246+ done
247+ if [ -z "${ok}" ]; then
248+ sudo journalctl -u etherpad --no-pager -n 300 || true
249+ exit 1
250+ fi
251+ # Marker proves the require('ep_etherpad-lite/...') calls in
252+ # the fixture's index.js all resolved.
253+ sudo journalctl -u etherpad --no-pager -n 500 \
254+ | grep -F 'ep_layout_trip_wire: plugin_packages layout OK'
255+ # And no MODULE_NOT_FOUND involving ep_etherpad-lite, anywhere.
256+ if sudo journalctl -u etherpad --no-pager -n 500 \
257+ | grep -E "Cannot find module '?ep_etherpad-lite"; then
258+ echo "::error::ep_etherpad-lite require failed inside an installed plugin"
259+ exit 1
260+ fi
261+ sudo systemctl stop etherpad
262+
200263 sudo dpkg --purge etherpad
201264 ! id etherpad 2>/dev/null
265+ # Purge must clean up runtime-created plugin artifacts that
266+ # dpkg didn't ship (ether/ep_comments_page#416, Qodo #3).
267+ sudo test ! -e /opt/etherpad/src/plugin_packages
268+ sudo test ! -e /var/lib/etherpad
202269
203270 - name : Upload artifact
204271 uses : actions/upload-artifact@v7
0 commit comments