On a schedule
Back up exports to GitHub each night
Every night your configuration or workflow exports are saved to a GitHub repository, and Slack lists exactly what changed.
- Runs
- On a schedule
- Apps
- GitHub, Slack
- AI
- Not needed
- Access
- contents:write (pull_requests:write for PR mode); chat:write
Send this to your assistant
Create a ClickRuntime automation: every night at 2, fetch the export from our tool's API, commit any changed files to the acme/backups repo, and post the list of changes to #eng.
First time? Adding ClickRuntime to your assistant takes about two minutes.
Why use it
Why teams use this automation
An operations team keeps dozens of workflows and settings in an internal tool. When someone breaks one, nobody can say what it looked like last week, because the only copy is the live one. Restoring means rebuilding from memory.
A nightly export committed to GitHub gives every change a date, a diff and a way back. The Slack message each morning shows what changed overnight, so surprises are spotted the next day instead of weeks later.
What you get out of it
Every change has a history
GitHub keeps each version with the date it changed. You can see what a setting was on any day and restore it.
Changes are announced
The Slack message lists the files that changed. An edit nobody expected gets questioned while people still remember it.
Only real changes are committed
Files that have not changed are skipped, so the history stays clean. Each commit means something actually moved.
Recovery is a copy away
When something breaks, the last good version is one click away in GitHub. Restoring takes minutes, not a day of rebuilding.
How it works
What happens, step by step
Every night, ClickRuntime fetches the latest export from your tool.
It compares each file with the version already in your GitHub repository.
Files that changed, or are new, are saved to the repository with a short message.
A summary of what changed is posted to your #eng Slack channel.
Before it runs live
- Connect GitHub
- Connect Slack, then invite the app to the channel (type /invite @ClickRuntime there)
What you get
Build your own
Need it to work differently?
Your own rules
Conditions, thresholds, filters and exceptions, written the way you'd explain them to a colleague.
Any number of apps
One automation can read from one app and update several others. Over 248 apps are ready, and anything with an API works too.
AI where it helps
Summaries, classification, extraction and drafts use ClickRuntime's built-in AI, with no extra key.
On a schedule or on each event
Runs as often as every 5 minutes, or the moment an app sends an event, and keeps track of what it already handled.
Changes you can ask for
- Run it at a different time, more or less often, or only on weekdays
- Add an AI step, for example to summarize, sort or draft a reply
- Add another app, for example also send it to Google Sheets
- Combine it with other GitHub and Slack steps into one automation
Under the hood
The code that runs this automation
import base64, json
from clickruntime import on_trigger, credentials, http, notify
def gh(method, path, **kw):
resp = http.request(method, f"https://api.github.com{path}", headers={
"Authorization": f"Bearer {credentials.connection('github', 'work')}", "Accept": "application/vnd.github+json"}, **kw)
return resp.raise_for_status() or (resp.json() if resp.content else None)
REPO, EXPORT_URL = "acme/backups", "https://tools.acme.example/api/export"
@on_trigger
def run(event):
items = http.get(EXPORT_URL, headers={"Authorization": f"Bearer {credentials.secret('EXPORT_TOKEN')}"}).json()
changed = []
for item in items:
path = f"exports/{item['id']}.json"
content = json.dumps(item, indent=2, sort_keys=True) + "\n"
try:
current = gh("GET", f"/repos/{REPO}/contents/{path}")
except Exception:
current = None
if current and base64.b64decode(current["content"]).decode() == content:
continue
gh("PUT", f"/repos/{REPO}/contents/{path}", json={"message": f"Backup {item.get('name', path)}",
"content": base64.b64encode(content.encode()).decode(), **({"sha": current["sha"]} if current else {})})
changed.append(item.get("name", path))
if changed:
notify.slack(f"Nightly backup: {len(changed)} changed\n" + "\n".join(f"• {c}" for c in changed), channel="#eng")
return {"items": len(items), "changed": len(changed)}FAQ
Common questions
What can it back up?
Can it open a pull request instead of committing directly?
Should the repository be private?
What permissions does it need?
Does it need AI?
How many runs does it use?
Can I change how it works?
Related
You might also like
Track flaky CI jobs in GitHub Actions
Each morning Slack lists the GitHub Actions workflows that failed and then passed on a re-run in the last week, so you know which tests are flaky.
See how it worksRemind reviewers in Slack about open GitHub pull requests
Each weekday morning, reviewers with pull requests waiting more than a day are mentioned by name in a Slack channel.
See how it worksPost a daily engineering digest from GitHub in Slack
Each morning before standup, Slack shows what merged yesterday, which pull requests are waiting for review and which issues were opened.
See how it worksKeep exploring
Set up “Back up exports to GitHub each night” from your assistant
Copy the prompt above, or connect your assistant first. Free plan, no credit card.