Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
**/.classpath
**/.dockerignore
**/.env
**/.git
**/.gitignore
Expand All @@ -21,4 +22,43 @@
**/secrets.dev.yaml
**/values.dev.yaml
LICENSE
README.md
!**/.gitignore
!.git/HEAD
!.git/config
!.git/packed-refs
!.git/refs/heads/**

# we don't need tests and their related code in production
**/*Tests.cs
**/*TestsRelated.cs

**/bin/*
**/obj/*
**/.vs/*
**/.vscode/*
**.user
**.http

**/appsettings.**
# need to include these files for tests execution in docker compose even though these maigh not be used in prod
!**/appsettings.json
!**/appsettings.MockForPullRequest.json

**/Dockerfile
**/lib/*

.devcontainer/
.github/
target/
ci/
e2e/

.dockerignore
.editorconfig
.gitattributes
.gitignore
docker-compose.yml
LICENSE
pgAdmin.json
README.md
180 changes: 180 additions & 0 deletions .github/workflows/.reusable-docker-build-and-push.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
name: Publish Docker image

# !!! NEVER add on push when there is on workflow_call
# if you do that the workflow can run multiple times
# for instance if you re-use this docker build workflow for prod deployment and for local-env in PR
# it will build the docker image it twice
# if you build => deploy => run e2e against prod it will build the image 3 times!
on:
# to allow to wait for a docker image to be published to proceed in another workflow
workflow_call:

jobs:
build-amd64:
runs-on: ubuntu-24.04
steps:
- name: Check out the repo
uses: actions/checkout@v4

# this is needed to address this issue according to the comment https://github.com/devcontainers/ci/issues/271#issuecomment-2301764487
# otherwise our TourmalineCore org name cannot be used in docker image names, only tourmalinecore
- name: Add Registry Image Env Var With Lowercase Organization and Repo Name
run: |
echo "REGISTRY_IMAGE=ghcr.io/${GITHUB_REPOSITORY,,}" >>${GITHUB_ENV}
- name: Prepare
run: |
platform=linux/amd64
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY_IMAGE }}

- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Build and push by digest
id: build
uses: docker/build-push-action@v6
with:
platforms: linux/amd64
context: .
file: ./Api/Dockerfile
build-args: |
EXCLUDE_UNIT_TESTS_FROM_BUILD=true
labels: ${{ steps.meta.outputs.labels }}
tags: ${{ env.REGISTRY_IMAGE }}
outputs: type=image,push-by-digest=true,name-canonical=true,push=true

- name: Export digest
run: |
mkdir -p ${{ runner.temp }}/digests
digest="${{ steps.build.outputs.digest }}"
touch "${{ runner.temp }}/digests/${digest#sha256:}"
- name: Upload digest
uses: actions/upload-artifact@v4
with:
name: digests-${{ env.PLATFORM_PAIR }}
path: ${{ runner.temp }}/digests/*
if-no-files-found: error
retention-days: 1

build-arm64:
runs-on: ubuntu-24.04-arm
steps:
- name: Check out the repo
uses: actions/checkout@v4

# this is needed to address this issue according to the comment https://github.com/devcontainers/ci/issues/271#issuecomment-2301764487
# otherwise our TourmalineCore org name cannot be used in docker image names, only tourmalinecore
- name: Add Registry Image Env Var With Lowercase Organization and Repo Name
run: |
echo "REGISTRY_IMAGE=ghcr.io/${GITHUB_REPOSITORY,,}" >>${GITHUB_ENV}
- name: Prepare
run: |
platform=linux/arm64
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY_IMAGE }}

- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Build and push by digest
id: build
uses: docker/build-push-action@v6
with:
platforms: linux/arm64
context: .
file: ./Api/Dockerfile
build-args: |
EXCLUDE_UNIT_TESTS_FROM_BUILD=true
labels: ${{ steps.meta.outputs.labels }}
tags: ${{ env.REGISTRY_IMAGE }}
outputs: type=image,push-by-digest=true,name-canonical=true,push=true

- name: Export digest
run: |
mkdir -p ${{ runner.temp }}/digests
digest="${{ steps.build.outputs.digest }}"
touch "${{ runner.temp }}/digests/${digest#sha256:}"
- name: Upload digest
uses: actions/upload-artifact@v4
with:
name: digests-${{ env.PLATFORM_PAIR }}
path: ${{ runner.temp }}/digests/*
if-no-files-found: error
retention-days: 1
merge:
runs-on: ubuntu-24.04
needs:
- build-amd64
- build-arm64
steps:
# this is needed to address this issue according to the comment https://github.com/devcontainers/ci/issues/271#issuecomment-2301764487
# otherwise our TourmalineCore org name cannot be used in docker image names, only tourmalinecore
- name: Add Registry Image Env Var With Lowercase Organization and Repo Name
run: |
echo "REGISTRY_IMAGE=ghcr.io/${GITHUB_REPOSITORY,,}" >>${GITHUB_ENV}
- name: Download digests
uses: actions/download-artifact@v4
with:
path: ${{ runner.temp }}/digests
pattern: digests-*
merge-multiple: true

- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY_IMAGE }}
tags: |
# minimal (short sha)
type=sha
# full length sha
type=sha,format=long
# set latest tag for default branch
# https://github.com/docker/metadata-action/issues/171 explains how to tag latest only on default branch
type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', github.event.repository.default_branch) }}
env:
# https://github.com/docker/metadata-action/issues/283
# without this flag it won't tag the image using the commit SHA
# for non push events like pull_request ones it requires this :(
DOCKER_METADATA_PR_HEAD_SHA: true

- name: Create manifest list and push
working-directory: ${{ runner.temp }}/digests
run: |
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
$(printf '${{ env.REGISTRY_IMAGE }}@sha256:%s ' *)
- name: Inspect image
run: |
docker buildx imagetools inspect ${{ env.REGISTRY_IMAGE }}:${{ steps.meta.outputs.version }}
32 changes: 32 additions & 0 deletions .github/workflows/.reusable-e2e-tests-against-prod.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: E2E Tests Against Prod

on:
workflow_call:

jobs:
e2e-test-against-prod:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4

- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'

- name: Download Karate JAR
run: |
curl -L https://github.com/karatelabs/karate/releases/download/v1.5.1/karate-1.5.1.jar -o karate.jar

- name: Run E2E Tests Against Local Env
run: |
# Learn more about '> /dev/null 2>&1': https://stackoverflow.com/a/42919998
# In essence it merges output and error streams and doesn't show errors in the terminal to avoid leakage of secrets in the pipeline
java -jar karate.jar . > /dev/null 2>&1
env:
"AUTH_FIRST_TENANT_LOGIN_WITH_ALL_PERMISSIONS": ${{ secrets.INNER_CIRCLE_PROD_AUTH_FIRST_TENANT_LOGIN_WITH_ALL_PERMISSIONS }}
"AUTH_FIRST_TENANT_PASSWORD_WITH_ALL_PERMISSIONS": ${{ secrets.INNER_CIRCLE_PROD_AUTH_FIRST_TENANT_PASSWORD_WITH_ALL_PERMISSIONS }}
"AUTH_API_ROOT_URL": ${{ secrets.INNER_CIRCLE_PROD_AUTH_API_ROOT_URL }}
"API_ROOT_URL": ${{ secrets.INNER_CIRCLE_PROD_ACCOUNTS_API_ROOT_URL }}
"SHOULD_USE_FAKE_EXTERNAL_DEPENDENCIES": "false"
45 changes: 45 additions & 0 deletions .github/workflows/deploy-to-prod-from-default.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: Deploy to Prod

on:
push:
branches:
- master

jobs:
docker-build-and-push:
uses: ./.github/workflows/.reusable-docker-build-and-push.yml

deploy-to-prod:
needs: [docker-build-and-push]
runs-on: ubuntu-24.04
steps:
- name: Check out the repo
uses: actions/checkout@v4

- name: Create default global .kube/config file
run: |
cd $HOME
mkdir .kube
echo "${{ secrets.INNER_CIRCLE_PROD_KUBECONFIG }}" > .kube/config

- name: Deploy
uses: helmfile/helmfile-action@v1.9.0
with:
helmfile-version: 'v0.164.0'
helm-version: 'v3.18.0'
helmfile-args: >
apply --suppress-diff --namespace ${{ secrets.INNER_CIRCLE_PROD_NAMESPACE }} -f Api/ci/helmfile.yaml
--state-values-set image.tag=sha-${{ github.sha }}
--state-values-set ingress.hostname=${{ secrets.INNER_CIRCLE_PROD_HOSTNAME }}
--state-values-set extraSecretEnvVars.ConnectionStrings__DefaultConnection=${{ secrets.INNER_CIRCLE_PROD_ACCOUNTS_DB_CONNECTION_STRING }}
--state-values-set extraSecretEnvVars.AuthenticationOptions__PublicSigningKey=${{ secrets.INNER_CIRCLE_PROD_PUBLIC_SIGNING_KEY }}
--state-values-set extraSecretEnvVars.HttpUrls__AuthServiceUrl=${{ secrets.INNER_CIRCLE_PROD_AUTH_SERVICE_URL }}
--state-values-set extraSecretEnvVars.HttpUrls__EmployeesServiceUrl=${{ secrets.INNER_CIRCLE_PROD_EMPLOYEES_SERVICE_URL }}
--state-values-set extraSecretEnvVars.AccountValidationOptions__CorporateEmailDomain=${{ secrets.INNER_CIRCLE_PROD_CORPORATE_EMAIL_DOMAIN }}
--state-values-set extraSecretEnvVars.AccountValidationOptions__IgnoreCorporateDomainValidationRule=${{ secrets.INNER_CIRCLE_PROD_IGNORE_CORPORATE_DOMAIN_VALIDATION_RULE }}
helmfile-auto-init: "false"

run-e2e-tests:
uses: ./.github/workflows/.reusable-e2e-tests-against-prod.yml
needs: [deploy-to-prod]
secrets: inherit
Loading