Spec-correct publication metadata refresh + imgproxy env fix#406
Merged
Conversation
The bluesky workflow's init step was pulling \`IMGPROXY_URL\` from a repo secret that didn't exist, expanding to an empty string. The Rust code read that empty string as a present-but-empty value, built a relative imgproxy URL, and reqwest refused with "relative URL without a base." Result: the publication record landed on the PDS without a cover blob. Two-part fix: 1. Drop the secret reference and hardcode \`IMGPROXY_URL: https://img.coreyja.com\` at the workflow level. imgproxy is a public service the blog itself links into; nothing about it needs to live in repo secrets. 2. Add \`required_env(name)\` that rejects both unset and empty-string values. Future missing/typoed env vars produce a clear error instead of a malformed URL further down the call chain. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…_cid drift detection
Adds two new pieces of state and the sync logic that uses them to make
publication-record updates cascade through every document that strong-
references it — fully via the bluesky workflow, no manual ops steps.
\`publications.toml\` gains \`cover_synced: bool\` (default \`false\`):
- init's idempotent fast path now requires this in addition to
cached \`at_uri\`/\`at_cid\`. Set to \`true\` only after a *successful*
cover-blob upload; an upload failure leaves it \`false\` so the next
deploy retries.
- Self-heals our current state: the publication record was created
on the prior deploy without a cover (\`IMGPROXY_URL\` was empty), so
\`cover_synced\` is absent (= \`false\`) → next deploy re-puts the
publication with cover → new cid in \`at_cid\`.
\`BlogFrontMatter\` gains \`atproto_pub_cid: Option<String>\`:
- Records the publication CID this document's \`publication: StrongRef\`
was pinned to at last sync.
- Sync compares against current \`pub_cfg.at_cid\`; drift triggers a
re-put of the document with the refreshed strong-ref. Spec-correct:
when the referent's content changes, every referrer gets re-emitted.
\`sync_one\` is rewritten around two booleans:
- \`need_doc_put\` = no document yet OR pinned cid drifted OR we're
going to put a bsky post (so we have a fresh doc cid for it)
- \`need_bsky_post\` = no bsky_url AND post is recent (>= cutoff)
- Skip when neither needs doing. Document re-put always re-writes
\`atproto_pub_cid\` so future runs short-circuit until drift again.
Net effect when the next bluesky workflow runs after this merges:
1. init re-puts the publication with cover → at_cid bumps → committed
2. sync walks 43 existing documents → all have atproto_pub_cid=None
→ drift detected → all re-put with new cid → frontmatter updated
3. Commit step pushes the new at_cid + 43 frontmatter updates back.
Future cover updates: flip cover_synced=false in publications.toml,
push, deploy. Same cascade runs again. No manual steps.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Earlier cargo fmt apparently didn't apply this hunk locally. CI's rustfmt
flagged the multi-line match form; condensed back to the standard
`match expr { ... }` shape.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two-commit follow-up to #404 that fixes both the missing publication cover and the strong-ref cascade behavior on future cover updates.
Why
After #404 merged, the bluesky workflow's init step ran with `IMGPROXY_URL=` (the repo secret didn't exist), my code built a relative URL, reqwest refused, and the publication record landed on the PDS without a cover blob. 43 documents now strong-reference that cidless publication.
Updating publication metadata in atproto is spec-correctly a cascade: change the publication's content → cid bumps → every `site.standard.document` that strong-refs it should be re-put with the new `StrongRef`. Lenient consumers deref by URI and ignore cid drift; strict consumers treat the strong ref as an invariant. We're doing it to spec.
Commit 1 — `Hardcode IMGPROXY_URL in bluesky workflow + treat empty env as missing`
Commit 2 — `Spec-correct publication-metadata refresh: cover_synced + atproto_pub_cid drift detection`
Two pieces of state + sync logic that makes publication updates cascade fully through CI, with no operator steps.
`publications.toml` gains `cover_synced: bool` (default `false`):
`BlogFrontMatter` gains `atproto_pub_cid: Option`:
`sync_one` rewritten around two booleans:
What happens on the next deploy after this merges
Future cover updates
Flip `cover_synced = false` in `publications.toml`, push, deploy. Same cascade runs. No manual ops.
Tests
🤖 Generated with Claude Code