This page is for the people who maintain Jinx — registering the GitHub App, deploying the Cloudflare Worker, wiring in new commands. If you just want to use Jinx, Getting started is the page you want.
For the architecture map (what runs where, who triggers it), see How Jinx is built. This page is the operational counterpart: what you do to stand it up, change it, and keep it running.
Jinx posts as jinx[bot] because it authenticates as a
registered GitHub App, not a maintainer’s PAT. Set up in Settings →
Developer settings → GitHub Apps → New on the org:
jinx.issue_comment, issues,
pull_request.Save the App ID, generate a private key, and install the app on every repo Jinx needs to act in.
Two values are required for every workflow:
JINX_APP_ID — the App ID from the registration
above.JINX_PRIVATE_KEY — the App’s private key, pasted
as-is.Both are read by actions/create-github-app-token
at the top of every workflow. Set them at the org level so new repos
pick them up automatically.
Module-specific secrets are only needed if you want that module’s features. A missing module secret is not fatal — Jinx skips the module and logs a hint:
| Secret | Used by |
|---|---|
AIRTABLE_API_KEY |
Airtable sync |
BSKY_USER, BSKY_PASS |
Bluesky announcements |
MASTODON_TOKEN |
Mastodon announcements |
LINKEDIN_ACCESS_TOKEN |
LinkedIn announcements |
SLACK_TOKEN |
Slack management |
MAILCHIMP_API_KEY |
Newsletter |
PLAUSIBLE_API_KEY |
Website analytics |
Jinx loads almost everything from data files in inst/,
so most operational changes don’t need a code release — just a PR.
inst/config/teams.yml — team definitions: roles, repos,
notification channels.inst/config/review-rules.yml — file-path patterns that
drive PR reviewer assignment.inst/config/labels.yml — file-path patterns that drive
PR labelling.inst/config/conferences.yml, events.yml,
languages.yml — module-specific lists.inst/templates/*.md — issue-comment replies, onboarding
checklists, command help.
inst/templates/teams/<name>.md extends the base
onboarding checklist for a specific team.inst/translations/ — message translations indexed by
language code.Editing any of these is a normal PR. The bot image rebuild picks them
up on the next push to main.
Every /jinx <verb> flows through the same two
functions, defined in R/commands.R:
To add a new verb:
cmd_parse() so it returns the structured fields
your verb needs.cmd_execute() to call your
module function.inst/commands/help.md
so /jinx help finds it.tests/testthat/test-commands.R
and the module function in its own test file.That’s it. The bot-commands.yml workflow already calls
cmd_parse + cmd_execute for issue-comment
triggers, and the Cloudflare Worker dispatches Slack-side calls into the
same workflow. You only need to touch a workflow if your verb needs a
new schedule or a separate trigger.
To add Jinx’s PR review to any RLadies+ repo, drop this workflow in:
# .github/workflows/jinx-review.yml
name: PR review
on:
pull_request:
types: [opened, reopened, synchronize]
jobs:
review:
uses: rladies/jinx/.github/workflows/reusable-pr-review.yml@main
secrets: inheritsecrets: inherit is how the caller repo gets
JINX_APP_ID and JINX_PRIVATE_KEY from the
org-level secrets — no copy-pasting.
The same pattern works for
reusable-welcome-contributor.yml,
reusable-thank-contributor.yml, and
reusable-post-checklist.yml.
Workflows run inside ghcr.io/rladies/jinx-bot:latest,
which has the package and all its dependencies pre-installed. infra-build-bot-image.yml
rebuilds it when DESCRIPTION, Dockerfile, or
other runtime files change on main. That’s why a typical
Jinx command run finishes in a few seconds — no
install.packages at run time.
When you add a new R dependency:
DESCRIPTION.main.infra-build-bot-image to finish — until then,
runs still use the old image and your new dependency won’t be
there.The Slack bot answers questions by retrieving from a Cloudflare
Vectorize index that’s built by Jinx on a weekly schedule. That builder
lives in R/rag-*.R and is configured by
inst/config/rag-sources.yml. See the RAG indexer article for the contributor
guide — what each source does, how to add a new one, and which env vars
the workflow needs.
The Worker at https://jinx.rladies.workers.dev is Jinx’s
front door for Slack and Airtable. It’s deployed by infra-deploy-worker.yml
on every push to worker/ on main.
Worker secrets are managed through Wrangler:
cd worker
wrangler secret put SLACK_SIGNING_SECRET
wrangler secret put SLACK_CLIENT_ID
wrangler secret put SLACK_CLIENT_SECRET
wrangler secret put GITHUB_PATKV namespaces (SLACK_TOKENS,
AIRTABLE_BASES) and the Vectorize index
(rladies-content) are declared in
wrangler.jsonc — adding one means editing that file, not
running a command.
For what the Worker actually does end-to-end, see How Jinx is built.
cli log of the failing step. Most
module functions print their own context./jinx ... got no reply. Tail
the Worker (wrangler tail from worker/).
Failures here are almost always signature verification, a missing env
var, or a Slack scope that wasn’t granted.infra-build-bot-image to finish, then try again.The audit log is the Actions run history. Logs for runs older than 14 days are gone; if you need to preserve evidence, screenshot it before the retention window closes.