Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 31 additions & 5 deletions .github/workflows/bluesky.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,15 +85,41 @@ jobs:
BLUESKY_APP_PASSWORD: ${{ secrets.BLUESKY_APP_PASSWORD }}
run: ./target/release/server publish-bluesky --dir notes

- name: Commit bsky_url updates
- name: Init standard.site publication
# No-op when `publications.toml` already has `at_uri` + `at_cid`
# cached (see `init_publication` in `standard_site.rs`). First run
# after merge creates the publication record on the PDS and writes
# the URI/CID back; later runs short-circuit without touching the
# network. Failure here is fatal — sync depends on it.
#
# `APP_BASE_URL` + `IMGPROXY_URL` are required so init can fetch the
# publication's branded OG card (rasterized PNG) and upload it as the
# publication cover blob. This depends on the Fly Deploy that
# preceded this workflow having the `/og/publication/{key}.svg`
# route live — the `workflow_run` chain enforces that ordering.
id: init_standard
env:
BLUESKY_IDENTIFIER: ${{ secrets.BLUESKY_IDENTIFIER }}
BLUESKY_APP_PASSWORD: ${{ secrets.BLUESKY_APP_PASSWORD }}
IMGPROXY_URL: ${{ secrets.IMGPROXY_URL }}
run: ./target/release/server publish-standard-site init blog

- name: Sync standard.site
id: sync_standard
env:
BLUESKY_IDENTIFIER: ${{ secrets.BLUESKY_IDENTIFIER }}
BLUESKY_APP_PASSWORD: ${{ secrets.BLUESKY_APP_PASSWORD }}
run: ./target/release/server publish-standard-site sync --key blog

- name: Commit syndication updates
run: |
git config user.name "${{ steps.app-token.outputs.app-slug }}[bot]"
git config user.email "${{ steps.app-token.outputs.app-slug }}[bot]@users.noreply.github.com"
git add notes/
git add notes/ blog/ publications.toml
if git diff --staged --quiet; then
echo "No changes to commit"
else
git commit -m "Add bsky_url to published notes"
git commit -m "Sync syndication state"
# Rebase onto whatever main looks like *now* — covers the case
# where main moved during this workflow run.
git pull --rebase origin main
Expand All @@ -103,7 +129,7 @@ jobs:
- name: Surface publish failures
# Marks the run red so failures are visible. Runs last so partial
# successes still got committed/pushed/deployed via the steps above.
if: steps.publish.outcome == 'failure'
if: steps.publish.outcome == 'failure' || steps.sync_standard.outcome == 'failure'
run: |
echo "::error::One or more notes failed to publish. See the 'Publish to Bluesky' step. Next run will retry."
echo "::error::One or more publishes failed. See logs. Next run will retry."
exit 1
2 changes: 1 addition & 1 deletion .github/workflows/fly_review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,5 +63,5 @@ jobs:
uses: superfly/fly-pr-review-apps@1.2.1
with:
name: coreyja-com-pr-${{ github.event.number }}
secrets: APP_BASE_URL="https://coreyja-com-pr-${{ github.event.number }}.fly.dev" DATABASE_URL="${{ steps.create-branch.outputs.db_url }}?sslmode=require" TWITCH_CLIENT_ID="FAKE" TWITCH_CLIENT_SECRET="FAKE" TWITCH_BOT_ACCESS_TOKEN="FAKE" TWITCH_BOT_USER_ID="FAKE" TWITCH_CHANNEL_USER_ID="FAKE" GITHUB_APP_ID="123" GITHUB_APP_CLIENT_ID="FAKE" GITHUB_APP_CLIENT_SECRET="FAKE" GITHUB_APP_PRIVATE_KEY="FAKE" GITHUB_PERSONAL_ACCESS_TOKEN="FAKE" OPEN_AI_API_KEY="FAKE" GOOGLE_CLIENT_ID="FAKE" GOOGLE_CLIENT_SECRET="FAKE" ENCRYPTION_SECRET_KEY="FAKE" JOBS_DISABLED="true" CRON_DISABLED="true" DISCORD_TOKEN="FAKE" DISCORD_BOT_DISABLED="true"
secrets: APP_BASE_URL="https://coreyja-com-pr-${{ github.event.number }}.fly.dev" DATABASE_URL="${{ steps.create-branch.outputs.db_url }}?sslmode=require" TWITCH_CLIENT_ID="FAKE" TWITCH_CLIENT_SECRET="FAKE" TWITCH_BOT_ACCESS_TOKEN="FAKE" TWITCH_BOT_USER_ID="FAKE" TWITCH_CHANNEL_USER_ID="FAKE" GITHUB_APP_ID="123" GITHUB_APP_CLIENT_ID="FAKE" GITHUB_APP_CLIENT_SECRET="FAKE" GITHUB_APP_PRIVATE_KEY="FAKE" GITHUB_PERSONAL_ACCESS_TOKEN="FAKE" OPEN_AI_API_KEY="FAKE" GOOGLE_CLIENT_ID="FAKE" GOOGLE_CLIENT_SECRET="FAKE" ENCRYPTION_SECRET_KEY="FAKE" JOBS_DISABLED="true" CRON_DISABLED="true" DISCORD_TOKEN="FAKE" DISCORD_BOT_DISABLED="true" ANTHROPIC_API_KEY="FAKE" LINEAR_CLIENT_ID="FAKE" LINEAR_CLIENT_SECRET="FAKE" LINEAR_WEBHOOK_SECRET="FAKE"
memory: 512
70 changes: 65 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ tower = "0.4.13"
tower-cookies = "0.11.0"
tower-http = "0.5.0"
typify = "0.0.14"
toml = "0.8"
url = "2.5.0"
urlencoding = "2.1"
vergen = "8.0.0"
1 change: 1 addition & 0 deletions blog/look-ma-no-ai/index.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
title: Look Ma’ no AI
subtitle: An apology, and a recommitment to writing the words myself.
author: Corey Alexander
date: 2026-05-27
---
Expand Down
30 changes: 30 additions & 0 deletions posts/src/blog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,9 +236,25 @@ pub struct BlogFrontMatter {
pub buttondown_id: Option<String>,
/// Absolute URL of an OG image to use instead of the auto-generated branded card.
pub og_image: Option<String>,
/// Optional short subtitle/tagline shown on the OG card in place of the
/// post date. When unset, the OG card renders the post date.
pub subtitle: Option<String>,
#[serde(default)]
pub tags: Vec<String>,
pub author: Option<String>,
/// AT URI of the `site.standard.document` record on the PDS, set after
/// the first successful sync. Acts as the idempotency key — its presence
/// means the document record has been created, so subsequent syncs use
/// `putRecord` against the same rkey rather than creating a new record.
pub atproto_uri: Option<String>,
/// Publication this post belongs to. Defaults to `"blog"` and corresponds
/// to an entry in `publications.toml`.
#[serde(default = "default_publication")]
pub publication: String,
}

fn default_publication() -> String {
"blog".to_string()
}

impl PostedOn for BlogFrontMatter {
Expand Down Expand Up @@ -321,8 +337,11 @@ mod test {
newsletter_send_at: None,
buttondown_id: None,
og_image: None,
subtitle: None,
tags: vec![],
author: None,
atproto_uri: None,
publication: "blog".to_string(),
};
let post = BlogPost {
path,
Expand Down Expand Up @@ -357,8 +376,11 @@ mod test {
newsletter_send_at: None,
buttondown_id: None,
og_image: None,
subtitle: None,
tags: vec![],
author: None,
atproto_uri: None,
publication: "blog".to_string(),
},
}
}
Expand All @@ -380,4 +402,12 @@ mod test {
let post = test_post("weekly/20230713/index.md", false);
assert_eq!(post.og_slug(), "weekly/20230713");
}

#[test]
fn frontmatter_defaults_apply_when_fields_absent() {
let yaml = "title: T\ndate: 2026-05-01";
let fm: BlogFrontMatter = serde_yaml::from_str(yaml).unwrap();
assert_eq!(fm.publication, "blog");
assert!(fm.atproto_uri.is_none());
}
}
7 changes: 7 additions & 0 deletions publications.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[[publication]]
key = "blog"
title = "coreyja.com"
description = "Personal blog: Rust, side projects, Battlesnake, AI agents."
url = "https://coreyja.com/posts"
content_dir = "blog"
collection = "site.standard.document"
1 change: 1 addition & 0 deletions server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ arborium = { workspace = true }
html-escape = { workspace = true }
thiserror = { workspace = true }
tokio = { workspace = true }
toml = { workspace = true }
tower = { workspace = true, features = ["util"] }
tower-http = { workspace = true, features = ["trace", "cors"] }
tracing = { workspace = true }
Expand Down
Loading
Loading