{"meta":{"title":"Extending GitHub Actions Importer with custom transformers","intro":"GitHub Actions Importer offers the ability to extend its built-in mapping.","product":"GitHub Actions","breadcrumbs":[{"href":"/en/actions","title":"GitHub Actions"},{"href":"/en/actions/reference","title":"Reference"},{"href":"/en/actions/reference/github-actions-importer","title":"GitHub Actions Importer"},{"href":"/en/actions/reference/github-actions-importer/custom-transformers","title":"Custom transformers"}],"documentType":"article"},"body":"# Extending GitHub Actions Importer with custom transformers\n\nGitHub Actions Importer offers the ability to extend its built-in mapping.\n\n## About custom transformers\n\nGitHub Actions Importer offers the ability to extend its built-in mapping by creating custom transformers. Custom transformers can be used to:\n\n* Convert items that GitHub Actions Importer does not automatically convert, or modify how items are converted. For more information, see [Creating custom transformers for items](#creating-custom-transformers-for-items).\n* Convert references to runners to use different runner labels. For more information, see [Creating custom transformers for runners](#creating-custom-transformers-for-runners).\n* Convert environment variable values from your existing pipelines to GitHub Actions workflows. For more information, see [Creating custom transformers for environment variables](#creating-custom-transformers-for-environment-variables).\n\n## Using custom transformers with GitHub Actions Importer\n\nA custom transformer contains mapping logic that GitHub Actions Importer can use to transform your plugins, tasks, runner labels, or environment variables to work with GitHub Actions. Custom transformers are written with a domain-specific language (DSL) built on top of Ruby, and are defined within a file with the `.rb` file extension.\n\nYou can use the `--custom-transformers` CLI option to specify which custom transformer files to use with the `audit`, `dry-run`, and `migrate` commands.\n\nFor example, if custom transformers are defined in a file named `transformers.rb`, you can use the following command to use them with GitHub Actions Importer:\n\n```shell\ngh actions-importer ... --custom-transformers transformers.rb\n```\n\nAlternatively, you can use the glob pattern syntax to specify multiple custom transformer files. For example, if multiple custom transformer files are within a directory named `transformers`, you can provide them all to GitHub Actions Importer with the following command:\n\n```shell\ngh actions-importer ... --custom-transformers transformers/*.rb\n```\n\n> \\[!NOTE]\n> When you use custom transformers, the custom transformer files must reside in the same directory, or in subdirectories, from where the `gh actions-importer` command is run.\n\n## Creating custom transformers for items\n\nYou can create custom transformers that GitHub Actions Importer will use when converting existing build steps or triggers to their equivalent in GitHub Actions. This is especially useful when:\n\n* GitHub Actions Importer doesn't automatically convert an item.\n* You want to change how an item is converted by GitHub Actions Importer.\n* Your existing pipelines use custom or proprietary extensions, such as shared libraries in Jenkins, and you need to define how these steps should function in GitHub Actions.\n\nGitHub Actions Importer uses custom transformers that are defined using a DSL built on top of Ruby. In order to create custom transformers for build steps and triggers:\n\n* Each custom transformer file must contain at least one `transform` method.\n* Each `transform` method must return a `Hash`, an array of `Hash`'s, or `nil`. This returned value will correspond to an action defined in YAML. For more information about actions, see [Understanding GitHub Actions](/en/actions/learn-github-actions/understanding-github-actions).\n\n### Example custom transformer for a build step\n\nThe following example converts a build step that uses the \"buildJavaScriptApp\" identifier to run various `npm` commands:\n\n```ruby copy\ntransform \"buildJavaScriptApp\" do |item|\n  command = [\"build\", \"package\", \"deploy\"].map do |script|\n    \"npm run #{script}\"\n  end\n\n  {\n    name: \"build javascript app\",\n    run: command.join(\"\\n\")\n  }\nend\n```\n\nThe above example results in the following GitHub Actions workflow step. It is comprised of converted build steps that had a `buildJavaScriptApp` identifier:\n\n```yaml\n- name: build javascript app\n  run: |\n    npm run build\n    npm run package\n    npm run deploy\n```\n\nThe `transform` method uses the identifier of the build step from your source CI/CD instance in an argument. In this example, the identifier is `buildJavaScriptLibrary`. You can also use comma-separated values to pass multiple identifiers to the `transform` method. For example, `transform \"buildJavaScriptApp\", \"buildTypeScriptApp\" { |item| ... }`.\n\n> \\[!NOTE]\n> The data structure of `item` will be different depending on the CI/CD platform and the type of item being converted.\n\n## Creating custom transformers for runners\n\nYou can customize the mapping between runners in your source CI/CD instance and their equivalent GitHub Actions runners.\n\nGitHub Actions Importer uses custom transformers that are defined using a DSL built on top of Ruby. To create custom transformers for runners:\n\n* The custom transformer file must have at least one `runner` method.\n* The `runner` method accepts two parameters. The first parameter is the source CI/CD instance's runner label, and the second parameter is the corresponding GitHub Actions runner label. For more information on GitHub Actions runners, see [GitHub-hosted runners](/en/actions/using-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources).\n\n### Example custom transformers for runners\n\nThe following example shows a `runner` method that converts one runner label to one GitHub Actions runner label in the resulting workflow.\n\n```ruby copy\nrunner \"linux\", \"ubuntu-latest\"\n```\n\nYou can also use the `runner` method to convert one runner label to multiple GitHub Actions runner labels in the resulting workflow.\n\n```ruby copy\nrunner \"big-agent\", [\"self-hosted\", \"xl\", \"linux\"]\n```\n\nGitHub Actions Importer attempts to map the runner label as best it can. In cases where it cannot do this, the `ubuntu-latest` runner label is used as a default. You can use a special keyword with the `runner` method to control this default value. For example, the following custom transformer instructs GitHub Actions Importer to use `macos-latest` as the default runner instead of `ubuntu-latest`.\n\n```ruby copy\nrunner :default, \"macos-latest\"\n```\n\n## Creating custom transformers for environment variables\n\nYou can customize the mapping between environment variables in your source CI/CD pipelines to their values in GitHub Actions.\n\nGitHub Actions Importer uses custom transformers that are defined using a DSL built on top of Ruby. To create custom transformers for environment variables:\n\n* The custom transformer file must have at least one `env` method.\n* The `env` method accepts two parameters. The first parameter is the name of the environment variable in the original pipeline, and the second parameter is the updated value for the environment variable for GitHub Actions. For more information about GitHub Actions environment variables, see [Store information in variables](/en/actions/learn-github-actions/variables).\n\n### Example custom transformers for environment variables\n\nThere are several ways you can set up custom transformers to map your environment variables.\n\n* The following example sets the value of any existing environment variables named `OCTO`, to `CAT` when transforming a pipeline.\n\n  ```ruby copy\n  env \"OCTO\", \"CAT\"\n  ```\n\n  You can also remove all instances of a specific environment variable so they are not transformed to an GitHub Actions workflow. The following example removes all environment variables with the name `MONA_LISA`.\n\n  ```ruby copy\n  env \"MONA_LISA\", nil\n  ```\n\n* You can also map your existing environment variables to secrets. For example, the following `env` method maps an environment variable named `MONALISA` to a secret named `OCTOCAT`.\n\n  ```ruby copy\n  env \"MONALISA\", secret(\"OCTOCAT\")\n  ```\n\n  This will set up a reference to a secret named `OCTOCAT` in the transformed workflow. For the secret to work, you will need to create the secret in your GitHub repository. For more information, see [Using secrets in GitHub Actions](/en/actions/security-guides/using-secrets-in-github-actions#creating-secrets-for-a-repository).\n\n* You can also use regular expressions to update the values of multiple environment variables at once. For example, the following custom transformer removes all environment variables from the converted workflow:\n\n  ```ruby copy\n  env /.*/, nil\n  ```\n\n  The following example uses a regular expression match group to transform environment variable values to dynamically generated secrets.\n\n  ```ruby copy\n  env /^(.+)_SSH_KEY/, secret(\"%s_SSH_KEY)\n  ```\n\n  > \\[!NOTE]\n  > The order in which `env` methods are defined matters when using regular expressions. The first `env` transformer that matches an environment variable name takes precedence over subsequent `env` methods. You should define your most specific environment variable transformers first.\n\n## Legal notice\n\nPortions have been adapted from <https://github.com/github/gh-actions-importer/> under the MIT license:\n\n```text\nMIT License\n\nCopyright (c) 2022 GitHub\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n```"}