In a previous post we looked at how to author an API specification locally and save to Anypoint Design Center, as well as how to manually sync changes made on the Anypoint platform to your local computer.

One of the benefits of maintaining the API specification on your local computer is to be able to save the specification in source control. The Anypoint platform provides a feature called GitHub Synchronization which will automatically sync changes to the specification from Design Center to GitHub and vice versa. This feature can remove the need to use the Anypoint CLI, however it does have the following limitations:

  • The feature only works with GitHub
  • The feature requires administrator access to a GitHub organization and doesn’t work with individual accounts without a GitHub organization
  • The feature saves the specification files to the root of the GitHub project and at the time of writing this post, the directory is not customizable

In this post we will look at an approach for automating the API specification sync between Anypoint Design Center and GitHub using GitHub Actions. While GitHub Actions are specific to GitHub, the techniques can be applied to other build tools that work with a variety of git hosting providers.

Prerequisites

Step 1: Add Secrets to GitHub

In GitHub, navigate to Settings -> Secrets -> Actions. Create the following Repository Secrets

  • ANYPOINT_ORG_ID: paste your Anypoint Organization Id
  • ANYPOINT_CONNECTED_APP_ID: paste your Anypoint connected app Id
  • ANYPOINT_CONNECTED_APP_SECRET: paste your Anypoint connected app secret

Step 2: Sync the OpenAPI Specification from Anypoint Design Center to GitHub

In this scenario, we are using the Anypoint Design Center to edit the OpenAPI spec and we want to bring the updates into GitHub for peer review and approval.

Create a new file in the GitHub project: .github/workflows/oas-retrieve-anypoint.yml

Add the following text to the file

name: OpenAPI Spec Retrieve from Anypoint
on:
  workflow_dispatch:
    inputs:
      git_committer_name:
        description: 'Name to use for the commit'
        required: true
        default: 'GitHub Actions'
        type: string
      git_committer_email:
        description: 'Email to use for the commit'
        required: true
        default: '[email protected]'
        type: string

jobs:
  retrieve-from-anypoint-platform:
    runs-on: ubuntu-latest
    steps:
      # Install nodejs 16
      - name: "Install Node.js"
        uses: actions/setup-node@v3
        with:
          node-version: 16

      # Install Anypoint CLI and relevant plugins
      - name: "Install Anypoint CLI"
        run: | 
          npm install -g anypoint-cli-v4
          anypoint-cli-v4 plugins:install anypoint-cli-account-plugin
          anypoint-cli-v4 plugins:install anypoint-cli-designcenter-plugin
          anypoint-cli-v4 --version
          anypoint-cli-v4 plugins --core

      # Checkout the source code
      - name: "Checkout Source Code"
        uses: actions/checkout@v2
      
      # Save temporary branch name as environment variable
      - name: Set Temporary Branch Name
        id: dateTime
        run:  echo "branch_name=oasSync/anypoint-download-$(date +'%Y-%m-%d-%H-%M-%S')" >> $GITHUB_ENV
      
      # Create new branch starting with 'oasSync/anypoint-download'
      - name: Create Temporary Branch
        run: git checkout -b ${{ env.branch_name }}

      # Download OpenAPI spec
      - name: Download OpenAPI Spec from Anypoint Design Center
        run: anypoint-cli-v4 designcenter:project:download --client_id ${{secrets.ANYPOINT_CONNECTED_APP_ID}} --client_secret ${{secrets.ANYPOINT_CONNECTED_APP_SECRET}} --organization ${{secrets.ANYPOINT_ORG_ID}} pet-owners-api ./docs/oas
      
      # Configure Git for commits
      - name: Initialize mandatory git config
        run: |
         git config user.name ${{inputs.git_committer_name}}
         git config user.email ${{inputs.git_committer_email}}
      
      # Commit changes and push to origin
      - name: Commit Changes
        id: make-commit
        run: |
          git add .
          git commit --message "Adding changes retrieved from Anypoint platform"
          echo "::set-output name=commit::$(git rev-parse HEAD)"
          git push origin ${{ env.branch_name }}
      
      # Create new pull request
      - name: Create Pull Request
        run: echo "pr_number=$(gh pr create -B main -H ${{ env.branch_name }} --title '${{ env.branch_name }} into main' --body 'Created by GitHub Action' | cut -d'/' -f7)" >> $GITHUB_ENV
        env:
          GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
      
      # Merge pull request and delete temporary branch
      - name: Merge Pull Request and Delete Temporary Branch
        run: gh pr merge ${{env.pr_number}} --rebase --delete-branch
        env:
          GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}

Workflow Highlights

  • Runs when triggered by a user in the GitHub web UI and accepts input parameters for the name and email to use for make the git commits.
  • Installs the Anypoint CLI and dependencies in the runner environment.
  • Creates a new branch with a naming convention that starts with oasSync so that it is clear where the change is originating from.
  • Downloads the OpenAPI specification, commits the changes, pushes to the GitHub project and opens a pull request
  • The final step of automatically merging the pull request to the main branch is optional and may not be a good fit with your process if you want to ensure peer review.
Use GitHub Actions to download OpenAPI specification from Anypoint platform
Use GitHub Actions to download OpenAPI specification from Anypoint platform

Step 3: Sync the OpenAPI Specification from GitHub to Anypoint Design Center

In this scenario, we are developing the specification locally and using a traditional process of pushing the changes to the GitHub project and opening a pull request.

Create a new file in the GitHub project: .github/workflows/oas-deploy-main.yml

Add the following text to the file

name: OpenAPI Spec Deploy
on:
  workflow_dispatch:
  pull_request:
    types:
      - closed
    branches:
      - main
    paths:
      - 'docs/oas/**'

jobs:
  deploy-to-anypoint-platform:
    # check if pull request was merged & ignore branches that begin with oasSync/anypoint-download
    if: ${{ github.event.pull_request.merged == true && !startsWith(github.head_ref, 'oasSync/anypoint-download') }}
    runs-on: ubuntu-latest
    steps:
      # Checkout the source code
      - name: "Checkout Source Code"
        uses: actions/checkout@v2
      
      # Install nodejs 16
      - name: "Install Node.js"
        uses: actions/setup-node@v3
        with:
          node-version: 16

      # Install Anypoint CLI and relevant plugins
      - name: "Install Anypoint CLI"
        run: | 
          npm install -g anypoint-cli-v4
          anypoint-cli-v4 plugins:install anypoint-cli-account-plugin
          anypoint-cli-v4 plugins:install anypoint-cli-designcenter-plugin
          anypoint-cli-v4 --version
          anypoint-cli-v4 plugins --core

      # Upload OpenAPI spec
      - name: Upload OpenAPI Spec to Anypoint Design Center
        run: anypoint-cli-v4 designcenter:project:upload --client_id ${{secrets.ANYPOINT_CONNECTED_APP_ID}} --client_secret ${{secrets.ANYPOINT_CONNECTED_APP_SECRET}} --organization ${{secrets.ANYPOINT_ORG_ID}} pet-owners-api ./docs/oas

Workflow Highlights

  • Runs only when a pull request that is targeted to the main branch is closed and merged and when there is a change to the directory where we are storing the specification.
  • Checks that the branch being merged (head) does NOT start with “oasSync/anypoint-download” so that we aren’t firing the workflow to upload changes to Anypoint when the changes originated from the platform; essentially avoiding circular actions.
  • Installs the Anypoint CLI and dependencies in the runner environment.
  • Uploads the changed specification to Anypoint Design Center.
Use GitHub Actions to upload OpenAPI specification to Anypoint platform
Use GitHub Actions to upload OpenAPI specification to Anypoint platform

Summary

By using GitHub Actions we are able to take advantage of all of the API specification development features of the Anypoint platform while ensuring that GitHub remains the source of truth for the specification file.

Resources

Leave a Comment

Your email address will not be published. Required fields are marked *