Skip to content

Add newsletter link to navigation #4

Add newsletter link to navigation

Add newsletter link to navigation #4

name: Lint new posts
# Blocking PR check: any new file added to docs/blog/posts/ MUST include
# `draft: true` in its frontmatter. This guarantees a PR merge cannot
# accidentally publish a post — the only legitimate way to flip a post live
# is through the scheduling workflows (auto-publisher, /publish-now,
# "Schedule a post" → publish-now). Removing `draft: true` is the dedicated
# job of the github-actions bot, and that path doesn't go through PR review.
#
# Modified existing posts are NOT checked here — auto-publisher commits
# legitimately remove `draft: true`.
#
# Runs on every PR (no path filter) so this check can be marked "required" in
# branch protection without leaving unrelated PRs hanging on a missing status.
# When no posts were added the check passes trivially.
on:
pull_request:
branches: [main]
permissions:
contents: read
pull-requests: write
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # need history to diff against base
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install PyYAML
run: pip install pyyaml
- name: Collect newly added posts
id: added
env:
BASE_SHA: ${{ github.event.pull_request.base.sha }}
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
run: |
set -e
ADDED=$(git diff --name-only --diff-filter=A "$BASE_SHA" "$HEAD_SHA" -- 'docs/blog/posts/*.md' || true)
if [ -z "$ADDED" ]; then
echo "No new posts added in this PR — lint passes trivially."
else
echo "Newly added post files:"
echo "$ADDED"
fi
{
echo "files<<EOF"
echo "$ADDED"
echo "EOF"
} >> "$GITHUB_OUTPUT"
- name: Enforce draft on new posts
if: steps.added.outputs.files != ''
env:
FILES: ${{ steps.added.outputs.files }}
run: |
set -e
# FILES is newline-separated; word-splitting on whitespace gives the arg list.
# shellcheck disable=SC2086
python scripts/schedule_lib.py lint-new-posts $FILES | tee result.json
- name: Post-fail explainer
if: failure()
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
let body = '### Lint failed: new post(s) missing `draft: true`\n\n';
body += 'Every new post in `docs/blog/posts/` must include `draft: true` in its frontmatter when first added. ';
body += 'This is a safety rail — a merge of this PR with the post in its current state would put it live on blogs.jaseci.org immediately, bypassing editorial review.\n\n';
body += 'Fix: add `draft: true` to the frontmatter of the affected file(s):\n\n';
body += '```yaml\n---\ndate: 2026-XX-XX\nauthors:\n - your_author_id\ncategories:\n - Your Category\nslug: your-slug\ndraft: true # <- this line\n---\n```\n\n';
body += 'Once an editor merges the PR, they will schedule a publish time using the *Schedule a post* workflow (or `/schedule <ISO datetime>` in this PR\'s comments). The auto-publisher will flip `draft: true` off when that time arrives.\n\n';
try {
const result = fs.readFileSync('result.json', 'utf8');
body += '<details><summary>Lint output</summary>\n\n```json\n' + result + '\n```\n\n</details>';
} catch (e) {}
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.pull_request.number,
body,
});