diff --git a/.dockerignore b/.dockerignore index 3edec41..4dac2d4 100644 --- a/.dockerignore +++ b/.dockerignore @@ -32,3 +32,6 @@ wheels/ *.egg-info/ .installed.cfg *.egg + +# https://github.com/google-github-actions/auth +gha-creds-*.json diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..5c156e5 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,123 @@ +# https://medium.com/@sbkapelner/building-and-pushing-to-artifact-registry-with-github-actions-7027b3e443c1 +# +# This workflow will build a docker container, publish it to Google Container +# Registry, and deploy it to GKE when there is a push to the "main" +# branch. +# +# To configure this workflow: +# +# 1. Enable the following Google Cloud APIs: +# +# - Artifact Registry (artifactregistry.googleapis.com) +# - Google Kubernetes Engine (container.googleapis.com) +# - IAM Credentials API (iamcredentials.googleapis.com) +# +# You can learn more about enabling APIs at +# https://support.google.com/googleapi/answer/6158841. +# +# 2. Ensure that your repository contains the necessary configuration for your +# Google Kubernetes Engine cluster, including deployment.yml, +# kustomization.yml, service.yml, etc. +# +# 3. Create and configure a Workload Identity Provider for GitHub: +# https://github.com/google-github-actions/auth#preferred-direct-workload-identity-federation. +# +# Depending on how you authenticate, you will need to grant an IAM principal +# permissions on Google Cloud: +# +# - Artifact Registry Administrator (roles/artifactregistry.admin) +# - Kubernetes Engine Developer (roles/container.developer) +# +# You can learn more about setting IAM permissions at +# https://cloud.google.com/iam/docs/manage-access-other-resources +# +# 5. Change the values in the "env" block to match your values. + +name: 'Build Wagtail Image' + +on: + push: + tags: + - 'stg-build-*' + +env: + PROJECT_ID: 'cca-web-staging' + GAR_LOCATION: 'us-west1' + REPOSITORY: 'us-west1-docker.pkg.dev/cca-web-staging/cca-docker-web' + IMAGE: 'libraries' + WORKLOAD_IDENTITY_PROVIDER: projects/316944295291/locations/global/workloadIdentityPools/github/providers/libraries-wagtail + +jobs: + lint: + name: 'Lint' + runs-on: 'ubuntu-latest' + environment: 'staging' + steps: + - run: npm run eslint + - run: npx run sass-lint + + setupbuildandpush: + name: 'Setup, Build, and Push Docker image to Artifact Registry' + runs-on: 'ubuntu-latest' + environment: 'staging' + + permissions: + contents: 'read' + id-token: 'write' + + steps: + - name: 'Checkout' + uses: 'actions/checkout@v4.2.2' + + # Configure Workload Identity Federation and generate an access token. + # See https://github.com/google-github-actions/auth for more options, + # including authenticating via a JSON credentials file. + - id: 'auth' + name: 'Authenticate to Google Cloud' + uses: 'google-github-actions/auth@v2.1.8' + with: + create_credentials_file: true # Important for Docker auth + project_id: '${{ env.PROJECT_ID }}' + service_account: 'libraries-wagtail-gh-actions@cca-web-staging.iam.gserviceaccount.com' + token_format: 'access_token' # Explicitly request OAuth token + workload_identity_provider: '${{ env.WORKLOAD_IDENTITY_PROVIDER }}' + + # Configure Docker to use the gcloud credentials + - name: 'Set up Cloud SDK' + uses: 'google-github-actions/setup-gcloud@v2.1.4' + + # Apparently this step is necessary too, google-github-actions/auth is not enough + - name: 'Docker Auth' + run: gcloud auth configure-docker ${{ env.GAR_LOCATION }}-docker.pkg.dev + + # Authenticate Docker to Google Cloud Artifact Registry + - name: 'Docker Auth' + uses: 'docker/login-action@v3.3.0' + with: + username: 'oauth2accesstoken' + password: '${{ steps.auth.outputs.auth_token }}' + registry: '${{ env.GAR_LOCATION }}-docker.pkg.dev' + + - name: 'Pull Latest Image' + # we need a consistent tag like "latest" or this docker pull fails & we lose our build cache + run: docker pull "${{ env.REPOSITORY }}/${{ env.IMAGE}}:latest" + + # unique Docker tag like ep-full-20-abcd123 + - name: Generate tags + id: tag + run: | + SHORT_SHA=$(echo ${{ github.sha }} | cut -c1-7) + if [ "${{ github.ref_type }}" = "tag" ]; then + VERSION="${{ github.ref_name }}-${SHORT_SHA}" + else + VERSION="${SHORT_SHA}" + fi + echo "tag=${{ env.REPOSITORY }}/${{ env.IMAGE}}:${VERSION}" >> $GITHUB_OUTPUT + + # TODO using existing Docker actions might be better? https://docs.docker.com/build/ci/github-actions/cache/ + - name: "Build and Tag Image" + # must build with --build-arg BUILDKIT_INLINE_CACHE=1 or image doesn't work with --cache-form + run: docker build --build-arg BUILDKIT_INLINE_CACHE=1 --cache-from "${{ env.REPOSITORY }}/${{ env.IMAGE}}:latest" --tag "${{ steps.tag.outputs.tag }}" --tag "${{ env.REPOSITORY }}/${{ env.IMAGE}}:latest" . + + - name: 'Push Image' + run: docker push --all-tags "${{ env.REPOSITORY }}/${{ env.IMAGE}}" diff --git a/.gitignore b/.gitignore index a6daac1..7af8e4d 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,6 @@ libraries/libraries/static/css *.min.js *.min.js.map .eslintcache + +# https://github.com/google-github-actions/auth +gha-creds-*.json