Publishing anywhere

One config key covers every host, because publishing is a folder plus one line of shell.

If your library folder is already on the web, publishing is finished the moment the file is written. There is nothing to upload, and nothing to configure beyond base_url.

Where a library can live

earmark builds every episode URL by appending to base_url, so <base_url>/audio/some-paper.mp3 has to resolve. That one requirement decides which services can hold a library.

Works base_url looks like
pCloud public folder https://filedn.com/XXXX/audio
Cloudflare R2, public bucket https://pub-xxxx.r2.dev
Backblaze B2, public bucket https://f000.backblazeb2.com/file/my-bucket
AWS S3, DigitalOcean Spaces, Wasabi, any S3-compatible bucket https://my-bucket.s3.amazonaws.com/audio
Your own server: nginx, Caddy, Apache https://example.com/audio
GitHub Pages, Netlify, Cloudflare Pages https://you.github.io/audio

The big consumer sync services are the ones that cannot, which surprises people:

Cannot host a library Why
Dropbox The Public folder was retired in 2017. Every share link now points at one file and carries an rlkey token, so there is no folder URL to append to.
Box Direct links are /shared/static/<hash>, one per file. Folders have no direct link at all.
Google Drive, OneDrive, iCloud Drive The same shape: a link per file, nothing that serves a path under a folder.

That is not a reason to stop using them. Keep the library wherever you like and point after_publish at something that does serve, with base_url set to where the files land rather than where they start.

When the folder is not already on the web

after_publish is one line of shell, run inside the library once the feed is written:

Host after_publish
GitHub Pages git add -A && git commit -m earmark && git push
S3 / R2 / B2 / Spaces rclone sync . r2:my-bucket/audio
Your own server rsync -a --delete . me@host:/var/www/audio/
after_publish = "rclone sync . r2:my-bucket/audio"

[feed]
base_url = "https://pub-xxxx.r2.dev"

Set base_url to wherever those files end up, not to where they start.

Why there is no --publisher flag

There used to be four publishers built in: folder, rclone, command, and github. They are gone, because all four are the table above. A config key that runs your shell covers every host that exists, including the one you will use next year, without earmark knowing the name of any of them.

So there is no plugin system to learn and no adapter to write. If a host isn’t in that table, the answer is a different one-liner, not a feature request.

Proving it worked

base_url being wrong is the failure that costs you the most time, because nothing errors: earmark writes the files, the feed validates, and the app shows nothing.

earmark feed --check

That HEADs the feed, the cover and the newest episodes and tells you which of them actually serve.

Episode filenames

audio writes audio/<slug>.mp3 and publish does not rename it. The two commands would otherwise disagree about where a document’s audio lives.

A content digest is still computed. It is the feed’s guid, which is how re-publishing a document you edited replaces its episode instead of adding a duplicate.

Adopting audio you already have

earmark publish interview.mp3

An existing .mp3, .m4a or .wav goes onto the feed with no synthesis at all, which is how a recording made elsewhere ends up in the same feed as the things earmark narrated.