Skip to content

Github Actions

This is an example of how to integrate Komposer in Github Actions.

The configuration is divided in three blocks:

  • building and pushing the Docker image
  • cleaning Komposer's Kubernetes resources previously deployed
  • deploy the new Kubernetes resource generated from Komposer

The example includes also some preliminary steps to setup Pytohn and Google Cloud SDK, they are there for completness but not mandatory to deploy the resources generated by Komposer.

name: "Komposer deploy example"

env:
  SERVICE_NAME: "service-example"
  GCLOUD_SDK_VERSION: "386.0.0"
  PYTHON_VERSION: "3.10"
  POETRY_VERSION: "1.1.15"
  GKE_PROJECT_ID: "my-project-id"
  GKE_CLUSTER: "my-cluster-name"

on:
  pull_request:

jobs:
  build-push:
    runs-on: ubuntu
    steps:
      - uses: actions/checkout@v3
      - name: Build and push
        run: |
          sha=${GITHUB_SHA::7}
          image=${{ env.SERVICE_NAME }}:${sha}

          docker build -t "$image" .
          docker push "$image"

  clean-dev-resources:
    steps:
      - uses: actions/checkout@v3
      - name: Authenticate to Google Cloud
        uses: google-github-actions/auth@v0.8.0
        with:
          credentials_json: ${{ secrets.GKE_JSON_KEY }}
      - name: Set up Cloud SDK
        uses: google-github-actions/setup-gcloud@v0.6.0
        with:
          version: ${{ env.GCLOUD_SDK_VERSION }}
          project_id: ${{ env.GKE_PROJECT_ID }}
      - name: Set cluster credentials
        env:
          PROJECT_ID: ${{ env.GKE_PROJECT_ID }}
          GKE_CLUSTER: ${{ env.GKE_CLUSTER }}
        run: |
          gcloud container clusters get-credentials \
              --project $GKE_PROJECT_ID \
              $GKE_CLUSTER
      - name: Clean up dev resources
        run: |
          # Set variables
          export branch_name=$( echo ${{ github.ref_name }} | tr '[:upper:]' '[:lower:]' | tr -c '[:alnum:]' '-' | sed 's/.$//' )
          export repository_name=$( echo ${{ github.repository }} | cut -d'/' -f2)

          # Delete resources
          kubectl delete job -l repository=$repository_name,branch=$branch_name
          kubectl delete deployment -l repository=$repository_name,branch=$branch_name
          kubectl delete service -l repository=$repository_name,branch=$branch_name
          kubectl delete ingress -l repository=$repository_name,branch=$branch_name
          kubectl delete configmap -l repository=$repository_name,branch=$branch_name

  deploy-dev:
    needs:
      - clean-dev-resources
      - build-push
    steps:
      - uses: actions/checkout@v3
      - name: Authenticate to Google Cloud
        uses: google-github-actions/auth@v0.8.0
        with:
          credentials_json: ${{ secrets.GKE_JSON_KEY }}
      - name: Set up Cloud SDK
        uses: google-github-actions/setup-gcloud@v0.6.0
        with:
          version: ${{ env.GCLOUD_SDK_VERSION }}
          project_id: ${{ env.GKE_PROJECT_ID }}
      - name: Set cluster credentials
        env:
          PROJECT_ID: ${{ env.GKE_PROJECT_ID }}
          GKE_CLUSTER: ${{ env.GKE_CLUSTER }}
        run: |
          gcloud container clusters get-credentials \
              --project $GKE_PROJECT_ID \
              $GKE_CLUSTER
      - uses: actions/setup-python@v3
        with:
          python-version: ${{ env.PYTHON_VERSION }}
      - name: Cache multiple Pips
        uses: actions/cache@v3
        with:
          path: |
            ~/.cache/pip
          key: ${{ runner.os }}-${{ env.PYTHON_VERSION }}-${{ hashFiles('**/poetry.lock') }}
      - name: install dependencies
        run: |
          pip install 'poetry== ${{ env.POETRY_VERSION }}'
          poetry install
      - name: Generate dev manifest
        run: |
          # Set variables
          export branch_name=$( echo ${{ github.ref_name }} | tr '[:upper:]' '[:lower:]' | tr -c '[:alnum:]' '-' | sed 's/.$//' )
          export repository_name=$( echo ${{ github.repository }} | cut -d'/' -f2)

          # Generate dev manifest
          poetry run komposer \
            --repository-name $repository_name \
            --branch-name $branch_name \
          > dev-deploy-template.yaml
      - name: Deploy dev manifest
        run: |
          # Set variables
          export branch_name=$( echo ${{ github.ref_name }} | tr '[:upper:]' '[:lower:]' | tr -c '[:alnum:]' '-' | sed 's/.$//' )
          export repository_name=$( echo ${{ github.repository }} | cut -d'/' -f2)
          export sha=${GITHUB_SHA::7}
          export image="${{ env.SERVICE_NAME }}:${sha}"

          # Render the manifest
          cat dev-deploy-template.yaml | envsubst '${image}' > dev-deploy.yaml

          # Deploy service
          cat dev-deploy.yaml | kubectl apply -l pre-deploy!=yes -f -

          for i in $(kubectl get deployments -l repository=$repository_name,branch=$branch_name -o name)
          do
            kubectl rollout status "$i" --timeout=300s
          done

Note

The branch name is a lowercase kebab version of the Git's branch name with any slash converted into dashes; this makes the branch name compatible with Kubernetes naming rules .

Building and pushing the image

The first step is to build and push the docker image of your service into the Docker hub:

name: "Komposer deploy example"

env:
  SERVICE_NAME: "service-example"
  GCLOUD_SDK_VERSION: "386.0.0"
  PYTHON_VERSION: "3.10"
  POETRY_VERSION: "1.1.15"
  GKE_PROJECT_ID: "my-project-id"
  GKE_CLUSTER: "my-cluster-name"

on:
  pull_request:

jobs:
  build-push:
    runs-on: ubuntu
    steps:
      - uses: actions/checkout@v3
      - name: Build and push
        run: |
          sha=${GITHUB_SHA::7}
          image=${{ env.SERVICE_NAME }}:${sha}

          docker build -t "$image" .
          docker push "$image"

  clean-dev-resources:
    steps:
      - uses: actions/checkout@v3
      - name: Authenticate to Google Cloud
        uses: google-github-actions/auth@v0.8.0
        with:
          credentials_json: ${{ secrets.GKE_JSON_KEY }}
      - name: Set up Cloud SDK
        uses: google-github-actions/setup-gcloud@v0.6.0
        with:
          version: ${{ env.GCLOUD_SDK_VERSION }}
          project_id: ${{ env.GKE_PROJECT_ID }}
      - name: Set cluster credentials
        env:
          PROJECT_ID: ${{ env.GKE_PROJECT_ID }}
          GKE_CLUSTER: ${{ env.GKE_CLUSTER }}
        run: |
          gcloud container clusters get-credentials \
              --project $GKE_PROJECT_ID \
              $GKE_CLUSTER
      - name: Clean up dev resources
        run: |
          # Set variables
          export branch_name=$( echo ${{ github.ref_name }} | tr '[:upper:]' '[:lower:]' | tr -c '[:alnum:]' '-' | sed 's/.$//' )
          export repository_name=$( echo ${{ github.repository }} | cut -d'/' -f2)

          # Delete resources
          kubectl delete job -l repository=$repository_name,branch=$branch_name
          kubectl delete deployment -l repository=$repository_name,branch=$branch_name
          kubectl delete service -l repository=$repository_name,branch=$branch_name
          kubectl delete ingress -l repository=$repository_name,branch=$branch_name
          kubectl delete configmap -l repository=$repository_name,branch=$branch_name

  deploy-dev:
    needs:
      - clean-dev-resources
      - build-push
    steps:
      - uses: actions/checkout@v3
      - name: Authenticate to Google Cloud
        uses: google-github-actions/auth@v0.8.0
        with:
          credentials_json: ${{ secrets.GKE_JSON_KEY }}
      - name: Set up Cloud SDK
        uses: google-github-actions/setup-gcloud@v0.6.0
        with:
          version: ${{ env.GCLOUD_SDK_VERSION }}
          project_id: ${{ env.GKE_PROJECT_ID }}
      - name: Set cluster credentials
        env:
          PROJECT_ID: ${{ env.GKE_PROJECT_ID }}
          GKE_CLUSTER: ${{ env.GKE_CLUSTER }}
        run: |
          gcloud container clusters get-credentials \
              --project $GKE_PROJECT_ID \
              $GKE_CLUSTER
      - uses: actions/setup-python@v3
        with:
          python-version: ${{ env.PYTHON_VERSION }}
      - name: Cache multiple Pips
        uses: actions/cache@v3
        with:
          path: |
            ~/.cache/pip
          key: ${{ runner.os }}-${{ env.PYTHON_VERSION }}-${{ hashFiles('**/poetry.lock') }}
      - name: install dependencies
        run: |
          pip install 'poetry== ${{ env.POETRY_VERSION }}'
          poetry install
      - name: Generate dev manifest
        run: |
          # Set variables
          export branch_name=$( echo ${{ github.ref_name }} | tr '[:upper:]' '[:lower:]' | tr -c '[:alnum:]' '-' | sed 's/.$//' )
          export repository_name=$( echo ${{ github.repository }} | cut -d'/' -f2)

          # Generate dev manifest
          poetry run komposer \
            --repository-name $repository_name \
            --branch-name $branch_name \
          > dev-deploy-template.yaml
      - name: Deploy dev manifest
        run: |
          # Set variables
          export branch_name=$( echo ${{ github.ref_name }} | tr '[:upper:]' '[:lower:]' | tr -c '[:alnum:]' '-' | sed 's/.$//' )
          export repository_name=$( echo ${{ github.repository }} | cut -d'/' -f2)
          export sha=${GITHUB_SHA::7}
          export image="${{ env.SERVICE_NAME }}:${sha}"

          # Render the manifest
          cat dev-deploy-template.yaml | envsubst '${image}' > dev-deploy.yaml

          # Deploy service
          cat dev-deploy.yaml | kubectl apply -l pre-deploy!=yes -f -

          for i in $(kubectl get deployments -l repository=$repository_name,branch=$branch_name -o name)
          do
            kubectl rollout status "$i" --timeout=300s
          done

Cleaning Kubernetes resources

Before deploying we need to remove any previously deployed resources by deleting all the resources with the labels matching the branch and repository names:

name: "Komposer deploy example"

env:
  SERVICE_NAME: "service-example"
  GCLOUD_SDK_VERSION: "386.0.0"
  PYTHON_VERSION: "3.10"
  POETRY_VERSION: "1.1.15"
  GKE_PROJECT_ID: "my-project-id"
  GKE_CLUSTER: "my-cluster-name"

on:
  pull_request:

jobs:
  build-push:
    runs-on: ubuntu
    steps:
      - uses: actions/checkout@v3
      - name: Build and push
        run: |
          sha=${GITHUB_SHA::7}
          image=${{ env.SERVICE_NAME }}:${sha}

          docker build -t "$image" .
          docker push "$image"

  clean-dev-resources:
    steps:
      - uses: actions/checkout@v3
      - name: Authenticate to Google Cloud
        uses: google-github-actions/auth@v0.8.0
        with:
          credentials_json: ${{ secrets.GKE_JSON_KEY }}
      - name: Set up Cloud SDK
        uses: google-github-actions/setup-gcloud@v0.6.0
        with:
          version: ${{ env.GCLOUD_SDK_VERSION }}
          project_id: ${{ env.GKE_PROJECT_ID }}
      - name: Set cluster credentials
        env:
          PROJECT_ID: ${{ env.GKE_PROJECT_ID }}
          GKE_CLUSTER: ${{ env.GKE_CLUSTER }}
        run: |
          gcloud container clusters get-credentials \
              --project $GKE_PROJECT_ID \
              $GKE_CLUSTER
      - name: Clean up dev resources
        run: |
          # Set variables
          export branch_name=$( echo ${{ github.ref_name }} | tr '[:upper:]' '[:lower:]' | tr -c '[:alnum:]' '-' | sed 's/.$//' )
          export repository_name=$( echo ${{ github.repository }} | cut -d'/' -f2)

          # Delete resources
          kubectl delete job -l repository=$repository_name,branch=$branch_name
          kubectl delete deployment -l repository=$repository_name,branch=$branch_name
          kubectl delete service -l repository=$repository_name,branch=$branch_name
          kubectl delete ingress -l repository=$repository_name,branch=$branch_name
          kubectl delete configmap -l repository=$repository_name,branch=$branch_name

  deploy-dev:
    needs:
      - clean-dev-resources
      - build-push
    steps:
      - uses: actions/checkout@v3
      - name: Authenticate to Google Cloud
        uses: google-github-actions/auth@v0.8.0
        with:
          credentials_json: ${{ secrets.GKE_JSON_KEY }}
      - name: Set up Cloud SDK
        uses: google-github-actions/setup-gcloud@v0.6.0
        with:
          version: ${{ env.GCLOUD_SDK_VERSION }}
          project_id: ${{ env.GKE_PROJECT_ID }}
      - name: Set cluster credentials
        env:
          PROJECT_ID: ${{ env.GKE_PROJECT_ID }}
          GKE_CLUSTER: ${{ env.GKE_CLUSTER }}
        run: |
          gcloud container clusters get-credentials \
              --project $GKE_PROJECT_ID \
              $GKE_CLUSTER
      - uses: actions/setup-python@v3
        with:
          python-version: ${{ env.PYTHON_VERSION }}
      - name: Cache multiple Pips
        uses: actions/cache@v3
        with:
          path: |
            ~/.cache/pip
          key: ${{ runner.os }}-${{ env.PYTHON_VERSION }}-${{ hashFiles('**/poetry.lock') }}
      - name: install dependencies
        run: |
          pip install 'poetry== ${{ env.POETRY_VERSION }}'
          poetry install
      - name: Generate dev manifest
        run: |
          # Set variables
          export branch_name=$( echo ${{ github.ref_name }} | tr '[:upper:]' '[:lower:]' | tr -c '[:alnum:]' '-' | sed 's/.$//' )
          export repository_name=$( echo ${{ github.repository }} | cut -d'/' -f2)

          # Generate dev manifest
          poetry run komposer \
            --repository-name $repository_name \
            --branch-name $branch_name \
          > dev-deploy-template.yaml
      - name: Deploy dev manifest
        run: |
          # Set variables
          export branch_name=$( echo ${{ github.ref_name }} | tr '[:upper:]' '[:lower:]' | tr -c '[:alnum:]' '-' | sed 's/.$//' )
          export repository_name=$( echo ${{ github.repository }} | cut -d'/' -f2)
          export sha=${GITHUB_SHA::7}
          export image="${{ env.SERVICE_NAME }}:${sha}"

          # Render the manifest
          cat dev-deploy-template.yaml | envsubst '${image}' > dev-deploy.yaml

          # Deploy service
          cat dev-deploy.yaml | kubectl apply -l pre-deploy!=yes -f -

          for i in $(kubectl get deployments -l repository=$repository_name,branch=$branch_name -o name)
          do
            kubectl rollout status "$i" --timeout=300s
          done

This is necessary because resources can be added, removed or renamed in the Komposer manifest between runs of the CI and the kubectl command doesn't provide a way to perform a full sync of the resources in the cluster compared with the resources in the Komposer's manifest.

Deploy the Komposer manifest

The last section, generating the Kubernetes manifest with Komposer and deploying the resources in the Kubernetes cluster.

After installing Python and setting up Google Cloud SDK we generate the manifest's template with Komposer:

name: "Komposer deploy example"

env:
  SERVICE_NAME: "service-example"
  GCLOUD_SDK_VERSION: "386.0.0"
  PYTHON_VERSION: "3.10"
  POETRY_VERSION: "1.1.15"
  GKE_PROJECT_ID: "my-project-id"
  GKE_CLUSTER: "my-cluster-name"

on:
  pull_request:

jobs:
  build-push:
    runs-on: ubuntu
    steps:
      - uses: actions/checkout@v3
      - name: Build and push
        run: |
          sha=${GITHUB_SHA::7}
          image=${{ env.SERVICE_NAME }}:${sha}

          docker build -t "$image" .
          docker push "$image"

  clean-dev-resources:
    steps:
      - uses: actions/checkout@v3
      - name: Authenticate to Google Cloud
        uses: google-github-actions/auth@v0.8.0
        with:
          credentials_json: ${{ secrets.GKE_JSON_KEY }}
      - name: Set up Cloud SDK
        uses: google-github-actions/setup-gcloud@v0.6.0
        with:
          version: ${{ env.GCLOUD_SDK_VERSION }}
          project_id: ${{ env.GKE_PROJECT_ID }}
      - name: Set cluster credentials
        env:
          PROJECT_ID: ${{ env.GKE_PROJECT_ID }}
          GKE_CLUSTER: ${{ env.GKE_CLUSTER }}
        run: |
          gcloud container clusters get-credentials \
              --project $GKE_PROJECT_ID \
              $GKE_CLUSTER
      - name: Clean up dev resources
        run: |
          # Set variables
          export branch_name=$( echo ${{ github.ref_name }} | tr '[:upper:]' '[:lower:]' | tr -c '[:alnum:]' '-' | sed 's/.$//' )
          export repository_name=$( echo ${{ github.repository }} | cut -d'/' -f2)

          # Delete resources
          kubectl delete job -l repository=$repository_name,branch=$branch_name
          kubectl delete deployment -l repository=$repository_name,branch=$branch_name
          kubectl delete service -l repository=$repository_name,branch=$branch_name
          kubectl delete ingress -l repository=$repository_name,branch=$branch_name
          kubectl delete configmap -l repository=$repository_name,branch=$branch_name

  deploy-dev:
    needs:
      - clean-dev-resources
      - build-push
    steps:
      - uses: actions/checkout@v3
      - name: Authenticate to Google Cloud
        uses: google-github-actions/auth@v0.8.0
        with:
          credentials_json: ${{ secrets.GKE_JSON_KEY }}
      - name: Set up Cloud SDK
        uses: google-github-actions/setup-gcloud@v0.6.0
        with:
          version: ${{ env.GCLOUD_SDK_VERSION }}
          project_id: ${{ env.GKE_PROJECT_ID }}
      - name: Set cluster credentials
        env:
          PROJECT_ID: ${{ env.GKE_PROJECT_ID }}
          GKE_CLUSTER: ${{ env.GKE_CLUSTER }}
        run: |
          gcloud container clusters get-credentials \
              --project $GKE_PROJECT_ID \
              $GKE_CLUSTER
      - uses: actions/setup-python@v3
        with:
          python-version: ${{ env.PYTHON_VERSION }}
      - name: Cache multiple Pips
        uses: actions/cache@v3
        with:
          path: |
            ~/.cache/pip
          key: ${{ runner.os }}-${{ env.PYTHON_VERSION }}-${{ hashFiles('**/poetry.lock') }}
      - name: install dependencies
        run: |
          pip install 'poetry== ${{ env.POETRY_VERSION }}'
          poetry install
      - name: Generate dev manifest
        run: |
          # Set variables
          export branch_name=$( echo ${{ github.ref_name }} | tr '[:upper:]' '[:lower:]' | tr -c '[:alnum:]' '-' | sed 's/.$//' )
          export repository_name=$( echo ${{ github.repository }} | cut -d'/' -f2)

          # Generate dev manifest
          poetry run komposer \
            --repository-name $repository_name \
            --branch-name $branch_name \
          > dev-deploy-template.yaml
      - name: Deploy dev manifest
        run: |
          # Set variables
          export branch_name=$( echo ${{ github.ref_name }} | tr '[:upper:]' '[:lower:]' | tr -c '[:alnum:]' '-' | sed 's/.$//' )
          export repository_name=$( echo ${{ github.repository }} | cut -d'/' -f2)
          export sha=${GITHUB_SHA::7}
          export image="${{ env.SERVICE_NAME }}:${sha}"

          # Render the manifest
          cat dev-deploy-template.yaml | envsubst '${image}' > dev-deploy.yaml

          # Deploy service
          cat dev-deploy.yaml | kubectl apply -l pre-deploy!=yes -f -

          for i in $(kubectl get deployments -l repository=$repository_name,branch=$branch_name -o name)
          do
            kubectl rollout status "$i" --timeout=300s
          done

Then we render the manifest by substituting the variables, in this case the Docker image's name, deploy it and waiting for the rollout to finish:

name: "Komposer deploy example"

env:
  SERVICE_NAME: "service-example"
  GCLOUD_SDK_VERSION: "386.0.0"
  PYTHON_VERSION: "3.10"
  POETRY_VERSION: "1.1.15"
  GKE_PROJECT_ID: "my-project-id"
  GKE_CLUSTER: "my-cluster-name"

on:
  pull_request:

jobs:
  build-push:
    runs-on: ubuntu
    steps:
      - uses: actions/checkout@v3
      - name: Build and push
        run: |
          sha=${GITHUB_SHA::7}
          image=${{ env.SERVICE_NAME }}:${sha}

          docker build -t "$image" .
          docker push "$image"

  clean-dev-resources:
    steps:
      - uses: actions/checkout@v3
      - name: Authenticate to Google Cloud
        uses: google-github-actions/auth@v0.8.0
        with:
          credentials_json: ${{ secrets.GKE_JSON_KEY }}
      - name: Set up Cloud SDK
        uses: google-github-actions/setup-gcloud@v0.6.0
        with:
          version: ${{ env.GCLOUD_SDK_VERSION }}
          project_id: ${{ env.GKE_PROJECT_ID }}
      - name: Set cluster credentials
        env:
          PROJECT_ID: ${{ env.GKE_PROJECT_ID }}
          GKE_CLUSTER: ${{ env.GKE_CLUSTER }}
        run: |
          gcloud container clusters get-credentials \
              --project $GKE_PROJECT_ID \
              $GKE_CLUSTER
      - name: Clean up dev resources
        run: |
          # Set variables
          export branch_name=$( echo ${{ github.ref_name }} | tr '[:upper:]' '[:lower:]' | tr -c '[:alnum:]' '-' | sed 's/.$//' )
          export repository_name=$( echo ${{ github.repository }} | cut -d'/' -f2)

          # Delete resources
          kubectl delete job -l repository=$repository_name,branch=$branch_name
          kubectl delete deployment -l repository=$repository_name,branch=$branch_name
          kubectl delete service -l repository=$repository_name,branch=$branch_name
          kubectl delete ingress -l repository=$repository_name,branch=$branch_name
          kubectl delete configmap -l repository=$repository_name,branch=$branch_name

  deploy-dev:
    needs:
      - clean-dev-resources
      - build-push
    steps:
      - uses: actions/checkout@v3
      - name: Authenticate to Google Cloud
        uses: google-github-actions/auth@v0.8.0
        with:
          credentials_json: ${{ secrets.GKE_JSON_KEY }}
      - name: Set up Cloud SDK
        uses: google-github-actions/setup-gcloud@v0.6.0
        with:
          version: ${{ env.GCLOUD_SDK_VERSION }}
          project_id: ${{ env.GKE_PROJECT_ID }}
      - name: Set cluster credentials
        env:
          PROJECT_ID: ${{ env.GKE_PROJECT_ID }}
          GKE_CLUSTER: ${{ env.GKE_CLUSTER }}
        run: |
          gcloud container clusters get-credentials \
              --project $GKE_PROJECT_ID \
              $GKE_CLUSTER
      - uses: actions/setup-python@v3
        with:
          python-version: ${{ env.PYTHON_VERSION }}
      - name: Cache multiple Pips
        uses: actions/cache@v3
        with:
          path: |
            ~/.cache/pip
          key: ${{ runner.os }}-${{ env.PYTHON_VERSION }}-${{ hashFiles('**/poetry.lock') }}
      - name: install dependencies
        run: |
          pip install 'poetry== ${{ env.POETRY_VERSION }}'
          poetry install
      - name: Generate dev manifest
        run: |
          # Set variables
          export branch_name=$( echo ${{ github.ref_name }} | tr '[:upper:]' '[:lower:]' | tr -c '[:alnum:]' '-' | sed 's/.$//' )
          export repository_name=$( echo ${{ github.repository }} | cut -d'/' -f2)

          # Generate dev manifest
          poetry run komposer \
            --repository-name $repository_name \
            --branch-name $branch_name \
          > dev-deploy-template.yaml
      - name: Deploy dev manifest
        run: |
          # Set variables
          export branch_name=$( echo ${{ github.ref_name }} | tr '[:upper:]' '[:lower:]' | tr -c '[:alnum:]' '-' | sed 's/.$//' )
          export repository_name=$( echo ${{ github.repository }} | cut -d'/' -f2)
          export sha=${GITHUB_SHA::7}
          export image="${{ env.SERVICE_NAME }}:${sha}"

          # Render the manifest
          cat dev-deploy-template.yaml | envsubst '${image}' > dev-deploy.yaml

          # Deploy service
          cat dev-deploy.yaml | kubectl apply -l pre-deploy!=yes -f -

          for i in $(kubectl get deployments -l repository=$repository_name,branch=$branch_name -o name)
          do
            kubectl rollout status "$i" --timeout=300s
          done