Skip to content

Latest commit

 

History

History
248 lines (193 loc) · 9.52 KB

5-custom-transformers.md

File metadata and controls

248 lines (193 loc) · 9.52 KB

Using custom transformers to customize GitHub Actions Importer's behavior

In this lab you will build upon the dry-run command to override GitHub Actions Importer'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 to set up your GitHub Codespaces environment.
  2. Completed the configure lab.
  3. Completed the dry-run lab.

Perform a dry-run

You will be performing a dry-run command to inspect the workflow that is converted by default. Run the following command within the codespace terminal:

  gh actions-importer dry-run travis-ci --travis-ci-repository "travisci-deploy-example" --output-dir tmp/dry-run

The converted workflow that is generated by the above command can be seen below:

Converted workflow 👇
name: actions-importer-labs/travisci-deploy-example
on:
  push:
    branches:
    - "**/*"
  pull_request:
concurrency:
#   # This item has no matching transformer
#   maximum_number_of_builds: 0
env:
  DB: mysql
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
    - name: checkout
      uses: actions/checkout@v2
    - run: gem install bundler
    - run: bundle install --jobs=3 --retry=3
    - run: rake
    - run: echo 'ready?'
#     # This item has no matching transformer
#     - codedeploy:
#         provider: codedeploy
#         access_key_id: YOUR AWS ACCESS KEY
#         secret_access_key: YOUR AWS SECRET KEY
#         bucket: S3 Bucket
#         key: latest/MyApp.zip
#         application: MyApp
#         deployment_group: MyDeploymentGroup
#       if: "${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}"
    - run: "./after_deploy_1.sh"
    - run: "./after_deploy_2.sh"
    - uses: desiderati/github-action-pushover@v1
      with:
        job-status: "${{ job.status }}"
        pushover-api-token: '12345'
        pushover-user-key: "${{ secrets.PUSHOVER_USER_KEY }}"
      if: "${{ github.event_name != 'pull_request' }}"

Note: You can refer to the previous lab to learn about the fundamentals of the dry-run command.

Custom transformers for an unknown step

The converted workflow above contains an codedeploy step that was not automatically converted. Answer the following questions before writing a custom transformer:

  1. What is the "identifier" of the step to customize?

    • codedeploy
  2. What is the desired Actions syntax to use instead?

    • After some research, you have determined that you can log in to AWS with the aws-actions/configure-aws-credentials@v1 action, and deploy the app to AWS using a run step to replace the functionality of codedeploy:

        - uses: aws-actions/configure-aws-credentials@v1
          with:
            role-to-assume: owner
            role-session-name: GitHub-Action-Role
            aws-region: east-2
        - run: |
            echo "Deploying branch ${{ env.GITHUB_REF }} to ${{ github.event.inputs.environment }}"
            commit_hash=`git rev-parse HEAD`
            aws deploy create-deployment --application-name MyApp --deployment-group-name MyDeploymentGroup --github-location repository=$GITHUB_REPOSITORY,commitId=$commit_hash --ignore-application-stop-failures

Now you can begin to write the custom transformer. Custom 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:

touch transformers.rb && code transformers.rb

Next, you will define a transform method for the codedeploy identifier by adding the following code to transformers.rb:

transform "codedeploy" do |_item|
  [
    {
      "uses" => "aws-actions/configure-aws-credentials@v1",
      "with" => {
        "role-to-assume" => "owner",
        "role-session-name" => "GitHub-Action-Role",
        "aws-region" => "east-2"
      }
    },
    {
      "run" => "echo \"Deploying branch ${{ env.GITHUB_REF }} to ${{ github.event.inputs.environment }}\"\ncommit_hash=`git rev-parse HEAD`\naws deploy create-deployment --application-name MyApp --deployment-group-name MyDeploymentGroup --github-location repository=$GITHUB_REPOSITORY,commitId=$commit_hash --ignore-application-stop-failures\n"
    }
  ]
end

This method can use any valid Ruby syntax and should return a Hash, or an array of Hashes that represent the YAML that should be generated for a given step. GitHub Actions Importer will use this method to convert a step with the provided identifier and will use the item parameter for the original values configured in Travis CI.

Now you 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:

  gh actions-importer dry-run travis-ci --travis-ci-repository "travisci-deploy-example" --output-dir tmp/travis/dry-run --custom-transformers transformers.rb

The converted workflow that is generated by the above command will now use the custom logic for the codedeploy step.

- #     # This item has no matching transformer
- #     - codedeploy:
- #         provider: codedeploy
- #         access_key_id: YOUR AWS ACCESS KEY
- #         secret_access_key: YOUR AWS SECRET KEY
- #         bucket: S3 Bucket
- #         key: latest/MyApp.zip
- #         application: MyApp
- #         deployment_group: MyDeploymentGroup
- #       if: "${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}"
+  - uses: aws-actions/configure-aws-credentials@v1
+    with:
+      role-to-assume: owner
+      role-session-name: GitHub-Action-Role
+      aws-region: east-2
+  - run: |
+      echo "Deploying branch ${{ env.GITHUB_REF }} to ${{ github.event.inputs.environment }}"
+      commit_hash=`git rev-parse HEAD`
+      aws deploy create-deployment --application-name MyApp --deployment-group-name MyDeploymentGroup --github-location repository=$GITHUB_REPOSITORY,commitId=$commit_hash --ignore-application-stop-failures

Note: Certain values such as the application-name are hard-coded, but you can apply these properties programmatically as well by using the item passed into the transform method. If you were unsure what the data structure of item was, you could use the following code in the custom transformer to print item to the console:

transform "codecov_codecov_upload" do |item|
  puts item
end

Custom transformers for environment variables

You can use custom transformers to edit the values of environment variables in converted workflows. In this example, you will update the DB environment variable to be sqlite instead of mysql.

To do this, add the following code to the transformers.rb file.

env "DB", "sqlite"

In this example, the first parameter to the env method is the environment variable name and the second is the updated value.

Now you can perform another dry-run command with the --custom-transformers CLI option. When you open the converted workflow the DB environment variable will be set to sqlite:

 env:
-  DB: "mysql"
+  DB: "sqlite"

Custom transformers for runners

Finally, you can use custom transformers to dictate which runners converted workflows should use. First, answer the following questions:

  1. What is the label of the runner in Travis to update?

    • linux
  2. What is/are the label(s) of the runner(s) in Actions to use instead?

    • new-runner, self-hosted

With these questions answered, you can add the following code to the transformers.rb file:

runner "linux", ["new-runner", "self-hosted"]

In this example, the first parameter to the runner method is the Travis CI label and the second is the GitHub Actions runner labels.

Now you can perform another dry-run command with the --custom-transformers CLI option. When you open the converted workflow, the runs-on statement will use the customized runner labels:

-    runs-on: ubuntu-latest
+    runs-on:
+      - new-runner
+      - self-hosted

At this point, the file contents of transformers.rb should match this:

Custom transformers 👇
transform "codedeploy" do |_item|
  [
      {
      "uses": "aws-actions/configure-aws-credentials@v1",
      "with": {
          "role-to-assume": "owner",
          "role-session-name": "GitHub-Action-Role",
          "aws-region": "east-2"
          }
      },
      {
      "run": "echo \"Deploying branch ${{ env.GITHUB_REF }} to ${{ github.event.inputs.environment }}\"\ncommit_hash=`git rev-parse HEAD`\naws deploy create-deployment --application-name MyApp --deployment-group-name MyDeploymentGroup --github-location repository=$GITHUB_REPOSITORY,commitId=$commit_hash --ignore-application-stop-failures\n"
      }
  ]
end

env "DB", "sqlite"

runner "linux", ["new-runner", "self-hosted"]

That's it. Congratulations, you have overridden GitHub Actions Importer's default behavior by customizing the conversion of:

  • Unknown steps
  • Environment variables
  • Runners

Next lab

Perform a production migration of a Travis CI pipeline