Skip to content

fix(blog): publish via PR instead of direct push#689

Merged
antoinedc merged 2 commits intodevelopfrom
feature/blog-stack
Mar 14, 2026
Merged

fix(blog): publish via PR instead of direct push#689
antoinedc merged 2 commits intodevelopfrom
feature/blog-stack

Conversation

@antoinedc
Copy link
Member

Summary

  • Blog publish workflow was failing because develop is a protected branch
  • Now creates a temporary branch, opens a PR, and auto-merges with --admin

Test plan

  • Re-trigger the blog publish workflow after merging

🤖 Generated with Claude Code

Antoine de Chevigné and others added 2 commits March 13, 2026 14:04
… pipeline

1. Shorten the-commerce-layer-erc-8183.md description from 166 to 145 chars
2. Add explicit ≤160 char rule in 2-draft.md prompt with Zod schema reference
3. Add astro build validation gate in draft.sh before committing — resets
   card to Detected on failure instead of pushing a broken article

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The publish workflow was pushing directly to develop which is a
protected branch requiring PRs. Now creates a temporary branch,
opens a PR, and merges it with --admin to bypass required checks.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@antoinedc antoinedc merged commit 1cec73e into develop Mar 14, 2026
3 checks passed
@greptile-apps
Copy link

greptile-apps bot commented Mar 14, 2026

Greptile Summary

This PR fixes the blog publish workflow by routing changes through a temporary branch + PR + --admin merge instead of pushing directly to the protected develop branch. It also adds an Astro build validation gate to draft.sh and fixes an article description that exceeded the 160-character Zod schema limit.

Key changes:

  • blog-publish.yml: Creates a blog/publish-<slug> branch, commits the status change, opens a PR against develop, and immediately merges it with --squash --admin --delete-branch
  • draft.sh: Adds a pre-commit npx astro build validation step; resets the project card to detected on failure
  • 2-draft.md: Clarifies the 160-character description constraint for the AI drafting prompt
  • the-commerce-layer-erc-8183.md: Shortens description to comply with the Zod schema

Issues found:

  • The "Create and merge PR" step uses the wrong condition (steps.resolve.outputs.article != '') — it will run with empty BRANCH/SLUG/TITLE env vars when the "Publish article" step exits early (article already published), causing gh pr create --head "" to fail
  • gh pr merge --admin with the default GITHUB_TOKEN may lack admin privileges needed to bypass branch protection; verify the repo has "Allow GitHub Actions to bypass branch protection" enabled, or swap to a PAT with admin scope
  • Re-triggering the workflow for the same article will fail at git checkout -b "$BRANCH" / git push origin "$BRANCH" since the branch may already exist; using git checkout -B would make re-runs idempotent

Confidence Score: 3/5

  • Safe to merge with low risk if the --admin permission issue is verified, but the early-exit logic bug should be fixed before relying on this in production.
  • The approach is sound and the non-workflow changes are clean, but the "Create and merge PR" step has a real logic bug that causes it to run with empty variables when the article is already published, and the --admin permission requirement introduces an untested assumption about GITHUB_TOKEN capabilities.
  • .github/workflows/blog-publish.yml — the step condition bug and --admin permission concern both live here.

Important Files Changed

Filename Overview
.github/workflows/blog-publish.yml Core change: workflow now creates a temp branch, opens a PR, and merges with --admin instead of pushing directly to develop. Has a logic bug where the "Create and merge PR" step can run with empty outputs when the article is already published, and potential permission issues with --admin using the default GITHUB_TOKEN.
blog/pipeline/draft.sh Adds an Astro build validation step before committing, catching schema/syntax errors early. Resets the project card to 'detected' on build failure. Well-structured addition consistent with the script's existing error-handling pattern.
blog/pipeline/prompts/2-draft.md Minor doc update: clarifies that description must be ≤160 characters and that the Zod schema enforces this at build time.
blog/src/content/blog/the-commerce-layer-erc-8183.md Shortens the article description to comply with the ≤160 character Zod schema constraint.

Sequence Diagram

sequenceDiagram
    participant W as blog-publish.yml
    participant GH as GitHub API
    participant R as develop (protected)

    W->>W: Resolve article (find draft)
    W->>W: Publish article step<br/>(update status: draft→published)
    W->>W: git checkout -b blog/publish-{slug}
    W->>GH: git push origin blog/publish-{slug}
    W->>GH: gh pr create --base develop --head blog/publish-{slug}
    GH-->>W: PR_URL
    W->>GH: gh pr merge PR_URL --squash --admin --delete-branch
    GH->>R: Merge squash commit into develop
    GH-->>W: Branch deleted
    Note over W,R: Bypasses branch protection via --admin flag
Loading

Fix All in Claude Code

Prompt To Fix All With AI
This is a comment left during a code review.
Path: .github/workflows/blog-publish.yml
Line: 93-94

Comment:
**"Create and merge PR" runs when "Publish article" exited early**

When the "Publish article" step hits the early-exit path (`exit 0` for an already-published article), it exits successfully but **never sets** `steps.publish.outputs.branch`, `steps.publish.outputs.slug`, or `steps.publish.outputs.title`. The "Create and merge PR" step only checks `steps.resolve.outputs.article != ''`, which is still truthy, so it proceeds with empty env vars. This causes `gh pr create --head ""` to fail ungracefully.

The condition should also gate on `steps.publish.outputs.branch != ''`:

```suggestion
      - name: Create and merge PR
        if: steps.resolve.outputs.article != '' && steps.publish.outputs.branch != ''
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: .github/workflows/blog-publish.yml
Line: 107

Comment:
**`--admin` may not work with `GITHUB_TOKEN`**

`gh pr merge --admin` bypasses branch protection rules only when the token belongs to a user/actor with admin permissions on the repository. The default `GITHUB_TOKEN` for GitHub Actions is typically given `write` access, **not** admin access.

For this to work, the repository settings must explicitly grant GitHub Actions the ability to bypass branch protection (via "Allow GitHub Actions to bypass branch protection rules" in the branch protection settings), or a PAT with admin scope stored as a secret should be used instead:

```yaml
GH_TOKEN: ${{ secrets.ADMIN_PAT }}
```

If the token lacks admin privileges, the merge will fail with a `422 Unprocessable Entity` error — reproducing the original problem in a different form. It's worth verifying the token/permission setup is correct before relying on this in production.

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: .github/workflows/blog-publish.yml
Line: 81-87

Comment:
**No idempotency for repeated runs on the same article**

If the workflow is re-triggered for the same article (e.g., after a transient failure in the "Create and merge PR" step), `git checkout -b "$BRANCH"` will fail because the local branch already exists, and `git push origin "$BRANCH"` would fail because the remote branch already exists too. Consider deleting the branch first or using `git checkout -B "$BRANCH"` (force-recreate) to make re-runs safe:

```suggestion
          git checkout -B "$BRANCH"
```

For the remote branch, you could add `git push origin "$BRANCH" --force` or delete and re-push, and for the leftover PR/branch from the failed run, a `gh pr close` cleanup step could also help.

How can I resolve this? If you propose a fix, please make it concise.

Last reviewed commit: a11ce93

Comment on lines +93 to +94
- name: Create and merge PR
if: steps.resolve.outputs.article != ''
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Create and merge PR" runs when "Publish article" exited early

When the "Publish article" step hits the early-exit path (exit 0 for an already-published article), it exits successfully but never sets steps.publish.outputs.branch, steps.publish.outputs.slug, or steps.publish.outputs.title. The "Create and merge PR" step only checks steps.resolve.outputs.article != '', which is still truthy, so it proceeds with empty env vars. This causes gh pr create --head "" to fail ungracefully.

The condition should also gate on steps.publish.outputs.branch != '':

Suggested change
- name: Create and merge PR
if: steps.resolve.outputs.article != ''
- name: Create and merge PR
if: steps.resolve.outputs.article != '' && steps.publish.outputs.branch != ''
Prompt To Fix With AI
This is a comment left during a code review.
Path: .github/workflows/blog-publish.yml
Line: 93-94

Comment:
**"Create and merge PR" runs when "Publish article" exited early**

When the "Publish article" step hits the early-exit path (`exit 0` for an already-published article), it exits successfully but **never sets** `steps.publish.outputs.branch`, `steps.publish.outputs.slug`, or `steps.publish.outputs.title`. The "Create and merge PR" step only checks `steps.resolve.outputs.article != ''`, which is still truthy, so it proceeds with empty env vars. This causes `gh pr create --head ""` to fail ungracefully.

The condition should also gate on `steps.publish.outputs.branch != ''`:

```suggestion
      - name: Create and merge PR
        if: steps.resolve.outputs.article != '' && steps.publish.outputs.branch != ''
```

How can I resolve this? If you propose a fix, please make it concise.

Fix in Claude Code

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.

1 participant