Integrations · GitHub
Draft pull requests in the blog directory you already have
Stenlio installs on one private repository, writes only inside the Markdown or MDX directory you register, and opens a draft pull request only after you approve the article.
Last substantive change:
What is supported
One private GitHub repository containing an existing Markdown or MDX content directory. Exactly one: an installation that hands Stenlio more than one repository, or a public one, is refused rather than resolved by guessing. Stenlio does not create your blog, choose your framework, or restructure your repository — it writes a file into the structure you already publish from.
Not supported: repositories without a content directory, writes outside the registered directory, organisation-wide installs, and any path that ends in an extension you did not register.
Setup
- 1. Install
- Install the Stenlio GitHub App on one private repository. Not on the organisation.
- 2. Register the surface
- Point Stenlio at the directory your blog already lives in — for example content/blog or src/content/posts — and at the file extensions it uses.
- 3. Give the site URL
- Your canonical public website. The crawl and the repository read are correlated against each other, so a mismatch is reported rather than silently ignored.
- 4. Approve a draft
- When an article artifact is ready, an owner or admin approves it. That is the moment anything is written.
| Step | What you do |
|---|---|
| 1. Install | Install the Stenlio GitHub App on one private repository. Not on the organisation. |
| 2. Register the surface | Point Stenlio at the directory your blog already lives in — for example content/blog or src/content/posts — and at the file extensions it uses. |
| 3. Give the site URL | Your canonical public website. The crawl and the repository read are correlated against each other, so a mismatch is reported rather than silently ignored. |
| 4. Approve a draft | When an article artifact is ready, an owner or admin approves it. That is the moment anything is written. |
What the write path guarantees
- Draft, always
- Pull requests are opened as drafts. Stenlio never marks one ready for review, never merges, and never pushes to your default branch.
- One branch per artifact
- The branch name is derived from the action ID and stored with it, so retries, replayed deliveries, and concurrent approvals all converge on the same branch and the same pull request instead of creating a second one.
- Frozen base commit
- The base revision is read at approval time and stored with the action, so the workflow can tell "the repository has not moved since you approved" from "it has".
- One directory
- Writes are re-derived against your registered directory root inside the approval transaction and again at the write boundary.
- Never an overwrite
- The file is committed without a blob SHA, which makes it a create-only call: if a file already exists at that path, GitHub refuses with a 422 instead of replacing its contents.
| Guarantee | How it holds |
|---|---|
| Draft, always | Pull requests are opened as drafts. Stenlio never marks one ready for review, never merges, and never pushes to your default branch. |
| One branch per artifact | The branch name is derived from the action ID and stored with it, so retries, replayed deliveries, and concurrent approvals all converge on the same branch and the same pull request instead of creating a second one. |
| Frozen base commit | The base revision is read at approval time and stored with the action, so the workflow can tell "the repository has not moved since you approved" from "it has". |
| One directory | Writes are re-derived against your registered directory root inside the approval transaction and again at the write boundary. |
| Never an overwrite | The file is committed without a blob SHA, which makes it a create-only call: if a file already exists at that path, GitHub refuses with a 422 instead of replacing its contents. |
Errors you can hit, and what each one means
- SELECT_EXACTLY_ONE_REPOSITORY
- The installation granted access to more than one repository, to none, or to a public one. Stenlio refuses the install rather than picking for you — go back to GitHub and select exactly one private repository.
- DAILY_PR_LIMIT_REACHED
- A draft pull request was already opened for this company inside the last 24 hours. It is a hard refusal, not a queue — approve again after the window.
- ARTICLE_EXTENSION_NOT_ALLOWED
- The drafted path does not end in one of the extensions you registered for the content surface.
- ARTIFACT_NOT_APPROVABLE
- The artifact has no content or no target path yet, so there is nothing to write.
- ARTIFACT_ACCESS_DENIED
- The caller is not an owner or admin of the workspace the artifact belongs to. Refused before any request reaches your installation.
- Revoked surface or disconnected install
- The approval query joins on a live content surface, a connected integration, and a connected provider account. If any of them is revoked or disconnected the artifact resolves to nothing and approval fails closed.
| Error | Cause |
|---|---|
| SELECT_EXACTLY_ONE_REPOSITORY | The installation granted access to more than one repository, to none, or to a public one. Stenlio refuses the install rather than picking for you — go back to GitHub and select exactly one private repository. |
| DAILY_PR_LIMIT_REACHED | A draft pull request was already opened for this company inside the last 24 hours. It is a hard refusal, not a queue — approve again after the window. |
| ARTICLE_EXTENSION_NOT_ALLOWED | The drafted path does not end in one of the extensions you registered for the content surface. |
| ARTIFACT_NOT_APPROVABLE | The artifact has no content or no target path yet, so there is nothing to write. |
| ARTIFACT_ACCESS_DENIED | The caller is not an owner or admin of the workspace the artifact belongs to. Refused before any request reaches your installation. |
| Revoked surface or disconnected install | The approval query joins on a live content surface, a connected integration, and a connected provider account. If any of them is revoked or disconnected the artifact resolves to nothing and approval fails closed. |
Related
Check your own directory against the real path guard before connecting anything — no account, nothing stored. Permissions and storage explains why contents-write is repository-wide and how the directory limit is enforced anyway. How it works covers the full run that produces the artifact in the first place.