Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: production ready docker build with ci workflow #13541

Draft
wants to merge 37 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
5e2cd6f
updated nextconfig and package.json
Feb 5, 2024
dd1cfea
added web dockerfile
Feb 5, 2024
f05767c
adjusted docker variables
Feb 5, 2024
bb680e8
added ci workflow
Feb 5, 2024
c66e12b
add opionated next build output
Feb 8, 2024
c6281b5
Merge branch 'main' into feat
keithwillcode Feb 8, 2024
191a47d
Merge branch 'main' into feat
zomars Feb 8, 2024
cc59283
try fixing eslint error
Feb 8, 2024
62f0b12
Merge branch 'main' into feat
keithwillcode May 9, 2024
06bc46e
Merge branch 'main' into feat
PeerRich May 21, 2024
3fdf8d0
fix: update docker env variables
May 21, 2024
8ca77d8
fix: change yarn run test to yarn test in dockerfile
May 21, 2024
080ef8f
fix: change yarn run test to yarn test in dockerfile
May 21, 2024
ead9398
fix: add database direct url to compose integration test
May 21, 2024
f4ff6e5
fix: fix and bump trivy version
May 21, 2024
1ae914c
feat: add workflow to automatically update compose and remote k8s man…
May 21, 2024
afff09f
fix: update workflow
May 21, 2024
3d7e429
fix: update workflow
May 21, 2024
75cf69d
fix: update workflow
May 21, 2024
01cc7f1
fix:
May 21, 2024
45ec1d7
Tag kubernetes manifest and update compose
May 23, 2024
e38a002
Tag kubernetes manifest and update compose
May 23, 2024
f9f8793
Merge branch 'calcom:main' into feat
ChichiCaleb May 23, 2024
5afc2a8
.
May 23, 2024
570f474
workflow update
May 23, 2024
8e5e9a9
Merge branch 'calcom:main' into feat
ChichiCaleb May 23, 2024
8e997c0
update pull_request to pull_request_targert
May 27, 2024
6a24cec
Merge branch 'calcom:main' into feat
ChichiCaleb May 27, 2024
3a5315e
split workflow
May 31, 2024
eb1f89b
Merge branch 'main' into feat
ChichiCaleb May 31, 2024
0fcb71f
split workflow
May 31, 2024
c3f4456
update workflow
May 31, 2024
edbe8fc
fix package.json
May 31, 2024
796e651
Merge branch 'main' into feat
ChichiCaleb Jul 18, 2024
ca2c3b3
Merge branch 'main' into feat
PeerRich Jul 22, 2024
f527954
consolidate workflow into docker-ci
Jul 22, 2024
ed817da
update workflow name
Jul 22, 2024
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
391 changes: 391 additions & 0 deletions .github/workflows/docker-ci
Original file line number Diff line number Diff line change
@@ -0,0 +1,391 @@
---
name: Docker CI

on:
push:
branches:
- main

pull_request:
branches:
- main
types: [opened, synchronize, reopened]

pull_request_target:
branches:
- main
types: [opened, synchronize, reopened]

workflow_dispatch:


jobs:
# # FIRST JOB #######################################################################
# builds a test image and push to GHCR which will subequently be pulled by integration-test
# and trivy scan jobs for their respective actions
build-test-image:
name: Build Image for Testing
runs-on: ubuntu-latest
permissions:
contents: write
packages: write

steps:
- name: Set up QEMU
uses: docker/setup-qemu-action@v3

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

- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Login to ghcr.io registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}


- name: Extract metadata for the Docker image
id: docker_meta
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ github.repository }}
tags: |
${{ github.run_id }}

- name: Build and Push to GHCR
uses: docker/build-push-action@v5
with:
file: infra/docker/web/Dockerfile
push: true
tags: ${{ steps.docker_meta.outputs.tags }}
cache-to: |
type=gha,scope=main-base,mode=max
cache-from: |
type=gha,scope=main-base
platforms: linux/amd64


# # # # # NEXT JOB #######################################################################
# builds and runs unit test specified in the repo by targeting unit-test layer of multistage docker build
# however uses the cache from test image to increase speed
unit-test:
name: unit test in docker
needs: [build-test-image]
runs-on: ubuntu-latest
permissions:
packages: read
contents: read

steps:
- name: Set up QEMU
uses: docker/setup-qemu-action@v3

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

- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Login to ghcr.io registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}


- name: Build and unit-test
uses: docker/build-push-action@v5
with:
file: infra/docker/web/Dockerfile
target: unit-test
push: false
cache-to: |
type=gha,scope=main-test,mode=max
cache-from: |
type=gha,scope=main-base
type=gha,scope=main-test
platforms: linux/amd64


# # # # # NEXT JOB #######################################################################
# pulls test image from GHCR and run integration test in docker compose testing ability of the built app
# to succesfully connect to postgres db
integration-test:
name: Integration test in Compose
needs: [build-test-image]
runs-on: ubuntu-latest
permissions:
packages: read
contents: read

steps:
- name: checkout
uses: actions/checkout@v4

- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Login to ghcr.io registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}


- name: Downcase repo name
run: |
echo "REPO=${GITHUB_REPOSITORY,,}" >>${GITHUB_ENV}

- name: Test healthcheck in Docker Compose
run: |
export TESTING_IMAGE=ghcr.io/${REPO}:"$GITHUB_RUN_ID"
echo Testing image: "$TESTING_IMAGE"

docker compose -f ./infra/docker/web/integration-test/compose.yml up -d calcom

echo "Waiting for the server to be healthy..."
sleep 60s

curl --fail http://localhost:3000 || exit 1


# # # # # NEXT JOB #######################################################################
# pulls test image from GHCR and run a trivy vulnerability scan for high and crtical CVEs (non-blocking)
# and uploads the sarif result to github security tab
scan-image:
name: Scan Image with Trivy
needs: [build-test-image]
runs-on: ubuntu-latest

permissions:
contents: read
packages: read
security-events: write # for github/codeql-action/upload-sarif to upload SARIF results

steps:
- name: checkout
uses: actions/checkout@v4

- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Login to ghcr.io registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}


- name: Downcase repo name
run: |
echo "REPO=${GITHUB_REPOSITORY,,}" >>${GITHUB_ENV}


- name: Run Trivy for HIGH,CRITICAL CVEs and report (non-blocking)
uses: aquasecurity/[email protected]
with:
image-ref: ghcr.io/${{env.REPO}}:${{ github.run_id }}
format: sarif # table, json, sarif
exit-code: 0 # 1 or 0. 0 means don't fail the job if issues are found
ignore-unfixed: true # Ignore unpatched/unfixed vulnerabilities
vuln-type: 'os,library'
severity: 'HIGH,CRITICAL' # UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL
timeout: 10m0s
output: 'trivy-results.sarif'
env:
TRIVY_USERNAME: ${{ github.repository_owner }}
TRIVY_PASSWORD: ${{ secrets.GITHUB_TOKEN }}

- name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: 'trivy-results.sarif'

# NEXT JOB #######################################################################
# generates changelog.MD or add to an existing one and create releases using conventional commits.
# creates prelease when a pull request is made to main branch if a succesful test image
# was built, with succesful unit and integration test.
# creates a release when a merge is made to the main branch
# and adds either the prelease or released version to github output
# to be used by final image published to docker hub
changelog:
name: automated changelog using conventional commit
needs: [build-test-image, unit-test, integration-test, scan-image]
runs-on: ubuntu-latest
outputs:
TAG: ${{ steps.docker_tag.outputs.TAG }}
permissions:
contents: write


steps:
- name: check out the repository with all releases
uses: actions/checkout@v4
with:
# fetch-depth: 0
persist-credentials: 'false'
ref: ${{github.event.repository.default_branch}}



- name: conventional Changelog Action
id: changelog
uses: TriPSs/[email protected]
with:
github-token: ${{ secrets.RELEASE_MAIN }}
version-file: "./apps/web/package.json"
git-branch: ${{github.event.repository.default_branch}}
preset: "conventionalcommits"
input-file: "./apps/web/CHANGELOG.md"
output-file: "./apps/web/CHANGELOG.md"
tag-prefix: "v"
pre-release: "${{github.event_name == 'pull_request'}} || ${{github.event_name == 'pull_request_target'}}"
pre-release-identifier: "alpha"
skip-on-empty: 'false'
# release-count: 20
skip-git-pull: true

- name: Create Release
uses: actions/create-release@v1
if: ${{ steps.changelog.outputs.skipped == 'false' }}
env:
GITHUB_TOKEN: ${{ secrets.RELEASE_MAIN }}
with:
tag_name: ${{ steps.changelog.outputs.tag }}
release_name: ${{ steps.changelog.outputs.tag }}
body: ${{ steps.changelog.outputs.clean_changelog }}

- name: export tag for final build
id: docker_tag
run: |
echo "TAG=${{ steps.changelog.outputs.tag }}" >> $GITHUB_OUTPUT


# NEXT JOB #######################################################################
# builds the final image and adds latest tag and image:V*.*.* semantic versioning tag to merge request
# and image:v*.*.*-alpha.* tag to pull requests made to main branch before pushing to dockerhub
build-final-image:
name: Build Final Image
needs: [unit-test, integration-test, scan-image,changelog]
runs-on: ubuntu-latest

permissions:
contents: write
packages: write
pull-requests: write # needed to create and update comments in PRs

steps:
- name: Set up QEMU
uses: docker/setup-qemu-action@v3

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

- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Login to ghcr.io registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Docker Metadata for Final Image Build
id: docker_meta
uses: docker/metadata-action@v5
with:
images: ${{ secrets.DOCKERHUB_USERNAME }}/cal.com
flavor: |
latest=false
tags: |
type=raw,value=latest,enable=${{ endsWith(github.ref, github.event.repository.default_branch) }}
type=raw,value=${{needs.changelog.outputs.TAG}}

- name: Docker Build and Push to Docker Hub
uses: docker/build-push-action@v5
with:
file: infra/docker/web/Dockerfile
push: true
tags: |
${{ steps.docker_meta.outputs.tags }} ,
labels: ${{ steps.docker_meta.outputs.labels }}
cache-from: |
type=gha,scope=main-base
platforms: linux/amd64



# NEXT JOB #######################################################################
#update docker compose image tag

update-compose:
name: Tag kubernetes manifest and update compose
needs: [unit-test, integration-test, scan-image,changelog,build-final-image]
runs-on: ubuntu-latest
permissions:
contents: write

steps:


- name: Checkout repository
uses: actions/checkout@v4
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
with:
persist-credentials: false
fetch-depth: 0
ref: ${{ github.ref }}

- name: Update compose manifest
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
run: |
yq --inplace ".services.calcom.image = \"${{ secrets.DOCKERHUB_USERNAME }}/calcom:${{ needs.changelog.outputs.TAG }}\"" infra/docker/web/docker-compose.yaml

- name: Configure git
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
run: |
git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]"

- name: Commit changes
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
run: |
git add .
git commit -m "Release ${{ needs.changelog.outputs.TAG }} [skip ci]"

- name: Push changes
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
uses: ad-m/github-push-action@master
with:
github_token: ${{ secrets.RELEASE_MAIN }}
branch: ${{ github.ref }}






Loading
Loading