Skip to main content
In this lesson you’ll create a custom transformer that converts a Jenkins sleep step into an equivalent GitHub Actions step. Instead of leaving the sleep step commented out in the generated workflow, the transformer will produce a step like:
This guide walks through inspecting the Jenkins pipeline JSON, writing a helper transformer to verify the structure, and implementing the final transformer in Ruby. It also shows how to run gh actions-importer with your custom transformer for dry-run and migrate.

Problem overview

When the importer doesn’t have a built-in transformer for an identifier like sleep, it reports:
  • “failed to locate transformer” for sleep
  • the step is left commented out in the generated workflow
Example of a generated workflow where sleep was previously commented out:
We need a transformer that reads the time argument from the Jenkins representation and dynamically generates the proper run: sleep <Ns> step.

How the Jenkins step appears in the importer JSON

The importer receives each pipeline step as a JSON item. For sleep, the JSON looks like:
The numeric sleep value is available at arguments[0].value.value (for example, 5 or 20). Extract that value in your transformer and use it to build the GitHub Actions step.

Transformer basics

  • Transformers are Ruby .rb files that define one or more transform blocks (DSL entries).
  • Each transform block should return a Ruby Hash that maps to the GitHub Actions YAML for a step.
  • Provide transformer files to the CLI with --custom-transformers for audit, dry-run, or migrate.
Example CLI usage:
Use dry-run to validate your transformer output before running a full migration. This prevents creating PRs with incorrect workflows.

Step 1 — Helper transformer to inspect sleep items

Start by creating a small helper transformer that prints each sleep item so you can confirm the JSON structure and the path to the time value. Save as helper-transformer.rb:
Run the importer with:
You should see output like:
This confirms where the time value is located in each sleep item.

Step 2 — Final sleep transformer

Now implement the transformer that extracts the time value and returns a hash representing the corresponding GitHub Actions step. Save it as sleep-transformer.rb:
Notes:
  • Access the time via item["arguments"][0]["value"]["value"].
  • Return a Ruby Hash with string keys; the importer converts it into YAML for the workflow.
Run a dry-run using this transformer:
If successful, the generated workflow will include transformed sleep steps.

Example generated YAML after transformation

Migrating with the transformer

You can supply the transformer to the migrate command. Example:
If the migration succeeds, the importer creates a pull request in the target repository (for example: https://github.com/jenkins-demo-org/demo-repo/pull/3) that contains the converted workflow including the dynamically generated sleep steps. You can review and merge that PR on GitHub.
A screenshot of a GitHub pull request page titled "Convert folder-1/folder-2/pipeline-project-2 to GitHub Actions." The page shows a comment saying the pipeline was migrated from Jenkins and the commit message / merge confirmation form.

Summary checklist

Ensure you access literal values correctly (e.g., item["arguments"][0]["value"]["value"]). Returning an incorrect structure can cause the importer to leave the item untransformed.

Final example transformer (recap)

With this pattern you can implement custom transformers for other Jenkins identifiers (for example: node, environment variables, or custom build steps) that the importer does not convert automatically.

Watch Video