feat(automations): reliable cron scheduling and webhook-driven push/CI triggers (#1972)
* feat(automations): reliable cron scheduling and webhook-driven push/CI triggers Automations were "wounded": cron schedules mishandled timezones and some never fired, and the GitHub push/CI trigger types were coming-soon stubs. Cron (fix): - The scheduler reduced every cron expression to a fixed interval derived only from a */N step in the minute/hour field, so any pinned schedule (0 9 * * *, 30 14 * * *, weekday ranges, day-of-month) never fired, and the configured timezone was parsed but never used. - Replace the interval approximation with robfig/cron/v3: shouldFire now computes the true next fire time in the configured timezone (DST-aware, defaulting to UTC for host-independence), anchored to last-evaluated or creation time. Dead interval-parsing helpers and shorthand constants removed. GitHub push + CI triggers (feat): - Implement push and CI-failure triggers end to end via the existing per-workspace GitHub App webhook plumbing (#1810): the HMAC-verified webhook service now parses push and completed check_run events, resolves the installation to its workspaces, and publishes normalized bus events. - A new automation subscriber matches enabled github_push / github_ci triggers by workspace + repo + branch/conclusion/check-name filters and fires them (deduped by commit SHA / check-run id). The old poll-based stub evaluators are removed; the PR poll path is unchanged. - Subscribe the App manifest to push/check_run and enable both trigger types in the registry (CI defaults to the failure conclusion). Docs: - Update docs/public/feature-status.md and automation-and-mcp.md so the cron and push/CI rows reflect shipped reality. Tests: regression tests pin the previously-never-firing cron shapes, timezone/DST behavior, and host-independence; backend tests cover the webhook parse->publish and subscriber match/fire/dedup flows for both push and CI-failure. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(automations): populate push.message and ci.url placeholders in fired trigger data Address PR review blockers: the default push and CI automation prompts reference {{push.message}} and {{ci.url}}, which the interpolator maps to data["message"] / data["html_url"] — but the webhook subscriber never populated those fields, so both always rendered empty. - Parse head_commit.message (push) and check_run.html_url (CI) in the GitHub webhook service and carry them on the published bus payloads. - Include "message" / "html_url" in the fired trigger data so the placeholders resolve; extend the webhook and subscriber tests to assert both flow through end to end. Non-blocking review cleanups: - Replace the misleading reuse of matchesAuthors for CI conclusions/check names with a clearly-named matchesFilterValue helper. - Drop dead context.Background() line and its unused import from the cron regression test. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(automations): scope webhook triggers to active installs and per-branch dedup Address CodeRabbit review on the push/CI webhook triggers: - Security: resolveWorkspaceIDs now only returns connections whose status is active, so a suspended or revoked GitHub App installation can no longer fire push/CI automations. - Correctness: include the branch in the push dedup key (push:owner/name@branch@sha) so the same commit pushed to two matching branches fires once per branch instead of being suppressed. - Correctness: add an optional head-branch filter to github_ci triggers and gate CI matching on it, matching the push trigger's branch-scoping. - Stability: make the webhook subscriber's Start retryable — a subscription failure rolls back partial subscriptions and leaves the subscriber un-started so a later Start re-attempts, instead of permanently disabling push/CI processing. - Tests: cover multi-connection workspace resolution (dedup + inactive filtering), per-branch push dedup, and CI branch filtering. - Docs: note the CI branch filter and per-branch push dedup. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test(automations): cover webhook subscriber Start retry-after-failure path Add TestGitHubWebhookSubscriberStartRetryableAfterFailure with a minimal flaky bus whose second Subscribe fails, pinning the retry contract: a subscription failure rolls back the partial subscription and leaves the subscriber un-started, and a later Start re-attempts and succeeds. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Kandev Agent <agent@kandev.dev> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -72,7 +72,7 @@ Released builds can lag this page. Check **Settings > System > About** or `kande
|
||||
| Local Docker and Sprites executors | Dependency-bound | Require the relevant daemon or provider, compatible host/image, token, platform, and credential-copy configuration. |
|
||||
| SSH executor | Limited | Remote sessions support trusted Linux or macOS hosts on amd64 or arm64, with public-key authentication, SFTP, TCP forwarding, and repository-source materialization. It ignores profile prepare/cleanup scripts and retains the remote task directory for manual cleanup. |
|
||||
| Remote Docker executor | In progress | The type and legacy/direct settings fields are registered, but runtime create/stop return `not yet implemented`, and the current **Settings > Executors** hub does not offer it. |
|
||||
| GitHub integration | Dependency-bound | Each workspace selects one PAT, named `gh` account, or App registration plus installation for automation and may add a personal App identity. Registrations can be reused deliberately or separated for independent root credentials and bot identities. Managed task access uses repository-bound broker leases; App tokens are minted for that repository, while redeemed PAT/CLI bearer tokens retain their provider scopes. Explicit profile `GITHUB_TOKEN`/`GH_TOKEN` values remain unmanaged overrides. |
|
||||
| GitHub integration | Dependency-bound | Each workspace selects one PAT, named `gh` account, or App registration plus installation for automation and may add a personal App identity. Registrations can be reused deliberately or separated for independent root credentials and bot identities. Managed task access uses repository-bound broker leases; App tokens are minted for that repository, while redeemed PAT/CLI bearer tokens retain their provider scopes. Explicit profile `GITHUB_TOKEN`/`GH_TOKEN` values remain unmanaged overrides. |
|
||||
| Azure DevOps integration | Limited | Azure DevOps Services supports workspace PAT configuration, read-only work-item and pull-request browsing, feedback, task launch, and durable task PR associations. Azure DevOps Server/TFS, Entra OAuth, writes, watches, and webhooks are not supported; neither `gh` nor `az` is required. |
|
||||
| GitLab integration | Limited | Each workspace can connect one `gitlab.com` or self-managed origin, browse and launch from issues/MRs, link tasks to MRs, run review/issue watches, review and act on linked MRs, assign reviewers, toggle MR notifications, and create/auto-link MRs. Provider permissions and exact host/project identity apply. Browse project narrowing is current-page-only, watches inspect at most their first 50 matches, GitLab has no team review-request equivalent, and issue notification subscription has no UI control. |
|
||||
| Jira integration | Limited | Search/browse, supported transitions, launch presets, task launch, and watches require provider credentials. Launch copies data rather than creating a durable association; each watch poll reads only the first 50 JQL matches. |
|
||||
@@ -80,9 +80,9 @@ Released builds can lag this page. Check **Settings > System > About** or `kande
|
||||
| Sentry integration | Limited | Multi-instance configuration, issue watches, and current-task issue actions are shipped; there is no top-level browser. Watches read only the newest first page, and the status picker allows multiple selections while the backend accepts at most one. |
|
||||
| Slack integration | Experimental | Uses a nonstandard browser-session token/cookie and polling rather than OAuth or a bot installation. A first scan can process up to 30 existing matches, and reactions/replies are best-effort. |
|
||||
| Integration **Enabled** switches | Limited | Jira/Linear/Sentry/Slack switches are browser-local presentation state; they do not stop backend pollers. Pause/delete watches or remove the Slack/provider configuration when polling must stop. |
|
||||
| Manual, preset/`@every` schedule, authenticated webhook, and GitHub PR-open automations | Limited | Task and Run modes are shipped, but Run cannot answer permission prompts. PR triggers need explicit repositories and ignore the saved Opened checkbox. Webhooks silently retain only the first 1 MiB. **Play** remains clickable while disabled but produces no history. |
|
||||
| Fixed cron timezone behavior | Limited | The UI accepts fixed cron and timezone values, but the current interval scheduler does not honor the configured timezone and some fixed cron expressions may never fire. Prefer tested presets or `@every` intervals. |
|
||||
| GitHub push and CI automation triggers | In progress | Trigger types and UI labels exist as coming-soon/stub paths; they are not working production triggers. GitHub's separate opt-in PR CI-fix automation is shipped. |
|
||||
| Manual, cron/`@every` schedule, authenticated webhook, and GitHub PR-open automations | Limited | Task and Run modes are shipped, but Run cannot answer permission prompts. PR triggers need explicit repositories and ignore the saved Opened checkbox. Webhooks silently retain only the first 1 MiB. **Play** remains clickable while disabled but produces no history. |
|
||||
| Calendar cron and timezone scheduling | Supported | Fixed calendar cron expressions (pinned minutes/hours, weekday ranges, day-of-month), named descriptors, and `@every` shorthand all fire at their correct next occurrence. The configured timezone is honored including its daylight-saving transitions; an empty timezone means UTC, so schedules are host-clock independent. The scheduler checks every 30 seconds and deduplicates per trigger per minute. |
|
||||
| GitHub push and CI automation triggers | Dependency-bound | Push and CI-check triggers are webhook-driven end to end (HMAC-verified GitHub App webhook → installation-to-workspace resolution → automation run). They require a workspace GitHub App connection whose installation is subscribed to the `push`/`check_run` events; an App created before this support existed must be reinstalled to receive them. CI matching defaults to the `failure` conclusion, enabling auto-fix-CI flows. GitHub's separate opt-in PR CI-fix automation remains shipped. |
|
||||
| Automation Run mode | Limited | Creates a hidden ephemeral task and starts immediately. It cannot require user input. Automatic worktree/branch reaping applies only when a Worktree runtime ID is present; other executors follow their own lifecycle. |
|
||||
|
||||
## MCP, clients, and operation
|
||||
|
||||
Reference in New Issue
Block a user