$npx -y skills add rudderlabs/rudder-agent-skills --skill rudder-transformationsCreates and manages RudderStack transformations and libraries with local testing. Use when creating, editing, or managing RudderStack transformations and transformation libraries using the Rudder CLI
| 1 | # RudderStack Transformations with Rudder CLI |
| 2 | |
| 3 | ## Overview |
| 4 | |
| 5 | RudderStack transformations allow real-time event manipulation using JavaScript or Python. Libraries provide reusable code shared across transformations. Both are managed as code using YAML specs and the Rudder CLI. |
| 6 | |
| 7 | ## Recommended Workflow |
| 8 | |
| 9 | Follow this loop for every change — authoring a new transformation or library, or editing existing code. Testing locally with fixtures is the key step that distinguishes transformations work from other CLI workflows. |
| 10 | |
| 11 | ```dot |
| 12 | digraph transformations_workflow { |
| 13 | rankdir=TB; |
| 14 | "rudder-cli workspace info" [shape=box]; |
| 15 | "Authenticated?" [shape=diamond]; |
| 16 | "rudder-cli auth login" [shape=box]; |
| 17 | "Edit YAML / JS / fixtures" [shape=box]; |
| 18 | "rudder-cli validate -l ./" [shape=box]; |
| 19 | "Validation errors?" [shape=diamond]; |
| 20 | "Fix errors" [shape=box]; |
| 21 | "rudder-cli transformations test --all -l ./" [shape=box]; |
| 22 | "Tests pass?" [shape=diamond]; |
| 23 | "Fix code or expected output" [shape=box]; |
| 24 | "rudder-cli apply --dry-run -l ./" [shape=box]; |
| 25 | "Diff matches intent?" [shape=diamond]; |
| 26 | "Adjust specs" [shape=box]; |
| 27 | "rudder-cli apply -l ./" [shape=box]; |
| 28 | "Done" [shape=doublecircle]; |
| 29 | |
| 30 | "rudder-cli workspace info" -> "Authenticated?"; |
| 31 | "Authenticated?" -> "rudder-cli auth login" [label="no"]; |
| 32 | "rudder-cli auth login" -> "rudder-cli workspace info"; |
| 33 | "Authenticated?" -> "Edit YAML / JS / fixtures" [label="yes"]; |
| 34 | "Edit YAML / JS / fixtures" -> "rudder-cli validate -l ./"; |
| 35 | "rudder-cli validate -l ./" -> "Validation errors?"; |
| 36 | "Validation errors?" -> "Fix errors" [label="yes"]; |
| 37 | "Fix errors" -> "rudder-cli validate -l ./"; |
| 38 | "Validation errors?" -> "rudder-cli transformations test --all -l ./" [label="no"]; |
| 39 | "rudder-cli transformations test --all -l ./" -> "Tests pass?"; |
| 40 | "Tests pass?" -> "Fix code or expected output" [label="no"]; |
| 41 | "Fix code or expected output" -> "rudder-cli validate -l ./"; |
| 42 | "Tests pass?" -> "rudder-cli apply --dry-run -l ./" [label="yes"]; |
| 43 | "rudder-cli apply --dry-run -l ./" -> "Diff matches intent?"; |
| 44 | "Diff matches intent?" -> "Adjust specs" [label="no"]; |
| 45 | "Adjust specs" -> "rudder-cli validate -l ./"; |
| 46 | "Diff matches intent?" -> "rudder-cli apply -l ./" [label="yes"]; |
| 47 | "rudder-cli apply -l ./" -> "Done"; |
| 48 | } |
| 49 | ``` |
| 50 | |
| 51 | **Steps:** |
| 52 | 1. **Verify auth** — `rudder-cli workspace info`; re-auth with `rudder-cli auth login` if needed. |
| 53 | 2. **Validate** — `rudder-cli validate -l ./` catches YAML schema errors, missing files, camelCase `import_name` violations. |
| 54 | 3. **Test locally** — `rudder-cli transformations test --all -l ./` runs each transformation against its `tests/input/*.json` fixtures and diffs against `tests/output/*.json`. Use `--modified` for faster iteration or pass a specific transformation id. |
| 55 | 4. **Dry run** — `rudder-cli apply --dry-run -l ./` shows the diff that would be applied. Check for unexpected deletions. |
| 56 | 5. **Apply** — `rudder-cli apply -l ./` publishes libraries and transformations atomically (correct order handled by the CLI). |
| 57 | |
| 58 | For the broader validate → apply cycle that applies to all CLI-managed resources, see the `rudder-cli-workflow` skill. This skill specializes it with the local-test step. |
| 59 | |
| 60 | ### Worked example |
| 61 | |
| 62 | A complete end-to-end project — library, transformation, fixtures, and README — lives at `examples/transformations-workflow/` in this repo. It includes a ported Base64 library (`base64-lib`), a sample transformation that uses it, and input/output test fixtures. Use it as a scaffold for new transformations or as a reference for `tests/` structure. |
| 63 | |
| 64 | ## Directory Structure |
| 65 | |
| 66 | ``` |
| 67 | transformations/ |
| 68 | my-transformation.yaml # Transformation spec |
| 69 | my-library.yaml # Library spec |
| 70 | javascript/ |
| 71 | my-transformation.js # JavaScript code |
| 72 | my-library.js # Library code |
| 73 | python/ |
| 74 | my-transformation.py # Python code |
| 75 | my-library.py # Library code |
| 76 | tests/ |
| 77 | input/ |
| 78 | event1.json # Test input events |
| 79 | output/ |
| 80 | event1.json # Expected outputs |
| 81 | ``` |
| 82 | |
| 83 | ## YAML Schemas |
| 84 | |
| 85 | ### Transformation Spec |
| 86 | |
| 87 | ```yaml |
| 88 | version: "rudder/v1" |
| 89 | kind: "transformation" |
| 90 | metadata: |
| 91 | name: "transformations" |
| 92 | # Optional: import section for linking to existing workspace resources |
| 93 | import: |
| 94 | workspaces: |
| 95 | - workspace_id: "your-workspace-id" |
| 96 | resources: |
| 97 | - remote_id: "existing-transformation-id" |
| 98 | urn: "transformation:my-transformation" |
| 99 | spec: |
| 100 | id: "my-transformation" # Unique identifier (used as external ID) |
| 101 | name: "My Transformation" # Human-readable name |
| 102 | description: "Description" # Option |