A GitHub Action for exporting Figma assets using ExFig CLI. Export colors, icons, images, and typography from Figma to your codebase with built-in caching.
- uses: DesignPipe/exfig-action@v2
with:
figma_token: ${{ secrets.FIGMA_TOKEN }}
command: icons
cache: true| Input | Description | Required | Default |
|---|---|---|---|
figma_token |
Figma Personal Access Token | Yes | - |
command |
ExFig command: colors, icons, images, typography, batch, fetch, download |
Yes | - |
config |
Path to exfig.pkl config file (comma-separated for batch) | No | exfig.pkl |
filter |
Filter pattern for assets (e.g., icon/*) |
No | - |
version |
ExFig version to use | No | latest |
cache |
Enable caching for incremental exports | No | false |
cache_path |
Path to cache file | No | .exfig-cache.json |
cache_key_prefix |
Prefix for cache key | No | exfig-cache |
granular_cache |
Enable experimental granular caching | No | false |
concurrent_downloads |
CDN download parallelism (number of concurrent downloads) | No | - |
timeout |
API timeout in seconds | No | - |
fail_fast |
Stop on first batch error | No | false |
report |
Path to write JSON report file (batch mode) | No | - |
rate_limit |
Figma API rate limit (requests/second) | No | 10 |
max_retries |
Maximum retries for failed API requests | No | 3 |
output_dir |
Output directory for exported assets | No | - |
verbose |
Enable verbose logging | No | false |
extra_args |
Additional CLI arguments to pass to ExFig (e.g., --force --dry-run) |
No | - |
slack_webhook |
Slack Incoming Webhook URL for notifications | No | - |
slack_mention |
User/group to mention on failure (plain ID: U123, S456; or @channel) |
No | - |
slack_templates |
Path to custom Slack templates directory (overrides defaults) | No | - |
| Output | Description |
|---|---|
assets_exported |
Number of assets exported |
changed_files |
List of changed files (newline-separated) |
cache_hit |
Whether cache was restored |
exit_code |
ExFig command exit code (0 = success) |
failed_count |
Number of failed configs in batch mode |
duration |
Execution duration (e.g., "5s") |
config_summary |
Summary of config files processed (batch command) |
validated_count |
Number of configs validated from cache (no changes) |
exported_configs |
Number of configs that exported new assets |
error_category |
Error category code (RATE_LIMIT, TIMEOUT, AUTH, etc.) |
error_message |
First error message from failed config (truncated) |
report_json |
Raw JSON report content (batch mode only) |
Export icons with caching:
name: Export Figma Icons
on:
workflow_dispatch:
schedule:
- cron: '0 0 * * *' # Daily
jobs:
export:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: DesignPipe/exfig-action@v2
with:
figma_token: ${{ secrets.FIGMA_TOKEN }}
command: icons
cache: true
- name: Commit changes
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add -A
git diff --staged --quiet || git commit -m "Update icons from Figma"
git pushjobs:
export:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Export colors
uses: DesignPipe/exfig-action@v2
with:
figma_token: ${{ secrets.FIGMA_TOKEN }}
command: colors
cache: true
cache_key_prefix: exfig-colors
- name: Export icons
uses: DesignPipe/exfig-action@v2
with:
figma_token: ${{ secrets.FIGMA_TOKEN }}
command: icons
cache: true
cache_key_prefix: exfig-icons
- name: Export typography
uses: DesignPipe/exfig-action@v2
with:
figma_token: ${{ secrets.FIGMA_TOKEN }}
command: typography
cache: true
cache_key_prefix: exfig-typography- uses: DesignPipe/exfig-action@v2
with:
figma_token: ${{ secrets.FIGMA_TOKEN }}
command: icons
filter: 'navigation/*'
cache: true- uses: DesignPipe/exfig-action@v2
with:
figma_token: ${{ secrets.FIGMA_TOKEN }}
command: icons
version: 'v1.2.0'Pass additional flags directly to ExFig CLI:
- uses: DesignPipe/exfig-action@v2
with:
figma_token: ${{ secrets.FIGMA_TOKEN }}
command: icons
extra_args: '--force'Export multiple configs with a structured JSON report:
- uses: DesignPipe/exfig-action@v2
id: exfig
with:
figma_token: ${{ secrets.FIGMA_TOKEN }}
command: batch
config: 'exfig-colors.pkl, exfig-icons.pkl'
cache: true
fail_fast: true
report: 'exfig-report.json'
- name: Use report
if: always()
run: echo '${{ steps.exfig.outputs.report_json }}' | jq .jobs:
export:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- uses: DesignPipe/exfig-action@v2
with:
figma_token: ${{ secrets.FIGMA_TOKEN }}
command: iconsThe action supports two levels of caching:
The ExFig binary is automatically cached per OS and version to avoid re-downloading on every run.
When cache: true, the action uses ExFig's built-in cache to enable incremental exports. Only changed assets are re-exported, significantly reducing Figma API calls and export time.
- uses: DesignPipe/exfig-action@v2
with:
figma_token: ${{ secrets.FIGMA_TOKEN }}
command: icons
cache: true
cache_path: '.exfig-cache.json' # Default
cache_key_prefix: 'exfig-cache' # DefaultThe cache is saved even on failure to support checkpoint resume for large exports.
For better performance with large asset libraries:
- uses: DesignPipe/exfig-action@v2
with:
figma_token: ${{ secrets.FIGMA_TOKEN }}
command: icons
cache: true
granular_cache: true- Ubuntu (Linux x64)
- macOS (Universal binary: arm64 + x86_64)
Create an exfig.pkl in your repository root:
amends "package://github.com/DesignPipe/exfig/releases/download/v2.0.0/exfig@2.0.0#/ExFig.pkl"
figma {
fileId = "YOUR_FIGMA_FILE_KEY"
}
icons {
new {
figma { page = "Icons" }
iOS { output = "Sources/Assets.xcassets/Icons" }
}
}
colors {
new {
figma { page = "Colors" }
iOS { output = "Sources/Assets.xcassets/Colors" }
}
}See ExFig documentation for full configuration options.
Send notifications to Slack when exports complete or fail:
- uses: DesignPipe/exfig-action@v2
with:
figma_token: ${{ secrets.FIGMA_TOKEN }}
command: batch
config: 'exfig/colors.pkl, exfig/icons.pkl'
slack_webhook: ${{ secrets.SLACK_WEBHOOK }}
slack_mention: 'U123456' # Mention on failure only (auto-formatted)| Status | Icon | Description |
|---|---|---|
| Success | β | Export completed successfully |
| Failure | β | Export failed (mentions user if configured) |
| Cache hit | π¨ | No changes detected, all assets up to date |
- Command: Shows command and config files (e.g.,
batch (colors.pkl, icons.pkl)) - Assets: Number of exported assets
- Duration: Execution time
- Repository: Link to GitHub Actions run
Override default notification templates with your own Slack Block Kit JSON:
- uses: DesignPipe/exfig-action@v2
with:
figma_token: ${{ secrets.FIGMA_TOKEN }}
command: icons
slack_webhook: ${{ secrets.SLACK_WEBHOOK }}
slack_templates: '.github/exfig-templates'Create only the templates you want to override:
.github/exfig-templates/
βββ success.json # Override success message
βββ failure.json # Override failure message
βββ cache-hit.json # Override cache hit message
Templates support these placeholders:
| Variable | Description | Example |
|---|---|---|
{{ICON}} |
Status icon | β , β, π¨ |
{{TITLE}} |
Main title | "Export completed" |
{{COMMAND}} |
Command with configs | "batch (colors.pkl)" |
{{ASSETS}} |
Assets count | "140" |
{{DURATION}} |
Execution time | "5s" |
{{REPO}} |
Repository name | "org/repo" |
{{RUN_URL}} |
Actions run URL | "https://github.com/..." |
{{SUBTITLE}} |
Context text | "2 config(s) failed" |
{{COLOR}} |
Attachment color | "#36a64f" |
Error: Request failed with status 403
Ensure your FIGMA_TOKEN secret has read access to the Figma file.
Error: Rate limit exceeded
Reduce rate_limit input or wait before retrying:
- uses: DesignPipe/exfig-action@v2
with:
figma_token: ${{ secrets.FIGMA_TOKEN }}
command: icons
rate_limit: 5
max_retries: 6Ensure caching is enabled and the cache path is accessible:
- uses: DesignPipe/exfig-action@v2
with:
figma_token: ${{ secrets.FIGMA_TOKEN }}
command: icons
cache: true
verbose: true # Enable verbose logging to debugMIT License - see LICENSE for details.