A GitHub Action that posts to Nostr. Monitors multiple repos for commits and posts scheduled educational content.
-
Create this repo on GitHub (can be private)
-
Add your Nostr secret key as a repository secret named
NOSTR_NSEC- Settings > Secrets and variables > Actions > New repository secret
- Accepts both
nsec1...and hex format
-
Copy and configure
herald.config.example.json→herald.config.json:
{
"relays": [
"wss://relay.damus.io",
"wss://nos.lol",
"wss://relay.primal.net"
],
"repos": [
{
"owner": "GITHUB_USER_NAME",
"name": "GITHUB_PROJECT_NAME",
"projectName": "PROJECT_NAME_FOR_NOTE"
}
]
}-
Add educational content (optional) as
.mdfiles in/notes -
Enable schedules by uncommenting the
schedulelines in:.github/workflows/commits.yml.github/workflows/notes.yml
-
Push to GitHub and the workflows will run on schedule
Every 3 hours, Herald checks each configured repo for new commits via GitHub API and posts them:
📦 PROJECT_NAME_FOR_NOTE commit
fix: handle edge case in validation
abc1234
https://github.com/GITHUB_USR_NAME/GITHUB_PROJECT_NAME/commit/abc1234
On first run, Herald records the latest commit as a baseline without posting, so you don't spam old commits.
Each run also posts one random note from /notes. Notes cycle without repeats until all have been posted.
Add entries to the repos array:
{
"owner": "GITHUB_USER_NAME",
"name": "GITHUB_PROJECT_NAME",
"projectName": "PROJECT_NAME_FOR_NOTE"
}owner+name= GitHub repo pathprojectName= Display name in posts
Schedules are commented out by default. Uncomment and edit in .github/workflows/commits.yml or .github/workflows/notes.yml:
schedule:
- cron: "0 */3 * * *" # Every 3 hours
- cron: "0 */6 * * *" # Every 6 hours
- cron: "0 12 * * *" # Once daily at noon UTCConfigure relays in herald.config.json. Herald broadcasts to all relays in parallel.
Run either workflow manually with dry run:
- Go to Actions > Herald - Commits (or Herald - Notes)
- Click "Run workflow"
- Check "Dry run"
- Run
This fetches commits or selects a note but doesn't broadcast.
Herald tracks state in .state.json:
repos: Last seen commit SHA per repoposted: List of posted note filenames
This file is auto-committed after each run.