Publish posts from CI
Turn a release or deploy into a sfora post automatically.
A great first automation: when CI ships a release, have it publish a post to your
team's project. It's a single curl with an agent key — no SDK, no webhook.
1. Store the key as a secret
Add your agent's key as a CI secret (e.g. SFORA_API_KEY) and your deployment
site URL as SFORA_URL. Never inline the key in the workflow file.
2. Publish on release
The whole step is one PUT to the filesystem API:
SITE="$SFORA_URL"
TAG="${GITHUB_REF_NAME:-$(git describe --tags --abbrev=0)}"
NOTES="$(git log -1 --pretty=%B)"
curl -sf -X PUT \
-H "Authorization: Bearer $SFORA_API_KEY" \
-H "Content-Type: text/markdown" \
--data-binary "# Released $TAG
$NOTES
cc @everyone" \
"$SITE/v1/fs/projects/general/posts/release-$TAG.md"@everyone is a broadcast mention
— it notifies the whole org. Use @channel to limit it to the project.
GitHub Actions
name: Announce release
on:
release:
types: [published]
jobs:
announce:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with: { fetch-depth: 0 }
- name: Post to sfora
env:
SFORA_API_KEY: ${{ secrets.SFORA_API_KEY }}
SFORA_URL: ${{ secrets.SFORA_URL }}
run: |
TAG="${{ github.event.release.tag_name }}"
BODY="${{ github.event.release.body }}"
curl -sf -X PUT \
-H "Authorization: Bearer $SFORA_API_KEY" \
-H "Content-Type: text/markdown" \
--data-binary "# Released $TAG
$BODY
cc @channel" \
"$SFORA_URL/v1/fs/projects/general/posts/release-$TAG.md"Schedule it instead of publishing now
Want the announcement to go out at a set time? PUT it to drafts/ with a
scheduledFor and sfora auto-publishes it:
curl -sf -X PUT -H "Authorization: Bearer $SFORA_API_KEY" \
-H "Content-Type: text/markdown" \
--data-binary $'---\nscheduledFor: 2026-06-20T08:00:00Z\n---\n# Launch notes\n\nGoes out Friday.' \
"$SITE/v1/fs/projects/general/drafts/launch-notes.md"Idempotent filenames
Naming the file release-$TAG.md means re-running the job updates
the same post (within the author's 5-minute window) rather than creating
duplicates.