From 1823b3c4771329a54abffa12e075f7f50c5cef70 Mon Sep 17 00:00:00 2001 From: Jacob Coffee Date: Tue, 3 Mar 2026 12:52:30 -0600 Subject: [PATCH 1/5] docs: update gaps in getting started contributing --- README.md | 157 +++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 126 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index db5cc1b..5a16bff 100644 --- a/README.md +++ b/README.md @@ -1,51 +1,146 @@ ## Python Insider Blog -Blog for Python core team, mostly for blogging about releases. +The official blog for the Python core team — mostly release announcements. -## About +Built with [Astro](https://astro.build/) and [Keystatic](https://keystatic.com/) CMS. +Content is plain Markdown, built statically at deploy time. -Uses keystatic for WYSIWYG editing. +## Quickstart -Features some custom components like: +### Prerequisites -- GitHub User, Repo -- PyPI Project -- CPython Docs +**Bun** — the JavaScript runtime used for this project. -Utilizes Bun for builds. Uses Astro.js which builds statically at build time. -Pre-commit config, powered by Prek to do CI things and spellchecks. +```bash +# macOS +brew install oven-sh/bun/bun -### From Blogger +# Linux / WSL +curl -fsSL https://bun.sh/install | bash -Migrated from Blogger with a field on new posts of "Previous Blogger URL" -so that we can more easily redirect. +# Windows — use WSL, then the Linux command above +``` -### Posts +See [bun.sh/docs/installation](https://bun.sh/docs/installation) for other methods. -Posts are structured under `content/posts/`. -They have the directory named after the blog entry title. +**prek** (optional) — runs pre-commit hooks locally. Only needed if you want +to run linting/spellcheck before pushing. CI will catch these regardless. -Inside is the core markdown (index.md) and optionally the images -used in the blog entry. +```bash +# macOS +brew install prefix-dev/prek/prek -### Authors +# Linux / Windows (standalone installer) +curl -fsSL https://prek.j178.dev/install.sh | bash + +# Or via cargo / pip / other methods +cargo install prek +``` + +See [prek.j178.dev/installation](https://prek.j178.dev/installation/#standalone-installer) +for all installation options. + +> [!NOTE] +> **Windows users**: The Makefile requires a Unix shell. Use +> [WSL](https://learn.microsoft.com/en-us/windows/wsl/install) or Git Bash. +> Alternatively, skip `make` and run the bun commands directly (see table below). + +### Setup + +```bash +git clone https://github.com/python/python-insider-blog.git +cd python-insider-blog +make install # installs node_modules + git hooks +make dev # starts dev server at http://127.0.0.1:4321 +``` + +`make install` runs `bun install` (dependencies) and `prek install` (git hooks). +If you don't have prek installed, the hook setup will fail but everything else +still works — you can write and preview posts without it. -Authors are configured via `content/authors/`. +## Writing a blog post -## Contributing +### Option A: Use the Keystatic UI (recommended) -There are `Make` targets to get up and going, assuming you have the -tooling required (Bun, prek, etc.) +1. Run `make dev` +2. Open http://127.0.0.1:4321/keystatic in your browser +3. Create or edit a post with the visual editor +4. Commit and open a pull request -### Writing Blog Entries +### Option B: Write Markdown directly -You can pull the repo, run `make dev`, and edit the page via Keystatic -with the nice UI or you can write markdown in your editor. +Create a new directory under `content/posts/` named after your post slug, +with an `index.md` inside: -Both should open a pull request to GitHub for review and CI checks. +``` +content/posts/python-31213-31115-31020/ +└── index.md +``` + +Frontmatter fields: + +```yaml +--- +title: "Python 3.12.13, 3.11.15, and 3.10.20 are now available" +description: "Security fix release for Python 3.12, 3.11, and 3.10" +authors: + - thomas-wouters +tags: + - "3.12" + - "3.11" + - "3.10" +pubDate: 2026-03-03 +draft: false +previousBloggerUrl: "" +--- +``` + +Then write the body in standard Markdown. Open a PR when done. + +> [!TIP] +> Links to PEPs, CPython docs, PyPI, GitHub repos/issues, CVEs, and +> python.org releases are automatically styled as inline reference badges. +> Just use normal Markdown links — no special syntax needed. +> +> If you're using the Keystatic editor, you also have access to explicit +> inline components: `{% GhUser name="hugovk" /%}`, `{% Pep number=649 /%}`, etc. + +### Authors -> [!NOTE] -> You have access to a few custom components that can be used like -> `{% GhUser name="hugovk" /%}`, but PEPs, CPython docs, and GitHub links -> will automatically be picked up if you use standard markdown via the -> URL regex. +Author profiles live in `content/authors/{id}.json`. If you're writing your +first post, create one (or use the Make target): + +```bash +make content-new-author ID=your-name NAME="Your Name" +``` + +Then edit the JSON to add your GitHub handle, avatar URL, etc. + +## Development + +| Make target | Without make | What it does | +| ------------------ | ------------------------ | ------------------------------------ | +| `make install` | `bun install` | Install dependencies (+ git hooks) | +| `make dev` | `bun run dev` | Start Astro dev server | +| `make build` | `bun run build` | Production build | +| `make preview` | `bun run preview` | Build and preview production locally | +| `make check` | `bun run lint && bun run typecheck` | Run linter + type checker | +| `make spellcheck` | — | Run typos spell checker (needs prek) | +| `make clean` | — | Remove build artifacts and caches | +| `make fresh` | — | Full clean reinstall | + +Run `make help` for the complete list. + +## Project structure + +``` +content/ + authors/ # Author profiles (JSON) + posts/ # Blog posts (Markdown + images) +src/ + components/ # Astro/React components + layouts/ # Page layouts + pages/ # Astro routes + plugins/ # Remark plugins (reference badges, etc.) + assets/ # Styles, fonts +``` From 10a0b57272552375d46515a179d0f53c9f1d5d27 Mon Sep 17 00:00:00 2001 From: Jacob Coffee Date: Tue, 3 Mar 2026 12:53:05 -0600 Subject: [PATCH 2/5] ci: run all precommit things in ci so people dont need precommit --- .github/workflows/ci.yml | 71 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7918712..cd1d11b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,6 +11,75 @@ concurrency: cancel-in-progress: true jobs: + lint: + name: Lint & format + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Check for trailing whitespace + run: | + if grep -rn --include='*.md' --include='*.ts' --include='*.tsx' --include='*.astro' --include='*.json' --include='*.yaml' --include='*.yml' --include='*.css' '[[:blank:]]$' .; then + echo "::error::Trailing whitespace found" + exit 1 + fi + + - name: Check for missing final newline + run: | + bad=0 + while IFS= read -r -d '' f; do + if [ -s "$f" ] && [ "$(tail -c1 "$f" | wc -l)" -eq 0 ]; then + echo "::error file=$f::Missing final newline" + bad=1 + fi + done < <(find . -type f \( -name '*.md' -o -name '*.ts' -o -name '*.tsx' -o -name '*.astro' -o -name '*.json' -o -name '*.yaml' -o -name '*.yml' -o -name '*.css' \) -not -path './node_modules/*' -not -path './.git/*' -print0) + exit $bad + + - name: Validate YAML files + run: | + pip install --quiet yamllint + find . -type f \( -name '*.yaml' -o -name '*.yml' \) -not -path './node_modules/*' -not -path './.git/*' | xargs -r python3 -c " + import sys, yaml + for f in sys.argv[1:]: + try: + yaml.safe_load(open(f)) + except Exception as e: + print(f'::error file={f}::{e}') + sys.exit(1) + " + + - name: Validate JSON files + run: | + find . -type f -name '*.json' -not -path './node_modules/*' -not -path './.git/*' | xargs -r python3 -c " + import sys, json + for f in sys.argv[1:]: + try: + json.load(open(f)) + except Exception as e: + print(f'::error file={f}::{e}') + sys.exit(1) + " + + - name: Check for merge conflict markers + run: | + if grep -rn '<<<<<<< \|=======$\|>>>>>>> ' --include='*.md' --include='*.ts' --include='*.tsx' --include='*.astro' --include='*.json' --include='*.yaml' --include='*.yml' --include='*.css' .; then + echo "::error::Merge conflict markers found" + exit 1 + fi + + - name: Check for large files + run: | + bad=0 + while IFS= read -r f; do + size=$(stat --printf='%s' "$f" 2>/dev/null || stat -f'%z' "$f") + if [ "$size" -gt 512000 ]; then + echo "::error file=$f::File is $(( size / 1024 ))KB (max 500KB)" + bad=1 + fi + done < <(git diff --cached --name-only --diff-filter=d 2>/dev/null || git ls-files) + exit $bad + quality: name: Quality checks runs-on: ubuntu-latest @@ -45,7 +114,7 @@ jobs: build: name: Build runs-on: ubuntu-latest - needs: [quality, spellcheck] + needs: [lint, quality, spellcheck] steps: - name: Checkout uses: actions/checkout@v6 From 7e061e7f9d7bcca7b55e1aa0cedb6e70d400db71 Mon Sep 17 00:00:00 2001 From: Jacob Coffee Date: Tue, 3 Mar 2026 12:54:43 -0600 Subject: [PATCH 3/5] use action to run hooks --- .github/workflows/ci.yml | 77 +++++++--------------------------------- 1 file changed, 13 insertions(+), 64 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cd1d11b..9083433 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,74 +11,23 @@ concurrency: cancel-in-progress: true jobs: - lint: - name: Lint & format + pre-commit: + name: Pre-commit hooks runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v6 - - name: Check for trailing whitespace - run: | - if grep -rn --include='*.md' --include='*.ts' --include='*.tsx' --include='*.astro' --include='*.json' --include='*.yaml' --include='*.yml' --include='*.css' '[[:blank:]]$' .; then - echo "::error::Trailing whitespace found" - exit 1 - fi - - - name: Check for missing final newline - run: | - bad=0 - while IFS= read -r -d '' f; do - if [ -s "$f" ] && [ "$(tail -c1 "$f" | wc -l)" -eq 0 ]; then - echo "::error file=$f::Missing final newline" - bad=1 - fi - done < <(find . -type f \( -name '*.md' -o -name '*.ts' -o -name '*.tsx' -o -name '*.astro' -o -name '*.json' -o -name '*.yaml' -o -name '*.yml' -o -name '*.css' \) -not -path './node_modules/*' -not -path './.git/*' -print0) - exit $bad - - - name: Validate YAML files - run: | - pip install --quiet yamllint - find . -type f \( -name '*.yaml' -o -name '*.yml' \) -not -path './node_modules/*' -not -path './.git/*' | xargs -r python3 -c " - import sys, yaml - for f in sys.argv[1:]: - try: - yaml.safe_load(open(f)) - except Exception as e: - print(f'::error file={f}::{e}') - sys.exit(1) - " - - - name: Validate JSON files - run: | - find . -type f -name '*.json' -not -path './node_modules/*' -not -path './.git/*' | xargs -r python3 -c " - import sys, json - for f in sys.argv[1:]: - try: - json.load(open(f)) - except Exception as e: - print(f'::error file={f}::{e}') - sys.exit(1) - " - - - name: Check for merge conflict markers - run: | - if grep -rn '<<<<<<< \|=======$\|>>>>>>> ' --include='*.md' --include='*.ts' --include='*.tsx' --include='*.astro' --include='*.json' --include='*.yaml' --include='*.yml' --include='*.css' .; then - echo "::error::Merge conflict markers found" - exit 1 - fi - - - name: Check for large files - run: | - bad=0 - while IFS= read -r f; do - size=$(stat --printf='%s' "$f" 2>/dev/null || stat -f'%z' "$f") - if [ "$size" -gt 512000 ]; then - echo "::error file=$f::File is $(( size / 1024 ))KB (max 500KB)" - bad=1 - fi - done < <(git diff --cached --name-only --diff-filter=d 2>/dev/null || git ls-files) - exit $bad + - name: Setup Bun + uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + + - name: Install dependencies + run: bun install --frozen-lockfile + + - name: Run pre-commit hooks via prek + uses: j178/prek-action@v1 quality: name: Quality checks @@ -114,7 +63,7 @@ jobs: build: name: Build runs-on: ubuntu-latest - needs: [lint, quality, spellcheck] + needs: [pre-commit, quality, spellcheck] steps: - name: Checkout uses: actions/checkout@v6 From 6eae61ff3e780c43c60d6af2b41215079a18374d Mon Sep 17 00:00:00 2001 From: Jacob Coffee Date: Tue, 3 Mar 2026 12:56:54 -0600 Subject: [PATCH 4/5] do not require prek --- Makefile | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index f1bd82e..5de097d 100644 --- a/Makefile +++ b/Makefile @@ -20,7 +20,11 @@ help: ## Show this help message .PHONY: install install: ## Install dependencies and git hooks bun install - prek install + @if command -v prek >/dev/null 2>&1; then \ + prek install; \ + else \ + echo "prek not found — skipping git hook setup (optional, see README)"; \ + fi ## Development From 4989813d5daf19a8a5c830229dad6afb8f172862 Mon Sep 17 00:00:00 2001 From: Jacob Coffee Date: Tue, 3 Mar 2026 12:57:48 -0600 Subject: [PATCH 5/5] check for bun install on all platforms --- Makefile | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 5de097d..fbe147b 100644 --- a/Makefile +++ b/Makefile @@ -17,8 +17,23 @@ help: ## Show this help message }' $(MAKEFILE_LIST) @echo "" +.PHONY: check-deps +check-deps: ## Verify required tools are installed + @command -v bun >/dev/null 2>&1 || { \ + echo ""; \ + echo " bun is required but not installed."; \ + echo ""; \ + echo " Install:"; \ + echo " macOS: brew install oven-sh/bun/bun"; \ + echo " Linux/WSL: curl -fsSL https://bun.sh/install | bash"; \ + echo ""; \ + echo " See: https://bun.sh/docs/installation"; \ + echo ""; \ + exit 1; \ + } + .PHONY: install -install: ## Install dependencies and git hooks +install: check-deps ## Install dependencies and git hooks bun install @if command -v prek >/dev/null 2>&1; then \ prek install; \ @@ -29,17 +44,17 @@ install: ## Install dependencies and git hooks ## Development .PHONY: dev -dev: ## Start development server +dev: check-deps ## Start development server bun run dev .PHONY: preview -preview: ## Build and preview production locally +preview: check-deps ## Build and preview production locally bun run preview ## Build .PHONY: build -build: ## Build production bundle +build: check-deps ## Build production bundle bun run build .PHONY: clean @@ -49,11 +64,11 @@ clean: ## Clean build artifacts and caches ## Quality .PHONY: lint -lint: ## Run oxlint on source files +lint: check-deps ## Run oxlint on source files bunx oxlint src/ .PHONY: typecheck -typecheck: ## Run TypeScript type checking +typecheck: check-deps ## Run TypeScript type checking bunx astro check .PHONY: check