From fa7b9a7ae0e3a65a53d8b62a7b4288678684b3dc Mon Sep 17 00:00:00 2001 From: j-dunham Date: Fri, 8 Sep 2023 12:56:19 -0400 Subject: [PATCH] Add custom transformer lab --- bitbucket/5-custom-transformers.md | 214 +++++++++++++++++- .../bootstrap/source_files/node_deploy.yml | 29 +++ 2 files changed, 242 insertions(+), 1 deletion(-) create mode 100644 bitbucket/bootstrap/source_files/node_deploy.yml diff --git a/bitbucket/5-custom-transformers.md b/bitbucket/5-custom-transformers.md index 842c58a..efc4943 100644 --- a/bitbucket/5-custom-transformers.md +++ b/bitbucket/5-custom-transformers.md @@ -1 +1,213 @@ -# Using custom transformers to customize GitHub Actions Importer's behavior +# Use 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 GitHub Actions. + +## Prerequisites + +1. Followed the steps [here](./readme.md#configure-your-codespace) to set up your GitHub Codespaces environment. +2. Completed the [configure lab](./1-configure.md#configuring-credentials). +3. Completed the [dry-run lab](./4-dry-run.md). + +## 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: + +```bash +gh actions-importer dry-run bitbucket --output-dir tmp/dry-run --workspace actions-importer --repository node-deploy --source-file-path ./bitbucket/bootstrap/source_files/node_deploy.yml +``` + +The converted workflow that is generated by the above command can be seen below: + +
+ Converted workflow 👇 + +```yaml +name: default +on: + push: +jobs: + step_job_1: + runs-on: ubuntu-latest + container: + image: node:16 + steps: + - uses: actions/checkout@v3.6.0 + - name: Build and Test + run: |- + npm install + npm test + apt update && apt install zip + zip -r app-${{ github.run_number }}.zip . -x *.git* bitbucket-pipelines.yml + - name: Code linting + run: |- + npm install eslint + npx eslint . +# # This item has no matching transformer +# - identifier: atlassian/unknown-azure-deploy:1.1.0 +# name: Deploy to Production +# variables: +# AZURE_APP_ID: "$AZURE_APP_ID" +# AZURE_PASSWORD: "$AZURE_PASSWORD" +# AZURE_TENANT_ID: "$AZURE_TENANT_ID" +# AZURE_RESOURCE_GROUP: "$AZURE_RESOURCE_GROUP" +# AZURE_APP_NAME: my-site +# ZIP_FILE: my-package.zip + - uses: actions/upload-artifact@v3.1.1 + with: + name: step_job_1 + path: "*.zip" +``` + +
+ +_Note_: You can refer to the previous [lab](./4-dry-run.md) to learn about the fundamentals of the `dry-run` command. + +## Custom transformers for an unknown step + +The converted workflow above contains a `atlassian/unknown-azure-deploy` step that was not automatically converted. Let's write a custom transformer to handle this unknown pipe! + +1) What is the "identifier" of the step to customize? This should be the identifier from the comment in the workflow without the version, or in other words the name of the pipe. + - __atlassian/unknown-azure-deploy__ + +2) What is the desired Actions syntax to use instead? + - After some research, you have determined that the [Azure Web App](https://github.com/marketplace/actions/azure-webapp) and [Azure Login](https://github.com/marketplace/actions/azure-login) actions in the marketplace will provide similar functionality: + + ```yaml + - uses: azure/login@v1.4.6 + with: + creds: "${{ secrets.AZURE_CREDENTIALS }}" + - uses: azure/webapps-deploy@v2.2.5 + with: + app-name: my-site + package: my-package.zip + resource-group-name: "$AZURE_RESOURCE_GROUP" + ``` + + 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: + + ```bash + touch transformers.rb && code transformers.rb + ``` + + Next, you will define a `transform` method for the `atlassian/unknown-azure-deploy` identifier by adding the following code to `transformers.rb`: + + ```ruby + transform "atlassian/unknown-azure-deploy" do |item| + [ + { + "uses" => "azure/login@v1.4.6", + "with" => { + "creds" => "${{ secrets.AZURE_CREDENTIALS }}" + } + }, + { + "name" => "Upload coverage to Codecov", + "uses" => "azure/webapps-deploy@v2.2.5", + "with" => { + "app-name" => "my-site", + "package" => item["variables"]["ZIP_FILE"], + "resource-group-name" => item["variables"]["AZURE_RESOURCE_GROUP"] + } + } + ] + end + ``` + +This method can use any valid Ruby syntax and should return a `Hash` or `Array` that represents 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 Bitbucket. The structure of the item can be viewed by looking at the commented out step for the identifier in the workflow. + +```yaml +identifier: atlassian/unknown-azure-deploy:1.1.0 +name: Deploy to Production +variables: + AZURE_APP_ID: "$AZURE_APP_ID" + AZURE_PASSWORD: "$AZURE_PASSWORD" + AZURE_TENANT_ID: "$AZURE_TENANT_ID" + AZURE_RESOURCE_GROUP: "$AZURE_RESOURCE_GROUP" + AZURE_APP_NAME: my-site + ZIP_FILE: my-package.zip +``` + +To access the values of the zip file and resource group information in the transformer, we are using `item["variables"]["ZIP_FILE"]` and `item["variables"]["AZURE_RESOURCE_GROUP"]`. + +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: + +```bash +gh actions-importer dry-run bitbucket --output-dir tmp/dry-run --workspace actions-importer --repository node-deploy --source-file-path ./bitbucket/bootstrap/source_files/node_deploy.yml --custom-transformers transformers.rb +``` + +The converted workflow that is generated by the above command will now use the custom logic for the `atlassian/unknown-azure-deplo` step. + +## Custom transformers for runners +Next, we will use a custom transformers to dictate which runners the converted workflows should use. To do this, answer the following questions: + +1. What is the label of the runner in Bitbucket to change? + - __my.custom.label__ + +2. What is the label of the runner in GitHub Actions to use instead? + - __some-other-runner__ + +With these questions answered, you can add the following code to the `transformers.rb` file: + +```ruby +runner "my.custom.label", "some.other.label" +``` + +In this example, the first parameter to the `runner` method is the runner label in Bitbucket and the second is the new runner label to use in GitHub Actions. + +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 label: + +```bash +gh actions-importer dry-run bitbucket --output-dir tmp/dry-run --workspace actions-importer --repository python --source-file-path ./bitbucket/bootstrap/source_files/python.yml --custom-transformers transformers.rb +``` +> Note: we are using the python pipeline because that uses the `runs-on` with the target label. + +```diff +runs-on: +- - my.custom.label ++ - some.other.label +``` + +At this point the file contents of `transformers.rb` should match this: + +
+ Custom transformers 👇 + +```ruby +runner "my.custom.label", "some-other-runner" + +transform "atlassian/unknown-azure-deploy" do |item| + variables = item["variables"] + [ + { + "uses" => "azure/login@v1.4.6", + "with" => { + "creds" => "${{ secrets.AZURE_CREDENTIALS }}" + } + }, + { + "name" => "Upload coverage to Codecov", + "uses" => "azure/webapps-deploy@v2.2.5", + "with" => { + "app-name" => "my-site", + "package" => variables["ZIP_FILE"], + "resource-group-name" => variables["AZURE_RESOURCE_GROUP"] + } + } + ] +end +``` + +
+ +That's it. Congratulations, you have overridden GitHub Actions Importer's default behavior by customizing the conversion of: + +- Unknown steps +- Runners +## Next lab + +[Perform a production migration of a Bitbucket pipeline](6-migrate.md) diff --git a/bitbucket/bootstrap/source_files/node_deploy.yml b/bitbucket/bootstrap/source_files/node_deploy.yml new file mode 100644 index 0000000..27613b2 --- /dev/null +++ b/bitbucket/bootstrap/source_files/node_deploy.yml @@ -0,0 +1,29 @@ +image: node:16 + +pipelines: + default: + - step: + name: Build and Test + script: + - npm install + - npm test + - apt update && apt install zip + - zip -r app-$BITBUCKET_BUILD_NUMBER.zip . -x *.git* bitbucket-pipelines.yml + artifacts: + - "*.zip" + - step: + name: Code linting + script: + - npm install eslint + - npx eslint . + - step: + name: Deploy to Production + script: + - pipe: atlassian/unknown-azure-deploy:1.1.0 + variables: + AZURE_APP_ID: $AZURE_APP_ID + AZURE_PASSWORD: $AZURE_PASSWORD + AZURE_TENANT_ID: $AZURE_TENANT_ID + AZURE_RESOURCE_GROUP: $AZURE_RESOURCE_GROUP + AZURE_APP_NAME: "my-site" + ZIP_FILE: "my-package.zip" \ No newline at end of file