Skip to content

Commit

Permalink
feat(docker): add hashes to image labels, deploy correct prod tag
Browse files Browse the repository at this point in the history
Co-Authored-By: Pram Gurusinga <9930966+pgurusinga@users.noreply.github.com>
  • Loading branch information
chohner and pgurusinga committed Jan 12, 2024
1 parent 89bfd31 commit 85ceead
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 38 deletions.
12 changes: 9 additions & 3 deletions .github/workflows/build-content.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,12 @@ jobs:
- run: npm run verifyWebsites
- run: ./docker.sh --build content
- run: ./docker.sh --push content
- run: ./docker.sh --build prod
- run: ./docker.sh --push prod
- id: prod_image_tag
run: echo "prod_image_tag=$(./docker.sh --prodImageTag)" >> $GITHUB_OUTPUT
outputs:
prod_image_tag: ${{ steps.prod_image_tag.outputs.prod_image_tag }}

deploy-preview:
needs: [build-push-content-image, get-content-file]
Expand All @@ -106,7 +112,7 @@ jobs:
uses: digitalservicebund/github-actions/argocd-deploy@a223a68bc5982e5175beb73c708d99d8f9ba7858
with:
environment: preview
version: ${{ env.IMAGE_VERSION }}-${{ needs.get-content-file.outputs.content_checksum }}
version: ${{ needs.build-push-content-image.outputs.prod_image_tag }}
deploying_repo: a2j-rechtsantragstelle
infra_repo: a2j-rechtsantragstelle-infra
deploy_key: ${{ secrets.DEPLOY_KEY }}
Expand All @@ -124,7 +130,7 @@ jobs:
USE_EXISTING_SERVER: true

deploy-production:
needs: [verify-preview-e2e, get-content-file]
needs: [verify-preview-e2e, build-push-content-image]
runs-on: ubuntu-latest
environment: production
steps:
Expand All @@ -140,7 +146,7 @@ jobs:
uses: digitalservicebund/github-actions/argocd-deploy@a223a68bc5982e5175beb73c708d99d8f9ba7858
with:
environment: production
version: ${{ env.IMAGE_VERSION }}-${{ needs.get-content-file.outputs.content_checksum }}
version: ${{ needs.build-push-content-image.outputs.prod_image_tag }}
deploying_repo: a2j-rechtsantragstelle
infra_repo: a2j-rechtsantragstelle-infra
deploy_key: ${{ secrets.DEPLOY_KEY }}
Expand Down
20 changes: 13 additions & 7 deletions .github/workflows/ci-pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ jobs:
- uses: actions/checkout@v4
- uses: ./.github/actions/cached-checkout-install
- run: ./docker.sh --build app
- run: ./docker.sh --push app
- run: ./docker.sh --build prod
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@d43c1f16c00cfd3978dde6c07f4bbcf9eb6993ca
with:
Expand All @@ -71,10 +73,14 @@ jobs:
uses: github/codeql-action/upload-sarif@81b419c908d540ec4c7da9bfb4b5d941fca8f624
with:
sarif_file: "trivy-results.sarif"
- run: ./docker.sh --push app
- run: ./docker.sh --push prod
- id: prod_image_tag
run: echo "prod_image_tag=$(./docker.sh --prodImageTag)" >> $GITHUB_OUTPUT
outputs:
prod_image_tag: ${{ steps.prod_image_tag.outputs.prod_image_tag }}

deploy-staging:
needs: [build-push-app-image, get-content-file]
needs: [build-push-app-image]
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
environment: staging
Expand All @@ -91,7 +97,7 @@ jobs:
uses: digitalservicebund/github-actions/argocd-deploy@a223a68bc5982e5175beb73c708d99d8f9ba7858
with:
environment: staging
version: ${{ env.IMAGE_VERSION }}-${{ needs.get-content-file.outputs.content_checksum }}
version: ${{ needs.build-push-app-image.outputs.prod_image_tag }}
deploying_repo: a2j-rechtsantragstelle
infra_repo: a2j-rechtsantragstelle-infra
deploy_key: ${{ secrets.DEPLOY_KEY }}
Expand All @@ -101,7 +107,7 @@ jobs:
argocd_sync_timeout: 300

deploy-preview:
needs: [build-push-app-image, get-content-file]
needs: [build-push-app-image]
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
environment: preview
Expand All @@ -118,7 +124,7 @@ jobs:
uses: digitalservicebund/github-actions/argocd-deploy@a223a68bc5982e5175beb73c708d99d8f9ba7858
with:
environment: preview
version: ${{ env.IMAGE_VERSION }}-${{ needs.get-content-file.outputs.content_checksum }}
version: ${{ needs.build-push-app-image.outputs.prod_image_tag }}
deploying_repo: a2j-rechtsantragstelle
infra_repo: a2j-rechtsantragstelle-infra
deploy_key: ${{ secrets.DEPLOY_KEY }}
Expand All @@ -136,7 +142,7 @@ jobs:
USE_EXISTING_SERVER: true

deploy-production:
needs: [verify-preview-e2e, get-content-file]
needs: [verify-preview-e2e, build-push-app-image]
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
environment: production
Expand All @@ -153,7 +159,7 @@ jobs:
uses: digitalservicebund/github-actions/argocd-deploy@a223a68bc5982e5175beb73c708d99d8f9ba7858
with:
environment: production
version: ${{ env.IMAGE_VERSION }}-${{ needs.get-content-file.outputs.content_checksum }}
version: ${{ needs.build-push-app-image.outputs.prod_image_tag }}
deploying_repo: a2j-rechtsantragstelle
infra_repo: a2j-rechtsantragstelle-infra
deploy_key: ${{ secrets.DEPLOY_KEY }}
Expand Down
80 changes: 52 additions & 28 deletions docker.sh
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
#!/usr/bin/env bash
set -euo pipefail

HELP_TEXT="USAGE: --contentHash, --contentHashFromImage, --contentFromImage, --build [app/content], --push [app/content]"
HELP_TEXT="USAGE: ./docker.sh (--contentHash | --contentHashFromImage | --contentFromImage | --appFromImage | --prodImageTag | --build (app | content | prod) | --push (app | content | prod))"
REGISTRY=ghcr.io
IMAGE_NAME=digitalservicebund/a2j-rechtsantragstelle
APP_IMAGE=$REGISTRY/$IMAGE_NAME-app
CONTENT_IMAGE=$REGISTRY/$IMAGE_NAME-content
PROD_IMAGE=$REGISTRY/$IMAGE_NAME
DOCKERFILE=Dockerfile

if [ "$#" -eq 0 ]; then
echo "Missing action"
echo $HELP_TEXT
exit 1
fi

function parseValidTarget() {
if [ "$#" -le 1 ]; then
echo "Missing target, aborting..."
echo $HELP_TEXT
exit 1
fi
case $2 in
app | content) TARGET=$2 ;;
app | content | prod) TARGET=$2 ;;
*)
echo "Unknown target $2, aborting..."
echo $HELP_TEXT
Expand All @@ -39,12 +45,16 @@ function getAppFromLatestImage() {
function hashFromContentFile() {
echo $(sha256sum $1 | cut -d' ' -f1)
}
function getContentHashFromLatestImage() {
local tmp_content_file="./content.tmp"
getContentFromLatestImage $tmp_content_file
local content_hash=$(hashFromContentFile $tmp_content_file)
rm $tmp_content_file
echo $content_hash

function hashFromImage() {
docker image inspect "$1" &>/dev/null || docker pull "$1" --quiet
docker image inspect "$1" --format '{{ json .Config.Labels.hash }}' | tr -d '"'
}

function prodImageTag() {
CONTENT_HASH=$(hashFromImage $CONTENT_IMAGE)
APP_HASH=$(hashFromImage $APP_IMAGE)
echo "$APP_HASH-$CONTENT_HASH"
}

case $1 in
Expand All @@ -61,58 +71,72 @@ case $1 in
exit 0
;;
--contentHashFromImage)
getContentHashFromLatestImage
hashFromImage $CONTENT_IMAGE
exit 0
;;
--contentHash)
hashFromContentFile content.json
exit 0
;;
--prodImageTag)
prodImageTag
exit 0
;;
--build)
parseValidTarget "$@"

case ${TARGET} in
app)
LATEST_GIT_TAG=$(git rev-parse HEAD)
APP_IMAGE_TAG=$APP_IMAGE:$LATEST_GIT_TAG

npm run build
npm run build-storybook
echo "Building $APP_IMAGE..."
docker build -t $APP_IMAGE -f $DOCKERFILE --target app .
docker build -t $APP_IMAGE --label "hash=$LATEST_GIT_TAG" -f $DOCKERFILE --target app --quiet .

echo "Tagging latest app image as $APP_IMAGE_TAG"
docker tag $APP_IMAGE $APP_IMAGE_TAG
;;
content)
docker build -t $CONTENT_IMAGE -f $DOCKERFILE --target content .
CONTENT_HASH=$(hashFromContentFile content.json)
CONTENT_IMAGE_TAG=$CONTENT_IMAGE:$CONTENT_HASH

echo "Building $CONTENT_IMAGE..."
docker build -t $CONTENT_IMAGE --label "hash=$CONTENT_HASH" -f $DOCKERFILE --target content --quiet .

echo "Tagging latest content image as $CONTENT_IMAGE_TAG"
docker tag $CONTENT_IMAGE $CONTENT_IMAGE:$CONTENT_HASH
;;
prod)
echo -e "\nBuilding $PROD_IMAGE..."
docker build -t $PROD_IMAGE -f $DOCKERFILE --build-arg="APP_IMAGE=$APP_IMAGE" --build-arg="CONTENT_IMAGE=$CONTENT_IMAGE" --target prod --quiet .

PROD_IMAGE_TAG=$PROD_IMAGE:$(prodImageTag)
echo "Tagging latest prod image as $PROD_IMAGE_TAG"
docker tag $PROD_IMAGE "$PROD_IMAGE_TAG"
;;
esac

echo "Building $PROD_IMAGE..."
docker build -t $PROD_IMAGE -f $DOCKERFILE --build-arg="APP_IMAGE=$APP_IMAGE" --build-arg="CONTENT_IMAGE=$CONTENT_IMAGE" --target prod .
;;
--push)
parseValidTarget "$@"
LATEST_GIT_TAG=$(git rev-parse HEAD)

case ${TARGET} in
app)
CONTENT_HASH=$(getContentHashFromLatestImage)
APP_IMAGE_TAG=$APP_IMAGE:$LATEST_GIT_TAG
echo "Tagging and pushing $APP_IMAGE_TAG"
docker tag $APP_IMAGE $APP_IMAGE_TAG
echo "Pushing $APP_IMAGE..."
docker push --all-tags $APP_IMAGE
;;
content)
CONTENT_HASH=$(hashFromContentFile content.json)
CONTENT_IMAGE_TAG=$CONTENT_IMAGE:$CONTENT_HASH
echo "Tagging and pushing $CONTENT_IMAGE_TAG"
docker tag $CONTENT_IMAGE $CONTENT_IMAGE:$CONTENT_HASH
echo "Pushing $CONTENT_IMAGE..."
docker push --all-tags $CONTENT_IMAGE
;;
prod)
echo "Pushing $PROD_IMAGE..."
docker push --all-tags $PROD_IMAGE
;;
esac

PROD_IMAGE_TAG=$PROD_IMAGE:$LATEST_GIT_TAG-$CONTENT_HASH
echo "Tagging and pushing $PROD_IMAGE_TAG"
docker tag $PROD_IMAGE $PROD_IMAGE_TAG
docker push --all-tags $PROD_IMAGE
;;

*)
echo "Unknown command $1"
echo "$HELP_TEXT"
Expand Down

0 comments on commit 85ceead

Please sign in to comment.