Skip to content

SDK reference: triggers

Triggers define when a workflow runs. KiCI provides 22 trigger types: 16 GitHub webhook triggers and 6 internal/generic triggers for event routing, scheduling, and non-GitHub sources. Each trigger returns a frozen config object with a unique _tag discriminator.

All triggers use a config object form — pass an options object to configure the trigger.

Create a pull request trigger. Returns a frozen PrTriggerConfig directly.

function pr(config?: PrConfigInput): PrTriggerConfig;

Config options:

interface PrConfigInput {
events?: PrEvent[];
target?: string | RegExp | (string | RegExp)[];
source?: string | RegExp | (string | RegExp)[];
paths?: string[]; // Use '!' prefix for exclusions (e.g., '!docs/**')
repos?: string | RegExp | (string | RegExp)[]; // Cross-repo source patterns -- see global-workflows.md
description?: string;
}

PrEvent values: 'opened', 'synchronize', 'reopened', 'closed', 'assigned', 'unassigned', 'labeled', 'unlabeled', 'edited', 'converted_to_draft', 'ready_for_review', 'locked', 'unlocked', 'review_requested', 'review_request_removed', 'auto_merge_enabled', 'auto_merge_disabled'

Default events (when events is not specified): opened, synchronize, reopened, closed

Examples:

// All PRs with default events
pr();
// PRs targeting main with path filter
pr({ target: 'main', events: ['opened', 'synchronize'], paths: ['src/**'] });
// Regex branch pattern
pr({ target: /^release\/v\d+$/ });

Create a push trigger. Returns a frozen PushTriggerConfig directly.

function push(config?: PushConfigInput): PushTriggerConfig;

Config options:

interface PushConfigInput {
branches?: string | RegExp | (string | RegExp)[];
tags?: string | RegExp | (string | RegExp)[];
paths?: string[]; // Use '!' prefix for exclusions (e.g., '!docs/**')
repos?: string | RegExp | (string | RegExp)[]; // Cross-repo source patterns -- see global-workflows.md
description?: string;
}

Examples:

// Any push
push();
// Push to main only
push({ branches: 'main' });
// Push with branch and path filters
push({ branches: ['main', 'develop'], paths: ['src/**'] });
// Tag pushes
push({ tags: ['v*'] });

Create a tag trigger. Returns a frozen TagTriggerConfig.

function tag(config?: TagConfigInput): TagTriggerConfig;

Config options: patterns (string/RegExp/array), description

tag(); // Any tag
tag({ patterns: ['v*'] }); // Semver tags
tag({ patterns: /^v\d+\.\d+$/ }); // Regex match

Create an issue/PR comment trigger. Returns a frozen CommentTriggerConfig.

function comment(config?: CommentConfigInput): CommentTriggerConfig;

Config options: actions (created/edited/deleted), source (issue/pr), bodyMatch (string or RegExp), description

comment(); // Any comment
comment({ bodyMatch: '/deploy' }); // Glob match on body
comment({ bodyMatch: /^\/deploy/i }); // Regex match on body
comment({ source: 'pr', actions: ['created'] }); // PR comments only

Create a pull request review trigger. Returns a frozen ReviewTriggerConfig.

function review(config?: ReviewConfigInput): ReviewTriggerConfig;

Config options: actions (submitted/edited/dismissed), states (approved/changes_requested/commented/dismissed), description

review(); // Any review
review({ states: ['approved'] }); // Approvals only
review({ actions: ['submitted'], states: ['approved'] }); // Submitted approvals

Create a PR review comment trigger. Returns a frozen ReviewCommentTriggerConfig.

function reviewComment(config?: ReviewCommentConfigInput): ReviewCommentTriggerConfig;

Config options: actions (created/edited/deleted), description

reviewComment(); // Any review comment
reviewComment({ actions: ['created'] }); // New review comments only

Create a release trigger. Returns a frozen ReleaseTriggerConfig.

function release(config?: ReleaseConfigInput): ReleaseTriggerConfig;

Config options: actions (published/unpublished/created/edited/deleted/prereleased/released), description

release(); // Any release event
release({ actions: ['published'] }); // Published releases only

Create a repository_dispatch trigger. Returns a frozen DispatchTriggerConfig.

function dispatch(config?: DispatchConfigInput): DispatchTriggerConfig;

Config options: types (string[]), description

dispatch(); // Any dispatch
dispatch({ types: ['deploy', 'rollback'] }); // Specific event types

Create a ref creation trigger (branches/tags). Returns a frozen CreateTriggerConfig.

function create(config?: CreateConfigInput): CreateTriggerConfig;

Config options: refTypes (branch/tag), patterns (string/RegExp/array), description

create(); // Any ref creation
create({ refTypes: ['tag'], patterns: ['v*'] }); // Tag creation only

Create a ref deletion trigger (branches/tags). Returns a frozen DeleteTriggerConfig.

Note: Since delete is a JavaScript reserved word, import as del: import { delete as del } from '@kici-dev/sdk'

function del(config?: DeleteConfigInput): DeleteTriggerConfig;

Config options: refTypes (branch/tag), patterns (string/RegExp/array), description

del(); // Any ref deletion
del({ refTypes: ['branch'], patterns: ['temp/*'] }); // Temp branch cleanup

Create a commit status trigger. Returns a frozen StatusTriggerConfig.

function status(config?: StatusConfigInput): StatusTriggerConfig;

Config options: contexts (picomatch strings like ‘ci/*’), states (error/failure/pending/success), description

status(); // Any status
status({ contexts: ['ci/*'], states: ['success'] }); // CI success

Create a workflow_run trigger. Returns a frozen WorkflowRunTriggerConfig.

function workflowRun(config?: WorkflowRunConfigInput): WorkflowRunTriggerConfig;

Config options: actions (requested/completed/in_progress), workflows (name filters), conclusions (success/failure/cancelled), description

workflowRun(); // Any workflow run
workflowRun({ workflows: ['CI'], actions: ['completed'], conclusions: ['success'] });

Create a fork trigger. No filter fields. Returns a frozen ForkTriggerConfig.

function fork(config?: ForkConfigInput): ForkTriggerConfig;
fork(); // Any fork event
fork({ description: 'Track forks' }); // With description

Create a star trigger. Returns a frozen StarTriggerConfig.

function star(config?: StarConfigInput): StarTriggerConfig;

Config options: actions (created/deleted), description

star(); // Any star event
star({ actions: ['created'] }); // New stars only

Create a watch trigger. Returns a frozen WatchTriggerConfig.

function watch(config?: WatchConfigInput): WatchTriggerConfig;

Config options: actions (started), description

watch(); // Any watch event
watch({ actions: ['started'] }); // Watch started only

Create a catch-all webhook trigger for any GitHub event. Returns a frozen WebhookTriggerConfig. Unlike other triggers, events is required — catch-all must specify what to catch.

function webhook(config: WebhookConfigInput): WebhookTriggerConfig;

Config options: events (required string[]), actions (optional string[]), repos (optional cross-repo source patterns — see global workflows), description

webhook({ events: ['deployment'] }); // Deployment events
webhook({ events: ['deployment', 'deployment_status'] }); // Multiple events
webhook({ events: ['deployment'], actions: ['created'] }); // With action filter

A webhook() trigger fires whenever a matching event arrives via any inbound webhook source within the same org, not just the source the workflow’s repository is bound to. If your repo is registered through a github source and a separate generic source in the same org POSTs an event with a matching name, the workflow still runs.

Two important rules govern the cross-source path:

  1. The registration’s source owns dispatch credentials. The runtime clone, auth, and check-status posting come from the source the workflow was registered with (via its default-branch push), never from the inbound source. A generic webhook fanning out to a github-registered workflow uses the github bundle’s clone token provider — the generic source contributes only the event payload.
  2. Org isolation is structural. A webhook delivered to org A can never trigger a workflow registered against org B. The lookup index is keyed on (customerId, eventName) so cross-org leakage is impossible.

The orchestrator emits kici_cross_source_fanout_size (histogram) per inbound webhook so operators can observe how many workflows each event reaches.

The following 6 trigger types support internal event routing, scheduling, lifecycle orchestration, and non-GitHub webhook sources.

Create a custom event trigger. Fires when a named internal event is emitted from a workflow step via ctx.emit(). Returns a frozen KiciEventTriggerConfig.

function kiciEvent(config: KiciEventConfigInput): KiciEventTriggerConfig;

Config options:

interface KiciEventConfigInput {
name: string; // Required: event name to listen for
match?: Record<string, unknown>; // JSONPath payload matching (e.g., { '$.env': 'prod' })
not?: Record<string, unknown>; // Negative JSONPath filter
source?: string; // Cross-repo source filter (e.g., 'org/infra-repo')
description?: string;
}
kiciEvent({ name: 'deploy-complete' }); // Match by name
kiciEvent({ name: 'deploy-complete', match: { '$.env': 'prod' } }); // With payload filter
kiciEvent({ name: 'deploy-complete', not: { '$.env': 'staging' } }); // Negative filter
kiciEvent({ name: 'deploy-complete', source: 'org/infra-repo' }); // Cross-repo

Create a workflow completion trigger. Fires automatically when another workflow finishes execution. Returns a frozen WorkflowCompleteTriggerConfig.

function workflowComplete(config?: WorkflowCompleteConfigInput): WorkflowCompleteTriggerConfig;

Config options:

interface WorkflowCompleteConfigInput {
name?: string; // Filter by workflow name
status?: WorkflowCompleteStatus[]; // Filter by completion status
source?: string; // Cross-repo source filter
description?: string;
}
type WorkflowCompleteStatus = 'success' | 'failed' | 'cancelled';
workflowComplete(); // Any workflow completion
workflowComplete({ name: 'CI' }); // Specific workflow
workflowComplete({ name: 'CI', status: ['success'] }); // Success only
workflowComplete({ name: 'CI', status: ['success'], source: 'org/repo' }); // Cross-repo

Create a job completion trigger. Fires automatically when a specific job within a workflow finishes. Returns a frozen JobCompleteTriggerConfig.

function jobComplete(config?: JobCompleteConfigInput): JobCompleteTriggerConfig;

Config options:

interface JobCompleteConfigInput {
workflow?: string; // Filter by workflow name
job?: string; // Filter by job name
status?: JobCompleteStatus[]; // Filter by completion status
source?: string; // Cross-repo source filter
description?: string;
}
type JobCompleteStatus = 'success' | 'failed' | 'cancelled' | 'skipped';
jobComplete(); // Any job completion
jobComplete({ workflow: 'CI', job: 'build' }); // Specific workflow + job
jobComplete({ workflow: 'CI', job: 'build', status: ['success'] }); // Success only
jobComplete({ workflow: 'CI', job: 'build', source: 'org/repo' }); // Cross-repo

jobComplete() starts a new workflow run that reacts to another job finishing (gated on the prior job’s status). For same-run fan-out — generating follow-up jobs from a prior job’s outputs within the same run — use a result-aware dynamicJob(group, { needs, generate }) instead.

Create a generic webhook trigger. Fires when a non-GitHub webhook is received from an external source configured via the admin API. Returns a frozen GenericWebhookTriggerConfig.

function genericWebhook(config: GenericWebhookConfigInput): GenericWebhookTriggerConfig;

Config options:

interface GenericWebhookConfigInput {
source: string; // Required: must match `--name` from `kici-admin source add generic`
events?: string[]; // Filter by event types
match?: Record<string, unknown>; // JSONPath payload matching
not?: Record<string, unknown>; // Negative JSONPath filter
auth?: GenericWebhookAuth; // HMAC or API key authentication
path?: string; // URL path pattern (replaces source for URL matching)
description?: string;
}
genericWebhook({ source: 'argocd' }); // Any event from ArgoCD
genericWebhook({ source: 'argocd', events: ['deploy.success'] }); // Specific events
genericWebhook({ source: 'argocd', match: { '$.env': 'prod' } }); // With payload filter
genericWebhook({ source: 'argocd', not: { '$.dry_run': true } }); // Negative filter
genericWebhook({
source: 'stripe',
auth: { method: 'hmac-sha256', secret: 'stripe-key', signatureHeader: 'stripe-signature' },
}); // HMAC auth
genericWebhook({ source: 'slack', auth: { method: 'api-key', secret: 'slack-token' } }); // API key auth
genericWebhook({ source: 'stripe', path: 'stripe/payments' }); // URL path pattern

Create a cron-based schedule trigger. Returns a frozen ScheduleTriggerConfig.

function schedule(config: ScheduleConfigInput): ScheduleTriggerConfig;

Config options:

interface ScheduleConfigInput {
cron: string; // Required: cron expression (5-field)
timezone?: string; // Timezone for cron evaluation (default: 'UTC')
description?: string; // Human-readable description of the schedule
}
schedule({ cron: '0 * * * *' }); // Every hour
schedule({ cron: '0 0 * * *' }); // Daily at midnight UTC
schedule({ cron: '0 9 * * 1', timezone: 'America/New_York' }); // Monday 9am ET
schedule({ cron: '*/15 * * * *', description: 'health check every 15 min' });

Create a lifecycle trigger for cross-workflow orchestration events. Returns a frozen LifecycleTriggerConfig.

function lifecycle(config: LifecycleConfigInput): LifecycleTriggerConfig;

Config options:

interface LifecycleConfigInput {
events: LifecycleEvent[]; // Required: lifecycle events to listen for
sources?: string[]; // Optional: filter by source repo (e.g., 'org/repo')
description?: string; // Human-readable description
}
type LifecycleEvent = 'workflow_complete' | 'job_complete' | 'job_failed' | 'registration_updated';
lifecycle({ events: ['workflow_complete'] }); // Any workflow completion
lifecycle({ events: ['job_failed'], sources: ['org/deploy-repo'] }); // Job failures from specific repo
lifecycle({ events: ['registration_updated'] }); // Workflow registration changes

Both pr() and push() (as well as tag(), create(), and delete()) accept glob strings and RegExp literals for pattern matching:

// Glob patterns (micromatch syntax)
pr({ target: ['main', 'release/*', 'feature/**'] });
// Regex patterns
pr({ target: /^release\/v\d+\.\d+$/ });
// Mixed
push({ branches: ['main', /^hotfix\//] });

Glob patterns use micromatch syntax. Regex patterns use standard JavaScript RegExp.