GitHub Actions
The Sitepaste deploy action publishes a directory of Markdown files from your repository and deploys your site. Push to main, and your changes are live in seconds. It is the natural fit for docs that live alongside code, and it works just as well for a blog kept in a repo.
Using the action requires an API token, which is a Pro plan feature.
Quick start
Create an API token in the Sitepaste dashboard under Account > Tokens (see authentication), and add it to your repository as a secret named SITEPASTE_TOKEN.
Then add a workflow at .github/workflows/deploy.yml:
name: Deploy docs
on:
push:
branches: [main]
paths: [docs/**]
concurrency:
group: sitepaste-deploy-${{ github.ref }}
cancel-in-progress: true
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: sitepaste/integrations/actions/deploy@v1
with:
api-token: ${{ secrets.SITEPASTE_TOKEN }}
content-dir: docs
content-type: docs
Every run validates all files, publishes them in one batch, and triggers a deploy.
Inputs
| Input | Required | Default | Description |
|---|---|---|---|
| api-token | Yes | Sitepaste API token. Store it as a repository secret. | |
| content-dir | No | content | Directory containing the Markdown files. |
| content-type | No | docs | Content type for all pages: docs, blog, or standalone. |
| site-id | No | Target site. Defaults to your workspace’s default site. | |
| dry-run | No | false | Validate and preview without publishing or deploying. |
| prune | No | false | Delete pages of this content type that have no matching file, making the directory the source of truth. |
Outputs: page-count (pages published) and deploy-url (the deployed site’s URL).
Sections from directories
The action maps your directory structure to sections. Files at the root of the content directory have no section; files in a subdirectory use the subdirectory name:
docs/
overview.md → /docs/overview
guides/
getting-started.md → /docs/guides/getting-started
deployment.md → /docs/guides/deployment
With content-type: standalone, the same layout produces top-level paths instead: guides/getting-started.md is published at /guides/getting-started. Standalone sections may also nest one level. A second directory becomes a sub-section:
api/
overview.md → /api/overview
builds/
post-builds.md → /api/builds/post-builds
Directories beyond that depth (one level for docs and blog, two for standalone) are ignored for the section, and the action prints a warning. A section field in front matter overrides the directory, and may itself be a nested path like api/builds on standalone pages. Set it to an empty string to clear the section for a file inside a subdirectory.
Directory casing carries through as the section’s display name: a directory named API/ publishes at /api/ and displays as “API” in the navigation, exactly as if you had typed it in the dashboard. Captured casing only fills in a display name where none is set, so a rename made in the dashboard survives every deploy.
Front matter
All fields are optional. Without front matter, the slug comes from the filename and the title from the slug.
| Field | Description |
|---|---|
| slug | URL slug for the page. |
| title | Page title. |
| contentType | docs, blog, standalone, or homepage. Defaults to the workflow’s content-type input. A homepage file publishes at / and must sit at the content root. |
| section | Overrides the directory-based section. |
| description | Meta description. |
| api_endpoint | Marks the page as an API reference, like GET /pages/{slug}. See API reference pages. |
| draft | Set to true to keep the page off the deployed site. |
| tags | A YAML list of tags. Casing is kept as the display name: iOS is stored as ios and displays as iOS. |
| date or publishedAt | Publish date. Date-only values like 2026-02-19 are accepted. |
| author | Author to credit the page to, as an author ID from GET /authors (not a name — names are not unique). Empty string removes the author. |
| og_image_url | Social preview image URL. |
| language | Language tag for the page, like en or pt-BR. |
| theme, primary_color, font_size, code_theme_light, code_theme_dark | Per-page theme overrides. Empty string resets a field to inherit from the site. |
| show_toc, show_comments, … | The boolean theme overrides, in snake_case: true, false, or "inherit". |
One field is deliberately missing: password. Front matter is committed to the repository, so a page password written there would be readable by anyone with repo access and preserved in git history — not a secret. The action fails the run if it finds one; set page passwords in the dashboard or through the API instead.
What the action does and does not do
It validates before sending. Slug format and length, title, description, and content size limits, tag limits, duplicate slugs, and dates are all checked locally first. If anything fails, the workflow fails with an annotation pointing at the exact file, and nothing is published.
It publishes everything, every run. Each run sends the full set of files as one batch. Pages are matched by slug, so existing pages are updated in place.
It does not delete unless you ask. By default, a file you remove from the repository stays published on your site. Set prune: 'true' to make the directory the source of truth: pages of the deployed content type with no matching file are deleted in the same run, so removed and renamed files clean up after themselves. Use pruning only when the repository owns that content type, since it will also delete pages of the same type that were created in the dashboard or from Obsidian. Combine it with dry-run to preview what would be deleted.
It always deploys. Every non-dry run ends by triggering a deploy, which counts against your monthly deploy quota. Use dry-run: 'true', for example on pull requests, to check changes without publishing.
Media is separate. Relative image references like  are not uploaded; the action warns about them. Upload images through the dashboard or the media API and reference them by URL.
The action source lives in the integrations repository. For the underlying API, see the pages and builds reference.