Skip to content

Commit 47dadca

Browse files
bakerboy448claude
andauthored
feat(devvit): port to Devvit Web (autowikimod) (#79)
Ports `devvit/` from the classic `@devvit/public-api` scaffold to Devvit Web as `autowikimod`, ahead of the Data API closing to unregistered apps on 2027-01-12. - `devvit.json` + Hono `/internal/*` server on `@devvit/web` 0.14.8, built to `dist/server/index.cjs` with `@devvit/start`. - Cron publish every 20 min. `onModAction` dropped: its payload carries no reason text and the cron already reads the mod log. - Renderer ported from `build_wiki_content`. FR-7 merges a removal with its `addremovalreason`. FR-8 shows approvals only when they reverse a Reddit/AutoModerator removal, looked up in a Redis hash keyed by target id. - Settings: wiki page (default `modlog-devvit` for side-by-side cutover), days shown/kept (90), action list, anonymize (cannot be disabled), ignored moderators. Menu: Publish now, Force rebuild, Test connection. - 42 Vitest tests (render, correlation, settings, Redis store on `@devvit/test`, publish cycle). The golden parity test runs a fixture through the unmodified Python publisher and requires byte-identical TS output; CI regenerates the golden with uv and fails on drift. - New `devvit.yml` workflow on the `hetzner` runner. Not yet uploaded or playtested. Deliberate differences from Python and the live-playtest list are in `devvit-migration/docs/STATUS.md`. Supersedes #72 (public-api bump) since the classic package is removed. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
1 parent fd39b6b commit 47dadca

44 files changed

Lines changed: 9225 additions & 3959 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.github/actionlint.yaml‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
self-hosted-runner:
2+
labels: [hetzner, ci-general, t16, gaming]

‎.github/workflows/devvit.yml‎

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
---
2+
name: Devvit app
3+
4+
"on":
5+
push:
6+
branches: [main]
7+
paths:
8+
- 'devvit/**'
9+
- 'modlog_wiki_publisher.py'
10+
- '.github/workflows/devvit.yml'
11+
pull_request:
12+
branches: [main]
13+
paths:
14+
- 'devvit/**'
15+
- 'modlog_wiki_publisher.py'
16+
- '.github/workflows/devvit.yml'
17+
workflow_dispatch:
18+
19+
concurrency:
20+
group: ${{ github.workflow }}-${{ github.ref }}
21+
cancel-in-progress: true
22+
23+
permissions:
24+
contents: read
25+
26+
jobs:
27+
test:
28+
runs-on: [self-hosted, Linux, X64, hetzner]
29+
timeout-minutes: 15
30+
defaults:
31+
run:
32+
working-directory: devvit
33+
steps:
34+
- name: Checkout
35+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
36+
37+
- name: Set up Node
38+
uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
39+
with:
40+
node-version-file: devvit/.nvmrc
41+
cache: npm
42+
cache-dependency-path: devvit/package-lock.json
43+
44+
- name: Install
45+
run: npm ci --no-fund --no-audit
46+
47+
- name: Type-check
48+
run: npm run type-check
49+
50+
- name: Test
51+
run: npm test
52+
53+
- name: Build
54+
run: npm run build
55+
56+
- name: Set up uv
57+
uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0
58+
59+
- name: Python parity golden is current
60+
run: |
61+
uv run --no-project --python 3.13 --with praw==8.0.3 \
62+
python -I test/parity/python_render.py test/parity/fixture.json "$GITHUB_WORKSPACE" > "$RUNNER_TEMP/golden.md"
63+
diff -u test/parity/golden.md "$RUNNER_TEMP/golden.md"

‎.pre-commit-config.yaml‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ repos:
77
files: \.json$
88
- id: check-merge-conflict
99
- id: end-of-file-fixer
10+
exclude: ^devvit/test/parity/golden\.md$
1011
- id: trailing-whitespace
12+
exclude: ^devvit/test/parity/golden\.md$
1113
- id: no-commit-to-branch
1214
args: ['--branch', 'main']
1315
- id: check-added-large-files

‎README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
Automatically publishes Reddit moderation logs to a subreddit wiki page with modmail inquiry links.
66

7-
> **🧪 Devvit migration in progress.** A re-platform of this bot to a Reddit-hosted [Devvit](https://developers.reddit.com/) app (no self-hosting, no bot password, no SQLite) is being scaffolded under [`devvit/`](devvit/) with requirements, research, and architecture docs in [`devvit-migration/docs/`](devvit-migration/). The Python app documented below remains the supported version. See [`devvit-migration/README.md`](devvit-migration/README.md) for status.
7+
> **🧪 Devvit migration in progress.** A re-platform of this bot to a Reddit-hosted [Devvit](https://developers.reddit.com/) app (no self-hosting, no bot password, no SQLite) lives under [`devvit/`](devvit/) as the Devvit Web app `autowikimod`, with design docs in [`devvit-migration/docs/`](devvit-migration/). The Python app documented below remains the supported version. See [`devvit-migration/README.md`](devvit-migration/README.md) for status.
88
99
## Features
1010

‎devvit-migration/README.md‎

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ Re-platforming the Python/PRAW **Reddit Modlog Wiki Publisher** into a **Devvit*
88
| --- | --- |
99
| `subreddit.mod.log(limit=N)` | `reddit.getModerationLog({ subredditName, type?, limit })` |
1010
| `subreddit.wiki[page].edit()` | `reddit.getWikiPage` / `reddit.updateWikiPage` (512 KB cap unchanged) |
11-
| SQLite dedup + retention + hash-cache | `context.redis` (strings for dedup, sorted-set by timestamp for retention, hash for wiki-hash cache) |
12-
| Continuous daemon (`update_interval`) | `Devvit.addSchedulerJob` + cron (1-min min granularity) + optional `onModAction` trigger |
11+
| SQLite dedup + retention + hash-cache | `redis` from `@devvit/web/server` (hashes for rows, dedup and hash cache; sorted sets by timestamp for retention) |
12+
| Continuous daemon (`update_interval`) | `devvit.json` scheduler task, cron `*/20 * * * *` |
1313
| `config.json` / env / CLI (19 options) | Devvit app + per-install settings (`anonymize_moderators` hardcoded true) |
1414
| Docker / s6 / systemd | Reddit-hosted (serverless, free); publish via app review |
1515

@@ -21,10 +21,8 @@ Re-platforming the Python/PRAW **Reddit Modlog Wiki Publisher** into a **Devvit*
2121
- [`docs/04-architecture.md`](docs/04-architecture.md) — module layout, Redis key schema, execution model, settings schema, phased plan, gap list
2222
- [`docs/STATUS.md`](docs/STATUS.md) — what is scaffolded vs. TODO, mapped to the parity matrix
2323
- [`docs/reddit-api/`](docs/reddit-api/) — stored Devvit API reference snippets
24-
- [`../devvit/`](../devvit/) — the Devvit app scaffold (TypeScript; compiles clean via `tsc --noEmit`)
24+
- [`../devvit/`](../devvit/) — the Devvit Web app (`autowikimod`)
2525

2626
## Status
2727

28-
Scaffold stage: requirements + research + architecture complete; component modules (`storage`, `modlog`, `render`, `wiki`, `settings`, `menu`, `main`) written and type-checking clean. Not yet `devvit upload`-tested against a live test subreddit. See [`docs/STATUS.md`](docs/STATUS.md).
29-
30-
This scaffold was produced by a multi-agent scrum (requirements → research → architecture → per-component implementation → scaffold). Treat the generated TypeScript as a reviewed starting point, not a shipped app — every Devvit API call should be validated in `devvit playtest` before publishing.
28+
Ported to Devvit Web; type-check, tests, build and Python parity pass offline. Awaiting upload and a live run on r/OpenSignups. See [`docs/STATUS.md`](docs/STATUS.md). `docs/01..04` describe the earlier classic-model design.

0 commit comments

Comments
 (0)