Repository navigation
Scheduling
Language: English · فارسی
pulsecheck runs once and exits. Something else starts it every few minutes. Pick one.
The quickest way is the minimal template, arian24b/pulsecheck-template. It has only four files: pulsecheck.yml, one workflow, a short README and a .gitignore. The workflow installs pulsecheckcli from PyPI, so no source code is copied into your repository.
- Click Use this template → Create a new repository, and choose Private (your
pulsecheck.ymllists your hosts). - Edit
pulsecheck.yml: put your sites undersites:and keep tokens as${VARS}. - Add each variable as a secret (Settings → Secrets and variables → Actions) and list it under
env:in.github/workflows/monitor.yml. The template already listsTG_TOKENandTG_CHAT. - Run it once with Actions → monitor → Run workflow.
Notes
- The workflow runs every 5 minutes. In the template repository itself it only runs when started by hand, so your copy is the only one that is scheduled.
- It installs
pulsecheckcli>=0.1,<1withuvxon every run. To pin an exact version, changePULSECHECK:in the workflow'senv:. - shoutrrr runs from its docker image (Docker is preinstalled on GitHub's Ubuntu runners), so there is nothing to install.
- The workflow also writes
pulsecheck status --mdto the run summary, so each run shows the current state without a dashboard. - State is stored with
actions/cache(restored from the newest entry, saved after each run). No commits are made. - GitHub may delay scheduled runs by several minutes and disables schedules in repositories with no activity for 60 days.
- The main
pulsecheckrepository also contains amonitor.ymlthat uses the checked-out source (uv run); use it only if you cloned the whole project.
GitHub's own schedule trigger is best effort. New or quiet repositories may get no scheduled runs for hours, and */5 runs are often delayed or skipped. The template's workflow also accepts repository_dispatch (event type pulsecheck), so any external scheduler (cron-job.org, a server's crontab, Cloudflare Cron) can start it:
curl -X POST \
-H "Authorization: Bearer $GITHUB_PAT" \
-H "Accept: application/vnd.github+json" \
https://api.github.com/repos/OWNER/REPO/dispatches \
-d '{"event_type":"pulsecheck"}'The token needs repo scope (classic) or Contents: write (fine-grained, that repository only). Run it every 5 minutes; concurrency: monitor stops overlapping runs. You can keep the built-in schedule as well.
- Push the repository to GitLab and commit your
pulsecheck.yml. -
Build → Pipeline schedules → New schedule, cron
*/5 * * * *. - The job image has no Docker, so
shoutrrr_bin: autouses the binary the job downloads (SHOUTRRR_VERSIONin.gitlab-ci.yml). -
Settings → CI/CD → Variables: add every
${VAR}your file uses (mask the secrets). - The job only runs for scheduled pipelines and caches
pulsecheck.dbunder one key. If your runners do not share a cache, state is lost between runs (see Troubleshooting).
Both have their own cron and their own limits (Vercel Hobby: one run per day; Cloudflare Free: 10 ms CPU per run). Setup and every limit are on the Serverless page.
The easy way: pulsecheck init adds the cron job for you (see Commands). By hand, in crontab -e:
# crontab -e
*/5 * * * * PATH="$HOME/.local/bin:/usr/local/bin:/usr/bin:/bin" flock -n /tmp/pulsecheck.lock pulsecheck run >> $HOME/pulsecheck.log 2>&1pulsecheck finds ~/.config/pulsecheck/pulsecheck.yml and the .env file next to it, so no secrets go into the crontab. State lives in state_file on disk. flock -n prevents overlapping runs.