Skip to content

Commit 4e810c8

Browse files
authored
Merge pull request #106 from ether/fix/pipelines
Fixed.
2 parents 17d2c0a + af2b158 commit 4e810c8

File tree

10 files changed

+2334
-2903
lines changed

10 files changed

+2334
-2903
lines changed

.eslintrc.cjs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,8 @@ require('eslint-config-etherpad/patch/modern-module-resolution');
55

66
module.exports = {
77
root: true,
8+
rules:{
9+
'no-extraneous-require': 'off', // Turn off the rule here
10+
},
811
extends: 'etherpad/plugin',
912
};

.github/workflows/backend-tests.yml

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -29,34 +29,45 @@ jobs:
2929
uses: actions/setup-node@v3
3030
with:
3131
node-version: 20
32-
cache: 'npm'
33-
cache-dependency-path: |
34-
etherpad/src/package-lock.json
35-
etherpad/src/bin/doc/package-lock.json
36-
plugin/package-lock.json
37-
- run: npm install [email protected] -g
38-
name: Install legacy npm for correct dependency resolution
32+
- uses: pnpm/action-setup@v3
33+
name: Install pnpm
34+
with:
35+
version: 8
36+
run_install: false
37+
- name: Get pnpm store directory
38+
shell: bash
39+
run: |
40+
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
41+
- uses: actions/cache@v4
42+
name: Setup pnpm cache
43+
with:
44+
path: ${{ env.STORE_PATH }}
45+
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
46+
restore-keys: |
47+
${{ runner.os }}-pnpm-store-
3948
-
4049
name: Prepare Etherpad core
4150
run: |
4251
cd ./etherpad/src
43-
npm ci
44-
npm link
52+
./bin/installDeps.sh
53+
pnpm link --global
54+
ls -lisa ../node_modules
4555
-
4656
name: Prepare plugin
4757
run: |
58+
pnpm config set auto-install-peers false
4859
cd ./plugin
4960
PLUGIN_NAME=$(npx -c 'printf %s\\n "${npm_package_name}"') || exit 1
50-
npm ci
51-
npm link
52-
npm link ep_etherpad-lite
53-
cd ../etherpad
54-
npm link "${PLUGIN_NAME}"
61+
pnpm i
62+
pnpm link --global
63+
pnpm link --global ep_etherpad-lite
64+
cd ../etherpad/src
65+
pnpm link --global "${PLUGIN_NAME}"
5566
# Rename to match the glob pattern passed to mocha.
56-
mv node_modules/"${PLUGIN_NAME}" node_modules/ep_client
67+
ln -s ../src/node_modules/${PLUGIN_NAME} ../node_modules/ep_client
5768
-
5869
name: Remove core tests so only the client is tested
5970
run: rm -rf ./etherpad/src/tests/backend/specs
6071
-
6172
name: Run the backend tests
62-
run: cd ./etherpad/src && npm test
73+
run: cd ./etherpad/src && pnpm test

.github/workflows/npmpublish.yml

Lines changed: 56 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -14,64 +14,57 @@ jobs:
1414
test:
1515
runs-on: ubuntu-latest
1616
steps:
17-
# Clone ether/etherpad-lite to ../etherpad-lite so that ep_etherpad-lite
18-
# can be "installed" in this plugin's node_modules. The checkout v2 action
19-
# doesn't support cloning outside of $GITHUB_WORKSPACE (see
20-
# https://github.com/actions/checkout/issues/197), so the repo is first
21-
# cloned to etherpad-lite then moved to ../etherpad-lite. To avoid
22-
# conflicts with this plugin's clone, etherpad-lite must be cloned and
23-
# moved out before this plugin's repo is cloned to $GITHUB_WORKSPACE.
2417
-
2518
uses: actions/checkout@v4
2619
with:
2720
repository: ether/etherpad-lite
2821
path: etherpad-lite
2922
-
3023
run: mv etherpad-lite ..
31-
# etherpad-lite has been moved outside of $GITHUB_WORKSPACE, so it is now
32-
# safe to clone this plugin's repo to $GITHUB_WORKSPACE.
3324
-
3425
uses: actions/checkout@v4
35-
# This is necessary for actions/setup-node because '..' can't be used in
36-
# cache-dependency-path.
37-
-
38-
name: Create ep_etherpad-lite symlink
39-
run: |
40-
mkdir -p node_modules
41-
ln -s ../../etherpad-lite/src node_modules/ep_etherpad-lite
4226
-
4327
uses: actions/setup-node@v3
4428
with:
4529
node-version: 20
46-
cache: 'npm'
47-
cache-dependency-path: |
48-
node_modules/ep_etherpad-lite/package-lock.json
49-
node_modules/ep_etherpad-lite/bin/doc/package-lock.json
50-
package-lock.json
51-
- run: npm install [email protected] -g
52-
name: Install legacy npm for correct dependency resolution
53-
# All of ep_etherpad-lite's devDependencies are installed because the
54-
# plugin might do `require('ep_etherpad-lite/node_modules/${devDep}')`.
55-
# Eventually it would be nice to create an ESLint plugin that prohibits
56-
# Etherpad plugins from piggybacking off of ep_etherpad-lite's
57-
# devDependencies. If we had that, we could change this line to only
58-
# install production dependencies.
59-
-
60-
run: cd ../etherpad-lite/src && npm ci
30+
- uses: pnpm/action-setup@v3
31+
name: Install pnpm
32+
with:
33+
version: 8
34+
run_install: false
35+
- name: Get pnpm store directory
36+
shell: bash
37+
run: |
38+
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
39+
- uses: actions/cache@v4
40+
name: Setup pnpm cache
41+
with:
42+
path: ${{ env.STORE_PATH }}
43+
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
44+
restore-keys: |
45+
${{ runner.os }}-pnpm-store-
6146
-
62-
run: npm ci
63-
# This runs some sanity checks and creates a symlink at
64-
# node_modules/ep_etherpad-lite that points to ../../etherpad-lite/src.
65-
# This step must be done after `npm ci` installs the plugin's dependencies
66-
# because npm "helpfully" cleans up such symlinks. :( Installing
67-
# ep_etherpad-lite in the plugin's node_modules prevents lint errors and
68-
# unit test failures if the plugin does `require('ep_etherpad-lite/foo')`.
47+
run: cd ../etherpad-lite/src && ./bin/installDeps.sh && pnpm link --global
6948
-
70-
run: npm install --no-save ep_etherpad-lite@file:../etherpad-lite/src
49+
run: |
50+
pnpm config set auto-install-peers false
51+
pnpm i
7152
-
72-
run: npm test
53+
run: pnpm link --global ep_etherpad-lite
7354
-
74-
run: npm run lint
55+
run: |
56+
has_testcli_script () {
57+
[[ $(pnpm run | grep "^ test" | wc -l) > 0 ]]
58+
}
59+
60+
if has_testcli_script; then
61+
pnpm run test
62+
else
63+
echo "No test script found"
64+
fi
65+
name: Run tests if available
66+
-
67+
run: pnpm run lint
7568

7669
publish-npm:
7770
if: github.event_name == 'push'
@@ -87,9 +80,24 @@ jobs:
8780
with:
8881
node-version: 20
8982
registry-url: https://registry.npmjs.org/
90-
cache: 'npm'
91-
- run: npm install [email protected] -g
92-
name: Install legacy npm for correct dependency resolution
83+
- uses: pnpm/action-setup@v3
84+
name: Install pnpm
85+
with:
86+
version: 8
87+
run_install: false
88+
- name: Get pnpm store directory
89+
shell: bash
90+
run: |
91+
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
92+
- uses: actions/cache@v4
93+
name: Setup pnpm cache
94+
with:
95+
path: ${{ env.STORE_PATH }}
96+
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
97+
restore-keys: |
98+
${{ runner.os }}-pnpm-store-
99+
- name: Only install direct dependencies
100+
run: pnpm config set auto-install-peers false
93101
-
94102
name: Bump version (patch)
95103
run: |
@@ -98,25 +106,13 @@ jobs:
98106
[ "${NEW_COMMITS}" -gt 0 ] || exit 0
99107
git config user.name 'github-actions[bot]'
100108
git config user.email '41898282+github-actions[bot]@users.noreply.github.com'
101-
npm ci
102-
npm version patch
109+
pnpm i
110+
pnpm version patch
103111
git push --follow-tags
104-
# This is required if the package has a prepare script that uses something
105-
# in dependencies or devDependencies.
106112
-
107-
run: npm ci
108-
# `npm publish` must come after `git push` otherwise there is a race
109-
# condition: If two PRs are merged back-to-back then master/main will be
110-
# updated with the commits from the second PR before the first PR's
111-
# workflow has a chance to push the commit generated by `npm version
112-
# patch`. This causes the first PR's `git push` step to fail after the
113-
# package has already been published, which in turn will cause all future
114-
# workflow runs to fail because they will all attempt to use the same
115-
# already-used version number. By running `npm publish` after `git push`,
116-
# back-to-back merges will cause the first merge's workflow to fail but
117-
# the second's will succeed.
113+
run: pnpm i
118114
-
119-
run: npm publish
115+
run: pnpm publish
120116
env:
121117
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
122118
-

.npmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
auto-install-peers=false

lib/index.js

Lines changed: 57 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,17 @@ const AttributePool = require('./AttributePool');
66
const assert = require('assert');
77
const superagent = require('superagent');
88

9+
10+
const randomString = (len = 10) => {
11+
const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
12+
let randomstring = '';
13+
for (let i = 0; i < len; i++) {
14+
const rnum = Math.floor(Math.random() * chars.length);
15+
randomstring += chars.substring(rnum, rnum + 1);
16+
}
17+
return randomstring;
18+
};
19+
920
exports.connect = (host) => {
1021
// Create an event emitter
1122
const ee = new EventEmitter();
@@ -24,8 +35,8 @@ exports.connect = (host) => {
2435
const padIdParam = '/p/';
2536
const indexOfPadId = parsed.pathname.indexOf(padIdParam);
2637
if (indexOfPadId >= 0) {
27-
padState.path = parsed.pathname.substring(0, indexOfPadId)
28-
padState.padId = parsed.pathname.substring(indexOfPadId + padIdParam.length)
38+
padState.path = parsed.pathname.substring(0, indexOfPadId);
39+
padState.padId = parsed.pathname.substring(indexOfPadId + padIdParam.length);
2940
} else {
3041
padState.path = '';
3142
padState.padId = randomString();
@@ -63,10 +74,54 @@ exports.connect = (host) => {
6374
socket.json.send(msg);
6475
});
6576

77+
78+
// sends a message to the server.
79+
// Can be used without parameters to try sending outgoing message
80+
const sendMessage = (optMsg) => {
81+
// console.log("sending message: ",
82+
// optMsg && (optMsg.changeset + '[' + optMsg.baseRev + ']'),
83+
// '; inflight: ' + (padState.inFlight && (
84+
// padState.inFlight.changeset + '[' + padState.inFlight.baseRev + ']')),
85+
// '; outgoing: ' + (padState.outgoing && (
86+
// padState.outgoing.changeset + '[' + padState.outgoing.baseRev + ']'))
87+
// );
88+
if (optMsg) {
89+
if (padState.outgoing) {
90+
assert(optMsg.baseRev === padState.outgoing.baseRev,
91+
'should append to the same document version');
92+
93+
padState.outgoing.changeset = Changeset.compose(
94+
padState.outgoing.changeset, optMsg.changeset, padState.apool);
95+
} else {
96+
padState.outgoing = optMsg;
97+
}
98+
}
99+
100+
if (!padState.inFlight && padState.outgoing) {
101+
padState.inFlight = padState.outgoing;
102+
padState.outgoing = null;
103+
socket.json.send({
104+
type: 'COLLABROOM',
105+
component: 'pad',
106+
data: JSON.parse(JSON.stringify(padState.inFlight)),
107+
});
108+
}
109+
};
110+
66111
socket.on('message', (obj) => {
67112
// message emitter sends all messages should they be required
68113
ee.emit('message', obj);
69114

115+
// Both server and client edited the document.
116+
// We need to update local change with remote changes
117+
// and visa versa
118+
const transformX = (client, server) => {
119+
const _c = Changeset.follow(server.changeset, client.changeset, false, padState.pool);
120+
const _s = Changeset.follow(client.changeset, server.changeset, true, padState.pool);
121+
client.changeset = _c;
122+
server.changeset = _s;
123+
};
124+
70125

71126
// Client is connected so we should start sending messages at the server
72127
if (obj.type === 'CLIENT_VARS') {
@@ -175,57 +230,6 @@ exports.connect = (host) => {
175230
};
176231
sendMessage(msg);
177232
};
178-
179-
// Both server and client edited the document.
180-
// We need to update local change with remote changes
181-
// and visa versa
182-
const transformX = (client, server) => {
183-
const _c = Changeset.follow(server.changeset, client.changeset, false, padState.pool);
184-
const _s = Changeset.follow(client.changeset, server.changeset, true, padState.pool);
185-
client.changeset = _c;
186-
server.changeset = _s;
187-
};
188-
189-
// sends a message to the server. Can be used without parameters to try sending outgoing message
190-
const sendMessage = (optMsg) => {
191-
// console.log("sending message: ", optMsg && (optMsg.changeset + '[' + optMsg.baseRev + ']'),
192-
// '; inflight: ' + (padState.inFlight && (
193-
// padState.inFlight.changeset + '[' + padState.inFlight.baseRev + ']')),
194-
// '; outgoing: ' + (padState.outgoing && (
195-
// padState.outgoing.changeset + '[' + padState.outgoing.baseRev + ']'))
196-
// );
197-
if (optMsg) {
198-
if (padState.outgoing) {
199-
assert(optMsg.baseRev === padState.outgoing.baseRev,
200-
'should append to the same document version');
201-
202-
padState.outgoing.changeset = Changeset.compose(
203-
padState.outgoing.changeset, optMsg.changeset, padState.apool);
204-
} else {
205-
padState.outgoing = optMsg;
206-
}
207-
}
208-
209-
if (!padState.inFlight && padState.outgoing) {
210-
padState.inFlight = padState.outgoing;
211-
padState.outgoing = null;
212-
socket.json.send({
213-
type: 'COLLABROOM',
214-
component: 'pad',
215-
data: JSON.parse(JSON.stringify(padState.inFlight)),
216-
});
217-
}
218-
};
219233
});
220234
return ee;
221235
};
222-
223-
const randomString = (len = 10) => {
224-
const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
225-
let randomstring = '';
226-
for (let i = 0; i < len; i++) {
227-
const rnum = Math.floor(Math.random() * chars.length);
228-
randomstring += chars.substring(rnum, rnum + 1);
229-
}
230-
return randomstring;
231-
};

0 commit comments

Comments
 (0)