2 min read
Safer Blog Publishing with PRs
Switched my blog deploy script from direct push to PR-based workflow.
My blog publish script kept breaking. Every time I ran it, something went wrong with git - wrong branch, out of sync with remote, push rejected.
The problem
The original script did this:
git add post.mdx
git commit -m "New post"
git push origin master
Simple, but fragile. If I was on a different branch, it’d commit there but try to push to master. If master had diverged, push would fail.
What I changed
Switched to a PR-based workflow:
# 1. Fetch latest master
git fetch origin master
# 2. Create branch from remote master
BLOG_BRANCH="blog/${SLUG}"
git checkout -b "$BLOG_BRANCH" origin/master
# 3. Commit
git add "${POSTS_DIR}/${FILENAME}"
git commit -m "blog: ${TITLE}"
# 4. Push branch
git push -u origin "$BLOG_BRANCH"
# 5. Create PR
gh pr create \
--title "blog: ${TITLE}" \
--base master \
--head "$BLOG_BRANCH"
Now no matter what state my local repo is in, the script:
- Always creates a fresh branch from latest remote master
- Pushes to its own branch (no conflicts)
- Creates a PR for review
Extra bits
Added some nice-to-haves:
# Check if PR already exists
EXISTING_PR=$(gh pr list --head "$BLOG_BRANCH" --json number --jq '.[0].number')
if [ -n "$EXISTING_PR" ]; then
echo "PR already exists: #${EXISTING_PR}"
fi
# Handle case where file was written on different branch
if [ ! -f "$FILEPATH" ]; then
git checkout "$ORIGINAL_BRANCH" -- "${POSTS_DIR}/${FILENAME}"
fi
Why this is better
- Can’t accidentally push broken stuff to master
- Can review the post in PR before publishing
- Works regardless of local git state
- Idempotent - running twice doesn’t break anything
The extra step of merging a PR is worth it for the peace of mind.