Skip to content

Commit e750d04

Browse files
committed
ci: drive the experiment from branch pushes (workflow_dispatch needs default branch)
1 parent bbf8dc6 commit e750d04

4 files changed

Lines changed: 189 additions & 0 deletions

File tree

.github/workflows/CI-windows-install-experiment.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ name: CI windows install experiment
1010

1111
on:
1212
workflow_dispatch:
13+
# workflow_dispatch only works from the default branch, and this harness is
14+
# deliberately not on master, so drive it from pushes to its own branch.
15+
push:
16+
branches:
17+
- 'ci/windows-global-install-136'
1318

1419
jobs:
1520
measure:

edit_options.json

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
{
2+
"settings": {
3+
"challenges": [
4+
{
5+
"name": "publication-match",
6+
"options": {
7+
"matches": "[{\"propertyName\":\"author.name\",\"regexp\":\"\\\\.(bso)$\"}]",
8+
"error": "Posting in this community requires a name that ends with .bso Go to the settings to set your username."
9+
},
10+
"exclude": [
11+
{ "role": ["moderator", "admin", "owner"] },
12+
{
13+
"postScore": 3,
14+
"replyScore": 0,
15+
"firstCommentTimestamp": 2592000,
16+
"rateLimit": 2
17+
},
18+
{ "challenges": [1] },
19+
{ "challenges": [2] }
20+
],
21+
"pendingApproval": false
22+
},
23+
{
24+
"name": "whitelist",
25+
"options": {
26+
"urls": "https://raw.githubusercontent.com/bitsocialnet/lists/refs/heads/master/whitelist-challenge.json",
27+
"error": "Or posting in this community requires being whitelisted. Go to https://t.me/bitsocialnet and ask to be whitelisted."
28+
},
29+
"exclude": [{ "role": ["moderator", "admin", "owner"] }, { "challenges": [0] }, { "challenges": [2] }],
30+
"pendingApproval": false
31+
},
32+
{
33+
"name": "@bitsocial/spam-blocker-challenge",
34+
"options": {
35+
"serverUrl": "https://spamblocker.bitsocial.net/api/v1",
36+
"autoAcceptThreshold": "0.2",
37+
"autoRejectThreshold": "0.8"
38+
},
39+
"exclude": [
40+
{ "challenges": [0] },
41+
{ "challenges": [1] },
42+
{ "role": ["owner", "admin", "moderator"] },
43+
{
44+
"publicationType": {
45+
"commentModeration": true,
46+
"communityEdit": true
47+
}
48+
}
49+
],
50+
"pendingApproval": true
51+
}
52+
]
53+
}
54+
}

scripts/switch-roles-eth-to-bso.sh

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
#!/bin/bash
2+
# Usage:
3+
# ./scripts/switch-roles-eth-to-bso.sh # dry run (preview changes)
4+
# ./scripts/switch-roles-eth-to-bso.sh --apply # apply changes
5+
6+
set -euo pipefail
7+
8+
APPLY=false
9+
if [[ "${1:-}" == "--apply" ]]; then
10+
APPLY=true
11+
else
12+
echo "=== DRY RUN (use --apply to execute) ==="
13+
echo
14+
fi
15+
16+
COMMUNITIES=$(bitsocial community list -q)
17+
18+
if [[ -z "$COMMUNITIES" ]]; then
19+
echo "No communities found."
20+
exit 0
21+
fi
22+
23+
TOTAL_CHANGED=0
24+
25+
while IFS= read -r address; do
26+
[[ -z "$address" ]] && continue
27+
28+
ROLES_JSON=$(bitsocial community get "$address" 2>/dev/null | jq -r '.roles // empty' || true)
29+
[[ -z "$ROLES_JSON" || "$ROLES_JSON" == "null" ]] && continue
30+
31+
ETH_KEYS=$(echo "$ROLES_JSON" | jq -r 'keys[] | select(endswith(".eth"))')
32+
[[ -z "$ETH_KEYS" ]] && continue
33+
34+
EDIT_ARGS=()
35+
while IFS= read -r eth_addr; do
36+
bso_addr="${eth_addr%.eth}.bso"
37+
role=$(echo "$ROLES_JSON" | jq -r --arg k "$eth_addr" '.[$k].role')
38+
39+
echo "[$address] $eth_addr -> $bso_addr ($role)"
40+
41+
EDIT_ARGS+=("--roles[\"$bso_addr\"].role" "$role")
42+
EDIT_ARGS+=("--roles[\"$eth_addr\"]" "null")
43+
done <<< "$ETH_KEYS"
44+
45+
if $APPLY; then
46+
if OUTPUT=$(bitsocial community edit "$address" "${EDIT_ARGS[@]}" 2>&1); then
47+
echo " applied"
48+
elif echo "$OUTPUT" | grep -q 'ERR_ROLE_ADDRESS_NAME_COULD_NOT_BE_RESOLVED'; then
49+
UNRESOLVED=$(echo "$OUTPUT" | grep -o '"roleAddress":"[^"]*"' | head -1 | cut -d'"' -f4)
50+
echo " skipped ($UNRESOLVED could not be resolved)"
51+
else
52+
echo " ERROR: $OUTPUT" >&2
53+
exit 1
54+
fi
55+
echo
56+
else
57+
echo " (dry run — skipping edit)"
58+
echo
59+
fi
60+
61+
TOTAL_CHANGED=$((TOTAL_CHANGED + 1))
62+
done <<< "$COMMUNITIES"
63+
64+
if [[ $TOTAL_CHANGED -eq 0 ]]; then
65+
echo "No .eth roles found in any community."
66+
else
67+
if $APPLY; then
68+
echo "$TOTAL_CHANGED community/communities updated."
69+
else
70+
echo "$TOTAL_CHANGED community/communities would be updated."
71+
fi
72+
fi

scripts/test-null-role.js

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import PKC from "@pkcprotocol/pkc-js";
2+
3+
const RPC_URL = "ws://localhost:9138";
4+
5+
const pkc = await PKC({ pkcRpcClientsOptions: [RPC_URL] });
6+
7+
await new Promise((resolve, reject) => {
8+
const timeout = setTimeout(() => reject(new Error("Timed out")), 20000);
9+
pkc.once("communitieschange", () => { clearTimeout(timeout); resolve(); });
10+
});
11+
12+
const address = pkc.communities[0];
13+
if (!address) { console.log("No communities"); await pkc.destroy(); process.exit(1); }
14+
15+
const community = await pkc.createCommunity({ address });
16+
console.log("Community:", address);
17+
console.log("Current roles:", JSON.stringify(community.roles, null, 2));
18+
19+
// Find any existing role to test null removal
20+
const existingRole = Object.entries(community.roles || {})[0];
21+
if (!existingRole) { console.log("No roles to test with"); await pkc.destroy(); process.exit(0); }
22+
23+
const [roleAddr, roleValue] = existingRole;
24+
console.log(`\nTesting null removal on: ${roleAddr} (${roleValue?.role})`);
25+
26+
// Test 1: Try removing with null
27+
console.log("\n--- Test: Removing role with null ---");
28+
try {
29+
await community.edit({ roles: { [roleAddr]: null } });
30+
console.log("SUCCESS: null works");
31+
} catch (e) {
32+
console.error("FAILED with null:", e.message || e);
33+
}
34+
35+
// Test 2: Try removing with undefined
36+
console.log("\n--- Test: Removing role with undefined ---");
37+
try {
38+
const community2 = await pkc.createCommunity({ address });
39+
await community2.edit({ roles: { [roleAddr]: undefined } });
40+
console.log("SUCCESS: undefined works");
41+
} catch (e) {
42+
console.error("FAILED with undefined:", e.message || e);
43+
}
44+
45+
// Check final state
46+
const community3 = await pkc.createCommunity({ address });
47+
console.log("\nFinal roles:", JSON.stringify(community3.roles, null, 2));
48+
49+
// Re-add the role back
50+
console.log("\n--- Restoring original role ---");
51+
try {
52+
await community3.edit({ roles: { [roleAddr]: roleValue } });
53+
console.log("Restored");
54+
} catch (e) {
55+
console.error("Failed to restore:", e.message || e);
56+
}
57+
58+
await pkc.destroy();

0 commit comments

Comments
 (0)