Skip to content

Configure Client-Side Triggers

Client-side triggers are automated hooks that run scripts or programs on your local machine during workspace lifecycle events. You can use them to enforce code formatting, run linters and test suites before publishing changes, or send notifications after a publish succeeds.

FlexVault supports two publish lifecycle events:

  • pre-publish: runs before fxv publish uploads changes. If a pre-publish trigger fails, the publish is canceled, preventing bad revisions from reaching the repository.
  • post-publish: runs after a publish completes successfully. Post-publish failures log a warning and do not roll back the published revision.

Configuration file locations

Define triggers in a TOML file placed at either of the following paths in your workspace:

  1. .fxv/triggers.toml (recommended to avoid cluttering the repository root)
  2. triggers.toml (at the workspace root)

You can track triggers.toml in version control so that team members share consistent verification steps.

Basic configuration

Below is an example configuration that formats files and runs unit tests before publishing:

version = 1

[defaults]
timeout_seconds = 60
abort_on_failure = true

[[pre-publish]]
name = "cargo-fmt"
description = "Check source code formatting"
command = ["cargo", "fmt", "--check"]

[[pre-publish]]
name = "cargo-test"
description = "Run test suite"
command = ["cargo", "test"]
timeout_seconds = 180

[[post-publish]]
name = "notify-slack"
description = "Send team notification"
command = ["python3", "scripts/notify.py"]
abort_on_failure = false

Global defaults

The [defaults] table sets fallback values for triggers in the file:

Setting Type Default Description
timeout_seconds integer 30 Maximum execution time in seconds for a trigger before it is terminated.
abort_on_failure boolean true When true, a non-zero exit code halts the publish lifecycle.

Trigger settings

Each trigger entry accepts the following fields:

Field Type Required Description
name string Yes Unique identifier for the trigger.
description string No Human-readable explanation of what the trigger performs.
command array of strings No Command executable and arguments (for example, ["python3", "lint.py"]).
script string No Path to an executable script (for example, "scripts/check.sh").
platform table No Platform-specific command overrides for windows, linux, and macos.
timeout_seconds integer No Maximum time in seconds before terminating the process. Overrides global default.
abort_on_failure boolean No Whether trigger failure halts execution. Overrides global default.
branches array of strings No List of branch glob patterns. The trigger runs only on matching branches.
file_patterns array of strings No List of file glob patterns. The trigger runs only when changed files match.

A trigger must specify at least one of command, script, or a matching platform override.

Cross-platform commands

Use the platform table when a verification command differs across operating systems:

[[pre-publish]]
name = "lint"
description = "Run platform-specific lint script"

[pre-publish.platform.windows]
command = ["powershell", "-ExecutionPolicy", "Bypass", "-File", "scripts/lint.ps1"]

[pre-publish.platform.linux]
command = ["./scripts/lint.sh"]

[pre-publish.platform.macos]
command = ["./scripts/lint.sh"]

Platform keys accept windows, linux, and macos (or darwin).

Filtering triggers

Triggers can run selectively based on the active branch or the specific files included in the revision.

Filter by branch

Use the branches list to restrict triggers to specific branches. Patterns support standard glob syntax:

[[pre-publish]]
name = "integration-tests"
command = ["npm", "run", "test:integration"]
branches = ["main", "release/*"]

Filter by changed files

Use file_patterns to run triggers only when matching files were modified or added:

[[pre-publish]]
name = "validate-shaders"
command = ["python3", "scripts/validate_shaders.py"]
file_patterns = ["shaders/**", "*.hlsl", "*.glsl"]

If none of the changed files match the patterns, FlexVault skips the trigger.

Environment variables provided to triggers

When executing a trigger, FlexVault injects context variables into the child process environment:

Variable Description
FXV_TRIGGER_EVENT Event name (pre-publish or post-publish).
FXV_TRIGGER_NAME Name of the executing trigger.
FXV_WORKSPACE_ROOT Absolute path to the workspace root directory.
FXV_USER Current logged-in user name.
FXV_BRANCH Name of the active branch.
FXV_COMMIT_MESSAGE Description provided for the publish.
FXV_BASE_REVISION Revision ID the publish is based upon (for example, main.123).
FXV_REVISION Published revision ID (available in post-publish).
FXV_CHANGED_FILES Path to a temporary text file listing every changed file, one path per line.

Your scripts can inspect these variables to tailor their behavior:

Write-Host "Running $env:FXV_TRIGGER_NAME on branch $env:FXV_BRANCH"
if ($env:FXV_CHANGED_FILES) {
    Write-Host "Files changed:"
    Get-Content $env:FXV_CHANGED_FILES
}
#!/usr/bin/env bash
echo "Running ${FXV_TRIGGER_NAME} on branch ${FXV_BRANCH}"
if [ -n "${FXV_CHANGED_FILES}" ]; then
  echo "Files changed:"
  cat "${FXV_CHANGED_FILES}"
fi

Security and trigger approvals

Triggers execute programs with your local user permissions. To guard against running untrusted or modified scripts when collaborating on shared repositories, FlexVault checks trigger approvals before execution.

FlexVault computes a SHA-256 fingerprint for each trigger covering the trigger name, command arguments, and file contents of referenced scripts. When a trigger runs for the first time, FlexVault displays a security prompt in the terminal:

================================================================================
FlexVault Security: Trigger Approval Required
================================================================================
The following client trigger is requesting permission to run on this machine:
  Trigger Name: cargo-test
  Event:        pre-publish
  Command:      cargo test
  Workspace:    /home/user/projects/my-game

Triggers execute arbitrary programs on your machine with your user credentials.
A malicious trigger in a repository can steal credentials, access local data,
or install malware.

Do you trust and approve this trigger to run on this machine? [y/N]:

Once approved, FlexVault records the approval in trusted_triggers.toml. Subsequent runs of the identical trigger execute without prompting.

Tamper detection

If anyone modifies the command, arguments, or referenced script files in triggers.toml, the calculated fingerprint changes. FlexVault detects the discrepancy and warns you before asking for re-approval:

WARNING: This trigger or its script has changed since it was previously approved!

Bypassing or auto-approving triggers

When running fxv publish, you can control trigger execution using command-line flags:

Bypass triggers

To skip running all pre-publish and post-publish triggers for a single publish, pass --no-triggers:

fxv publish -d "Emergency documentation fix" --no-triggers

Auto-approve triggers

In automated environments such as continuous integration workers, interactive prompts cannot be answered. Pass --trust-triggers to approve and run triggers without prompting:

fxv publish -d "Automated build artifact" --trust-triggers --unattended