GitHub Actions as CI component for CI/CD : Store Docker image in GCP Artifacts Registry

This is the CI (continues integration) part of common CI/CD pipelines.

Task: Set up a new CI pipeline using GitHub Actions that should be triggered for any pull request.

1. The GitHub Actions file structure in your repo:

IMAGE-BUILDER repo:
.
├── .git
├── .github
│   └── workflows
│       ├── flask-app
│       │   ├── Dockerfile
│       │   ├── app.py
│       │   └── requirements.txt
│       └── g-registry-build.yaml    
├── .gitignore
├── README.md
└── sonar-project.properties

image-builder/.github/workflows/g-registry-build.yaml


# This is a basic workflow to help you get started with Actions

name: Docker Build and Push Release

# Controls when the action will run. Triggers the workflow on push or pull request
# events but only for the master branch
on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]
    types: [opened, synchronize, reopened]

jobs:

  sonarcloud:
    name: SonarCloud
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0  # Shallow clones should be disabled for a better relevancy of analysis
      - name: SonarCloud static code Scan
        uses: SonarSource/sonarcloud-github-action@master
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}  # Needed to get PR information, if any
          SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}

  app-build:
    name: Tagged Docker release to Google Artifact Registry
    runs-on: ubuntu-latest
    needs: sonarcloud
    permissions:
      contents: 'read'
      id-token: 'write'

    steps:
    - id: checkout
      name: Checkout
      uses: 'actions/checkout@v3'
    
    - name: Set up Docker Buildx
      uses: docker/setup-buildx-action@v2 

    - name: Get tag for the image
      id: get-tag
      run: echo ::set-output name=short_ref::${GITHUB_REF#refs/*/}
  
    - id: 'auth'
      name: 'Authenticate to Google Cloud'
      uses: 'google-github-actions/auth@v1'
      with:
        token_format: access_token
        workload_identity_provider: 'projects/12344123412311/locations/global/workloadIdentityPools/my-pool/providers/provider'
        service_account: '[email protected]'
        access_token_lifetime: 300s

    - name: Login to Artifact Registry
      uses: docker/login-action@v1
      with:
        registry: us-west2-docker.pkg.dev  #us-west2-docker.pkg.dev/my-project-name/flask
        username: oauth2accesstoken
        password: ${{ steps.auth.outputs.access_token }}

    - id: docker-push-tagged
      name: Tag Docker image and push to Google Artifact Registry
      uses: 'docker/build-push-action@v2'
      with:
        context: .github/workflows/flask-app
        file: .github/workflows/flask-app/Dockerfile
        push: true
        tags: |
          us-west2-docker.pkg.dev/my-project-name.github/workflows/g-registry-build.yaml/flask-docker/application:${{ steps.get-tag.outputs.short_ref }}

To setup the Sonar Cloud code scanner put the sonar-project.properties file in the root of the repo :

image-builder/sonar-project.properties

GCP Artifact Registry Setup (

Pre-setup:

It can be done from GCP console (embeded shell CLI)

#Configuring gcloud in GitHub Actions

This GitHub Action to configure authentication for the gcloud CLI tool.

Warning! Workload Identity Federation requires Cloud SDK (gcloud) version 363.0.0 or later.

OUTPUT:

Save this value as an environment variable:

Create a Workload Identity Provider in that pool:

OUTPUT: Created workload identity pool provider [provider].

Allow authentications from the Workload Identity Provider originating from your repository to impersonate the Service Account created above:

TODO(developer): Update this value to your GitHub repository.

export REPO="username(or organization-name)/repo-name" # e.g. "google/chrome"

If you want to admit all repos of an owner (user or organization), map on attribute.repository_owner:

OUTPUT:

#Authenticating to Container Registry and Artifact Registry This example demonstrates authenticating to Google Container Registry (GCR) or Google Artifact Registry (GAR). The most common way to authenticate to these services is via a gcloud docker proxy. However, you can authenticate to these registries directly using the auth action:

You must set token_format: access_token in your Action YAML. Here are a few examples:

flask-app/Dockerfile

flask-app/requirements.txt

flask-app/app.py

Last updated