Skip to content

Commit

Permalink
HEAT-230 Adding helm config to run updating dependency info as job (#6)
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewrlee authored Apr 3, 2024
1 parent fceb264 commit 8daeac1
Show file tree
Hide file tree
Showing 18 changed files with 587 additions and 7 deletions.
31 changes: 31 additions & 0 deletions .github/actions/cloud-platform-auth/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Cloud Platform Auth
description: Authenticate with MOJ Cloud Platform

inputs:
api:
description: The KUBE_ENV_API
required: true
cert:
description: The KUBE_CERT
required: true
cluster:
description: The KUBE_CLUSTER
required: true
namespace:
description: The KUBE_NAMESPACE
required: true
token:
description: The KUBE_TOKEN
required: true

runs:
using: composite
steps:
- name: Authenticate
shell: bash
run: |
echo "${{ inputs.cert }}" > ca.crt
kubectl config set-cluster ${{ inputs.cluster }} --certificate-authority=./ca.crt --server=${{ inputs.api }}
kubectl config set-credentials cd-serviceaccount --token=${{ inputs.token }}
kubectl config set-context ${{ inputs.cluster }} --cluster=${{ inputs.cluster }} --user=cd-serviceaccount --namespace=${{ inputs.namespace }}
kubectl config use-context ${{ inputs.cluster }}
59 changes: 59 additions & 0 deletions .github/actions/cloud-platform-deploy/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
name: Cloud Platform Deploy
description: Deploy to Cloud Platform using Helm

inputs:
environment:
description: The environment to deploy to (dev/preprod/prod)
required: true
version:
description: The version of the service to deploy
required: true
api:
description: The KUBE_ENV_API
required: true
cert:
description: The KUBE_CERT
required: true
cluster:
description: The KUBE_CLUSTER
required: true
namespace:
description: The KUBE_NAMESPACE
required: true
token:
description: The KUBE_TOKEN
required: true

runs:
using: composite
steps:
- uses: actions/checkout@v3

- name: Authenticate
uses: ./.github/actions/cloud-platform-auth
with:
api: ${{ inputs.api }}
cert: ${{ inputs.cert }}
cluster: ${{ inputs.cluster }}
namespace: ${{ inputs.namespace }}
token: ${{ inputs.token }}

- name: Deploy
shell: bash
run: |
eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"
brew install helm
cd helm_deploy/${{ github.event.repository.name }}
yq -i ".appVersion = \"${{ inputs.version }}\"" "Chart.yaml"
helm dependency update .
exec helm upgrade '${{ github.event.repository.name }}' . \
--atomic \
--history-max 10 \
--force \
--install \
--reset-values \
--set 'image.tag=${{ inputs.version }}' \
--set 'version=${{ inputs.version }}' \
--timeout 10m \
--values '${{ steps.env.outputs.values-file }}' \
--wait
38 changes: 38 additions & 0 deletions .github/actions/docker-build/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: Build Docker image
description: Build, and optionally push, a Docker image

inputs:
project:
description: Project name
push:
description: Whether to push images to the registry
default: 'false'
version:
description: Version

runs:
using: "composite"
steps:
- uses: docker/setup-qemu-action@v2
- uses: docker/setup-buildx-action@v2
- uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ github.token }}

- name: Build Docker images
uses: docker/build-push-action@v4
with:
cache-from: type=gha
cache-to: type=gha,mode=max
context: .
push: ${{ inputs.push }}
provenance: false
tags: |
ghcr.io/ministryofjustice/${{ inputs.project }}:latest
ghcr.io/ministryofjustice/${{ inputs.project }}:${{ inputs.version }}
build-args: |
GIT_BRANCH=${{ github.head_ref || github.ref_name }}
GIT_REF=${{ github.sha }}
BUILD_NUMBER=${{ inputs.version }}
50 changes: 50 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: Build

on:
workflow_call:
inputs:
push:
type: boolean
default: false
force-deploy:
type: boolean
default: false
outputs:
version:
value: ${{ jobs.build-docker.outputs.version }}
workflow_dispatch:
inputs:
push:
description: Push images
type: boolean
default: false

env:
push: ${{ inputs.push }}

jobs:
build-docker:
name: Docker build
runs-on: ubuntu-latest
strategy:
matrix:
project:
- hmpps-component-dependencies
outputs:
version: ${{ steps.version.outputs.version }}
steps:
- uses: actions/checkout@v3

- name: Set version
id: version
run: |
version=$(date '+%Y-%m-%d').${{ github.run_number }}.$(echo ${{ github.sha }} | cut -c1-7)
echo "version=$version" | tee -a "$GITHUB_OUTPUT"
- name: Build Docker images
uses: ./.github/actions/docker-build
id: build
with:
project: ${{ matrix.project }}
push: ${{ env.push }}
version: ${{ steps.version.outputs.version }}
72 changes: 72 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
name: Deploy

on:
workflow_call:
inputs:
github_environment:
description: The name of the github environment for deployment secrets
type: string
required: true
environment:
description: The name of the environment to deploy to
type: string
required: true
version:
description: The image version to deploy
type: string
required: true

workflow_dispatch:
inputs:
github_environment:
description: The name of the github environment for deployment secrets
type: choice
required: true
options:
- development
- production
environment:
description: Environment
type: choice
required: true
options:
- dev
- prod
version:
description: Image version
type: string
required: true

jobs:
deploy:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
environment: [development, production]
environment:
name: ${{ inputs.github_environment }}
steps:
- uses: actions/checkout@v3

- name: Deploy to Dev
uses: ./.github/actions/cloud-platform-deploy
with:
environment: ${{ inputs.environment }}
version: ${{ inputs.version }}
api: https://${{ secrets.DEVELOPMENT_KUBE_CLUSTER }}
cert: ${{ secrets.DEVELOPMENT_KUBE_CERT }}
cluster: ${{ secrets.DEVELOPMENT_KUBE_CLUSTER }}
namespace: ${{ secrets.DEVELOPMENT_KUBE_NAMESPACE }}
token: ${{ secrets.DEVELOPMENT_KUBE_TOKEN }}

- name: Deploy to Prod
uses: ./.github/actions/cloud-platform-deploy
with:
environment: ${{ inputs.environment }}
version: ${{ inputs.version }}
api: https://${{ secrets.PRODUCTION_KUBE_CLUSTER }}
cert: ${{ secrets.PRODUCTION_KUBE_CERT }}
cluster: ${{ secrets.PRODUCTION_KUBE_CLUSTER }}
namespace: ${{ secrets.PRODUCTION_KUBE_NAMESPACE }}
token: ${{ secrets.PRODUCTION_KUBE_TOKEN }}
46 changes: 46 additions & 0 deletions .github/workflows/pipeline.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: Pipeline

on:
push:
branches:
- main
workflow_dispatch: # Can be triggered manually from a branch
inputs:
environment:
description: 'Deployment Environment (valid values: "development", "production")'
required: true
default: 'development'
version:
description: 'Application version to deploy'
required: true

jobs:
build:
name: Build
uses: ./.github/workflows/build.yml
with:
push: true
secrets: inherit


deploy_to_dev:
name: Deploy to dev
uses: ./.github/workflows/deploy.yml
needs: build
with:
github_environment: development
environment: dev
version: ${{ needs.build.outputs.version }}
secrets: inherit


deploy_to_prod:
name: Deploy to prod
uses: ./.github/workflows/deploy.yml
needs:
- deploy_to_dev # wait for the deploy_to_dev job to complete
with:
github_environment: production
environment: prod
version: ${{ github.event.inputs.version }}
secrets: inherit
66 changes: 66 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Stage: base image
FROM node:20.11-bookworm-slim as base

ARG BUILD_NUMBER
ARG GIT_REF
ARG GIT_BRANCH

LABEL maintainer="HMPPS Digital Studio <[email protected]>"

ENV TZ=Europe/London
RUN ln -snf "/usr/share/zoneinfo/$TZ" /etc/localtime && echo "$TZ" > /etc/timezone

RUN addgroup --gid 2000 --system appgroup && \
adduser --uid 2000 --system appuser --gid 2000

WORKDIR /app

# Cache breaking and ensure required build / git args defined
RUN test -n "$BUILD_NUMBER" || (echo "BUILD_NUMBER not set" && false)
RUN test -n "$GIT_REF" || (echo "GIT_REF not set" && false)
RUN test -n "$GIT_BRANCH" || (echo "GIT_BRANCH not set" && false)

# Define env variables for runtime health / info
ENV BUILD_NUMBER=${BUILD_NUMBER}
ENV GIT_REF=${GIT_REF}
ENV GIT_BRANCH=${GIT_BRANCH}

RUN apt-get update && \
apt-get upgrade -y && \
apt-get autoremove -y && \
rm -rf /var/lib/apt/lists/*

# Stage: build assets
FROM base as build

ARG BUILD_NUMBER
ARG GIT_REF
ARG GIT_BRANCH

COPY package*.json ./
RUN npm ci --no-audit

COPY . .
RUN npm run build

RUN npm prune --no-audit --omit=dev

# Stage: copy production assets and dependencies
FROM base

COPY --from=build --chown=appuser:appgroup \
/app/package.json \
/app/package-lock.json \
./

COPY --from=build --chown=appuser:appgroup \
/app/dist ./dist

COPY --from=build --chown=appuser:appgroup \
/app/node_modules ./node_modules

EXPOSE 3000 3001
ENV NODE_ENV='production'
USER 2000

CMD [ "npm", "start" ]
22 changes: 22 additions & 0 deletions helm_deploy/.helmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/
Loading

0 comments on commit 8daeac1

Please sign in to comment.