Skip to content

Add Blog sample types and a seeder API - #2772

Merged
pournasserian merged 6 commits into
mainfrom
feat/dreamy-williamson-ded303
Nov 4, 2026
Merged

pournasserian merged 6 commits into
mainfrom
feat/dreamy-williamson-ded303

Conversation

@pournasserian

@pournasserian pournasserian commented Nov 4, 2026 •

Copy link
Copy Markdown
Member

Closes #2706.

What

  • SDK FluentCMS.Seeding: ISeeder, SeedContext (services, site, locale, the host clock, InLocale) and ISeedRunner.
  • Core: cms.Seeding.Add<T>(), RequireLocale(...), RunOnStart and ClaimTimeout. Seeders run in StartAsync after the migrations, on the default site, as the system principal with the Seed origin. With no seeder added nothing is added to start-up. Only seeders added with Add run, at boot and through ISeedRunner.
  • What was applied (seeder Name and Version) and a claim are kept in the instance settings area seeding (no system table). A run claims the seeder with a write that names the version it read; an instance that loses skips and boots normally, and a claim older than 15 minutes can be taken over.
  • SiteManager.EnsureLocaleAsync adds a locale to the default site if missing. Site management arrives in M2, and the sample needs fr.
  • samples/Blog: Article, Author, Tag, Seo, HeroBlock, QuoteBlock, GalleryBlock, typed BlogSettings ([Settings("blog")]), BlogSeeder and cms.AddBlogSample().
  • Seed set: 2 authors, 3 tags, 5 articles (published in en and fr, published, draft, trashed with DeleteAsync, scheduled last with ScheduleAsync 30 days after the host clock) and the site's blog settings. Everything goes through the public services.
  • Spec updated in 4.16 and 6.3.

Decisions

  • Entries are found by slug (authors and tags too, Author gained a unique slug), each step converges (publish if draft, add fr if missing, trash if not trashed, schedule if still a draft), a unique conflict counts as already there, and purged or renamed content does not come back because an applied seeder is skipped.
  • SiteSettings is typed settings, not the singleton from 4.2, as the notes on the issue say.
  • Media fields are left out of the sample until the media plugin registers the media field type. GalleryBlock has a caption and a column count for now.
  • samples/Blog references Sdk and Core, to offer AddBlogSample. No system table or migration change.

Tests

BlogSampleTests and BlogSeedingTests in FluentCMS.Core.IntegrationTests (the second covers concurrent runs on a file database, purge, rename and settings change then another boot, a crash halfway then a rerun, a version bump, claim timeout, failure release) (one seeded host for the class, about 0.5 s): types register, read-back of authors, tags, articles, relations, blocks and component, the fr translation, the trashed entry only in the trash, the scheduled entry a draft with SchedulePublishAt at clock plus delay, Seed origin in the versions, settings stored, a second run creates no rows, and a host without the sample has no seed service.

dotnet build -c Release -warnaserror and the full dotnet test -c Release (2779 tests) pass locally. Markdown lint is clean. SQLite only; PostgreSQL and SQL Server follow #2711.

No new packages.

ISeeder, SeedContext and ISeedRunner in the SDK; cms.Seeding in core runs
registered seeders on start as the system principal with the Seed origin.
samples/Blog holds the sample types, typed settings and an idempotent seed
set with a translation, a trashed and a scheduled article.
The seeding settings area keeps each seeder's applied version and a claim
taken with a compare-and-swap write, so boots skip applied seeds and
concurrent boots run one. Entries are found by slug, each step converges,
and the locale insert tolerates a concurrent boot and writes activity.
…ing edits

The claim has an id and is renewed while the run lasts; only a stale claim
is taken over, and a run releases or finishes only its own. Seeders get the
version they were last applied at, and the Blog seed changes state only for
what it created or on a first run.
Any exception after the claim is taken releases it if it is still the run's,
and the Blog seed's state steps accept an entry that an overlapping run or a
person already published, trashed or purged.
@pournasserian
pournasserian merged commit a31a5fe into main Nov 4, 2026
5 checks passed
@pournasserian
pournasserian deleted the feat/dreamy-williamson-ded303 branch November 4, 2026 15:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Sample Blog content types and seed API

1 participant