feat: publish scheduled posts on their pubDate with a daily build
This commit is contained in:
parent
c8e0446216
commit
c6b3007995
6 changed files with 25 additions and 4 deletions
4
.github/workflows/main.yml
vendored
4
.github/workflows/main.yml
vendored
|
|
@ -3,6 +3,10 @@ name: Deploy to OVH VPS
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [main]
|
branches: [main]
|
||||||
|
# Daily rebuild at 07:00 Rome (summer time) publishes posts whose pubDate is today
|
||||||
|
schedule:
|
||||||
|
- cron: "0 5 * * *"
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
deploy:
|
deploy:
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
---
|
---
|
||||||
import type { CollectionEntry } from "astro:content";
|
import type { CollectionEntry } from "astro:content";
|
||||||
import { getCollection } from "astro:content";
|
import { getCollection } from "astro:content";
|
||||||
|
import { isPublished } from "../utils/posts";
|
||||||
import { Image } from "astro:assets";
|
import { Image } from "astro:assets";
|
||||||
import Footer from "../components/Footer.astro";
|
import Footer from "../components/Footer.astro";
|
||||||
import Navbar from "../components/Navbar.astro";
|
import Navbar from "../components/Navbar.astro";
|
||||||
|
|
@ -11,7 +12,7 @@ type BlogPost = CollectionEntry<"blog">;
|
||||||
|
|
||||||
const allPosts: BlogPost[] = await getCollection("blog");
|
const allPosts: BlogPost[] = await getCollection("blog");
|
||||||
const sortedPosts: BlogPost[] = allPosts
|
const sortedPosts: BlogPost[] = allPosts
|
||||||
.filter((post: BlogPost) => !post.data.draft)
|
.filter((post: BlogPost) => isPublished(post))
|
||||||
.sort((a: BlogPost, b: BlogPost) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf());
|
.sort((a: BlogPost, b: BlogPost) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf());
|
||||||
|
|
||||||
const allTags: Record<string, number> = sortedPosts.reduce(
|
const allTags: Record<string, number> = sortedPosts.reduce(
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
---
|
---
|
||||||
import type { CollectionEntry } from "astro:content";
|
import type { CollectionEntry } from "astro:content";
|
||||||
import { getCollection } from "astro:content";
|
import { getCollection } from "astro:content";
|
||||||
|
import { isPublished } from "../../utils/posts";
|
||||||
import { Image } from "astro:assets";
|
import { Image } from "astro:assets";
|
||||||
import BaseLayout from "../../layouts/BaseLayout.astro";
|
import BaseLayout from "../../layouts/BaseLayout.astro";
|
||||||
import Navbar from "../../components/Navbar.astro";
|
import Navbar from "../../components/Navbar.astro";
|
||||||
|
|
@ -15,7 +16,7 @@ type BlogPost = CollectionEntry<"blog">;
|
||||||
|
|
||||||
export async function getStaticPaths() {
|
export async function getStaticPaths() {
|
||||||
const blogEntries: BlogPost[] = await getCollection("blog");
|
const blogEntries: BlogPost[] = await getCollection("blog");
|
||||||
return blogEntries.map((entry: BlogPost) => ({
|
return blogEntries.filter((entry: BlogPost) => isPublished(entry)).map((entry: BlogPost) => ({
|
||||||
params: { slug: entry.slug },
|
params: { slug: entry.slug },
|
||||||
props: { entry },
|
props: { entry },
|
||||||
}));
|
}));
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
---
|
---
|
||||||
import type { CollectionEntry } from "astro:content";
|
import type { CollectionEntry } from "astro:content";
|
||||||
import { getCollection } from "astro:content";
|
import { getCollection } from "astro:content";
|
||||||
|
import { isPublished } from "../../../utils/posts";
|
||||||
import { Image } from "astro:assets";
|
import { Image } from "astro:assets";
|
||||||
import Footer from "../../../components/Footer.astro";
|
import Footer from "../../../components/Footer.astro";
|
||||||
import Navbar from "../../../components/Navbar.astro";
|
import Navbar from "../../../components/Navbar.astro";
|
||||||
|
|
@ -10,7 +11,7 @@ type BlogPost = CollectionEntry<"blog">;
|
||||||
|
|
||||||
export async function getStaticPaths() {
|
export async function getStaticPaths() {
|
||||||
const allPosts: BlogPost[] = await getCollection("blog");
|
const allPosts: BlogPost[] = await getCollection("blog");
|
||||||
const publishedPosts: BlogPost[] = allPosts.filter((post: BlogPost) => !post.data.draft);
|
const publishedPosts: BlogPost[] = allPosts.filter((post: BlogPost) => isPublished(post));
|
||||||
|
|
||||||
const allTags = new Set<string>();
|
const allTags = new Set<string>();
|
||||||
publishedPosts.forEach((post: BlogPost) => {
|
publishedPosts.forEach((post: BlogPost) => {
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,12 @@
|
||||||
import rss from "@astrojs/rss";
|
import rss from "@astrojs/rss";
|
||||||
import { getCollection } from "astro:content";
|
import { getCollection } from "astro:content";
|
||||||
|
import { isPublished } from "../utils/posts";
|
||||||
import type { APIContext } from "astro";
|
import type { APIContext } from "astro";
|
||||||
|
|
||||||
export async function GET(context: APIContext) {
|
export async function GET(context: APIContext) {
|
||||||
const blog = await getCollection("blog");
|
const blog = await getCollection("blog");
|
||||||
const publishedPosts = blog
|
const publishedPosts = blog
|
||||||
.filter((post) => !post.data.draft)
|
.filter((post) => isPublished(post))
|
||||||
.sort((a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf());
|
.sort((a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf());
|
||||||
|
|
||||||
return rss({
|
return rss({
|
||||||
|
|
|
||||||
13
src/utils/posts.ts
Normal file
13
src/utils/posts.ts
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
import type { CollectionEntry } from "astro:content";
|
||||||
|
|
||||||
|
type BlogPost = CollectionEntry<"blog">;
|
||||||
|
|
||||||
|
// A post with a future pubDate stays in the repo but is left out of the build
|
||||||
|
// until that day (Rome calendar day, not UTC): the scheduled CI build publishes
|
||||||
|
// it. `astro dev` shows everything so scheduled posts can be previewed.
|
||||||
|
export function isPublished(post: BlogPost, now: Date = new Date()): boolean {
|
||||||
|
if (post.data.draft) return false;
|
||||||
|
if (import.meta.env.DEV) return true;
|
||||||
|
const today = new Intl.DateTimeFormat("en-CA", { timeZone: "Europe/Rome" }).format(now);
|
||||||
|
return post.data.pubDate.toISOString().slice(0, 10) <= today;
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue