# Using custom transformers to customize Valet's behavior In this lab we will build upon the `dry-run` command to override Valet's default behavior and customize the converted workflow using "custom transformers". Custom transformers can be used to: 1. Convert items that are not automatically converted. 2. Convert items that were automatically converted using different actions. 3. Convert environment variable values differently. 4. Convert references to runners to use a different runner name in Actions. ## Prerequisites 1. Followed the steps [here](./readme.md#configure-your-codespace) to set up your Codespace environment and start you GitLab server. 2. Completed the [configure lab](./1-configure-lab.md#configuring-credentials). 3. Completed the [dry-run lab](./3-dry-run.md). ## Perform a dry-run We will be performing a `dry-run` command to inspect the workflow that is converted by default. Run the following command within the codespace terminal: ```bash gh valet dry-run gitlab --output-dir tmp --namespace valet --project terraform-example ``` The converted workflow that is generated by the above command can be seen below:
Converted workflow 👇 ```yaml name: valet/custom-transformer on: push: workflow_dispatch: concurrency: group: "${{ github.ref }}" cancel-in-progress: true jobs: plan: runs-on: ubuntu-latest timeout-minutes: 60 env: PLAN: plan.cache PLAN_JSON: plan.json steps: - uses: actions/checkout@v2 with: fetch-depth: 20 lfs: true - run: terraform plan -out=$PLAN - run: terraform show --json $PLAN | convert_report > $PLAN_JSON # # 'artifacts.terraform' was not transformed because there is no suitable equivalent in GitHub Actions ```
_Note_: You can refer to the previous [lab](./3-dry-run.md) to learn about the fundamentals of the `dry-run` command. ## Custom transformers for an unknown step The converted workflow above contains an `artifacts.terraform` step was not automatically converted. We will need to answer the following questions before writing a custom transformer: 1. What is the "identifier" of the step to customize? - __artifacts.terraform__ 2. What is the desired Actions syntax to use instead? - After some research, we have determined that the following bash script will provide similar functionality: ```yaml - uses: actions/upload-artifact@v3 with: path: VALUE_FROM_GITLAB ``` Now we can begin to write the custom transformer. Customer transformers use a DSL built on top of Ruby and should be defined in a file with the `.rb` file extension. You can create this file by running the following command in your codespace terminal: ```bash code transformers.rb ``` Next, we will define a `transform` method for the `artifacts.terraform` identifier by adding the following code to `transformers.rb`: ```ruby transform "artifacts.terraform" do |item| { uses: "actions/upload-artifact@v2", with: { path: item } } end ``` This method can use any valid ruby syntax and should return a `Hash` that represents the YAML that should be generated for a given step. Valet will use this method to convert a step with the provided identifier and will use the `item` parameter for the original values configured in GitLab. Now, we can perform another `dry-run` command and use the `--custom-transformers` CLI option to provide this custom transformer. Run the following command within your codespace terminal: ```bash gh valet dry-run gitlab --output-dir tmp --namespace valet --project terraform-example --custom-transformers transformers.rb ``` The converted workflow that is generated by the above command will now use the custom logic for the `artifacts.terraform` step. ```diff - # # 'artifacts.terraform' was not transformed because there is no suitable equivalent in GitHub Actions + uses: actions/upload-artifact@v2 + with: + path: "$PLAN_JSON" ``` _Note_: If you were unsure what the data structure of `item` was then you could use the following code in the custom transformer to print `item` to the console: ```ruby transform "artifacts.terraform" do |item| puts item end ``` ## Custom transformers for environment variables We can also use custom transformers to edit the values of environment variables in converted workflows. In our example, we will be updating the `PLAN_JSON` environment variable to be `custom_plan.json` instead of `plan.json`. To do this, add the following code to the `transformers.rb` file. ```ruby env "PLAN_JSON", "custom_plan.json" ``` In this example, the first parameter to the `env` method is the environment variable name and the second is the updated value. Now, we can perform another `dry-run` command with the `--custom-transformers` CLI option. When you open the converted workflow the `PLAN_JSON` environment variable will be set to `custom_plan.json`: ```diff env: PLAN: plan.cache - PLAN_JSON: plan.json + PLAN_JSON: custom_plan.json ``` At this point of the lab the file contents of `transformers.rb` should match this:
Custom transformers 👇 ```ruby env "PLAN_JSON", "custom_plan.json" transform "artifacts.terraform" do |item| { uses: "actions/upload-artifact@v2", with: { path: item } } end ```
Thats it! Congratulations you have overridden Valet's default behavior by customizing the conversion of: - Unknown steps - Environment variables ## Next lab [Perform a production migration of a GitLab pipeline](5-migrate.md)