Skip to content

Commit

Permalink
poc for northflank
Browse files Browse the repository at this point in the history
  • Loading branch information
dcramer committed Jun 12, 2024
1 parent 99366fb commit d29f1e9
Show file tree
Hide file tree
Showing 2 changed files with 352 additions and 4 deletions.
348 changes: 348 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,348 @@
name: Build & Deploy
on:
push:
branches:
- main
- feat/northflank-deploy
workflow_dispatch:
inputs:
force:
description: "Force deploy to all services"
default: true
type: boolean
nocache:
description: "Do not rely on existing layer cache"
default: false
type: boolean
deploy:
description: "Deploy changes upon successful build"
default: true
type: boolean
env:
REGION: us-central1
PROJECT_ID: cask-382601
GOOGLE_CLIENT_ID: "721909483682-uk3befic1j1krv3drig2puu30v1i4v48.apps.googleusercontent.com"
SENTRY_DSN: "https://[email protected]/4505138086019073"
SENTRY_ORG: "peated"
SENTRY_PROJECT: "peated"
API_SERVER: https://api.peated.com
URL_PREFIX: https://peated.com
FATHOM_SITE_ID: "OGNPFEUC"

REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}

NF_CREDENTIALS_ID: github
NF_PROJECT_ID: default-project
jobs:
build:
name: 🚀 Build
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
runs-on: ubuntu-latest
permissions:
contents: "read"
id-token: "write"
if: ${{ inputs.deploy || github.event_name == 'push' }}
steps:
- name: ⬇️ Checkout repo
uses: actions/checkout@v3

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

- name: Log in to the Container registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Record Version
id: vars
run: echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT

- name: Verify CLI
id: verify_cli
run: |
if docker inspect "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:cli-${{ github.sha }}"; then
echo "image_exists=true" >> "$GITHUB_OUTPUT"
else
echo "image_exists=false" >> "$GITHUB_OUTPUT"
fi
- name: Verify Web
id: verify_web
run: |
if docker inspect "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:web-${{ github.sha }}"; then
echo "image_exists=true" >> "$GITHUB_OUTPUT"
else
echo "image_exists=false" >> "$GITHUB_OUTPUT"
fi
- name: Verify API
id: verify_api
run: |
if docker inspect "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:api-${{ github.sha }}"; then
echo "image_exists=true" >> "$GITHUB_OUTPUT"
else
echo "image_exists=false" >> "$GITHUB_OUTPUT"
fi
- name: Verify Worker
id: verify_worker
run: |
if docker inspect "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:worker-${{ github.sha }}"; then
echo "image_exists=true" >> "$GITHUB_OUTPUT"
else
echo "image_exists=false" >> "$GITHUB_OUTPUT"
fi
# optimize cache by building all stages
- name: Build All Stages
uses: docker/build-push-action@v5
if: |
steps.verify_web.outputs.image_exists == 'false'
|| steps.verify_api.outputs.image_exists == 'false'
|| steps.verify_worker.outputs.image_exists == 'false'
|| steps.verify_cli.outputs.image_exists == 'false'
with:
context: .
cache-from: type=gha,scope=prod
cache-to: type=gha,mode=max,scope=prod
no-cache: ${{ inputs.nocache || false }}
build-args: |
VERSION=${{ github.sha }}
API_SERVER=${{ env.API_SERVER }}
URL_PREFIX=${{ env.URL_PREFIX }}
GOOGLE_CLIENT_ID=${{ env.GOOGLE_CLIENT_ID }}
SENTRY_DSN=${{ env.SENTRY_DSN }}
SENTRY_ORG=${{ env.SENTRY_ORG }}
SENTRY_PROJECT=${{ env.SENTRY_PROJECT }}
FATHOM_SITE_ID=${{ env.FATHOM_SITE_ID }}
secrets: |
"SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }}"
- name: Build Web
uses: docker/build-push-action@v5
if: steps.verify_web.outputs.image_exists == 'false'
with:
context: .
cache-from: type=gha,scope=prod
no-cache: ${{ inputs.nocache || false }}
push: true
target: web
build-args: |
VERSION=${{ github.sha }}
API_SERVER=${{ env.API_SERVER }}
URL_PREFIX=${{ env.URL_PREFIX }}
GOOGLE_CLIENT_ID=${{ env.GOOGLE_CLIENT_ID }}
SENTRY_DSN=${{ env.SENTRY_DSN }}
SENTRY_ORG=${{ env.SENTRY_ORG }}
SENTRY_PROJECT=${{ env.SENTRY_PROJECT }}
FATHOM_SITE_ID=${{ env.FATHOM_SITE_ID }}
secrets: |
"SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }}"
tags: |
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:web-${{ github.sha }}
- name: Build Worker
uses: docker/build-push-action@v5
if: steps.verify_worker.outputs.image_exists == 'false'
with:
context: .
cache-from: type=gha,scope=prod
no-cache: ${{ inputs.nocache || false }}
push: true
target: worker
build-args: |
VERSION=${{ github.sha }}
API_SERVER={{ env.API_SERVER }}
URL_PREFIX=${{ env.URL_PREFIX }}
GOOGLE_CLIENT_ID=${{ env.GOOGLE_CLIENT_ID }}
SENTRY_DSN=${{ env.SENTRY_DSN }}
SENTRY_ORG=${{ env.SENTRY_ORG }}
SENTRY_PROJECT=${{ env.SENTRY_PROJECT }}
FATHOM_SITE_ID=${{ env.FATHOM_SITE_ID }}
secrets: |
"SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }}"
tags: |
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:worker-${{ github.sha }}
- name: Build CLI
uses: docker/build-push-action@v5
if: steps.verify_cli.outputs.image_exists == 'false'
with:
context: .
cache-from: type=gha,scope=prod
no-cache: ${{ inputs.nocache || false }}
push: true
target: cli
build-args: |
VERSION=${{ github.sha }}
API_SERVER={{ env.API_SERVER }}
URL_PREFIX=${{ env.URL_PREFIX }}
GOOGLE_CLIENT_ID=${{ env.GOOGLE_CLIENT_ID }}
SENTRY_DSN=${{ env.SENTRY_DSN }}
SENTRY_ORG=${{ env.SENTRY_ORG }}
SENTRY_PROJECT=${{ env.SENTRY_PROJECT }}
FATHOM_SITE_ID=${{ env.FATHOM_SITE_ID }}
secrets: |
"SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }}"
tags: |
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:cli-${{ github.sha }}
- name: Build API
uses: docker/build-push-action@v5
if: steps.verify_api.outputs.image_exists == 'false'
with:
context: .
cache-from: type=gha,scope=prod
no-cache: ${{ inputs.nocache || false }}
push: true
target: api
build-args: |
VERSION=${{ github.sha }}
API_SERVER=${{ env.API_SERVER }}
URL_PREFIX=${{ env.URL_PREFIX }}
GOOGLE_CLIENT_ID=${{ env.GOOGLE_CLIENT_ID }}
SENTRY_DSN=${{ env.SENTRY_DSN }}
SENTRY_ORG=${{ env.SENTRY_ORG }}
SENTRY_PROJECT=${{ env.SENTRY_PROJECT }}
FATHOM_SITE_ID=${{ env.FATHOM_SITE_ID }}
secrets: |
"SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }}"
tags: |
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:api-${{ github.sha }}
deploy:
name: 🚀 Deploy
concurrency:
group: ${{ github.workflow }}
runs-on: ubuntu-latest
needs: [build]
permissions:
contents: "read"
id-token: "write"
deployments: "write"
steps:
- uses: chrnorm/deployment-action@v2
name: Create GitHub deployment
id: deployment
with:
token: "${{ github.token }}"
environment-url: https://peated.app
environment: production
initial-status: in_progress

- name: ⬇️ Checkout repo
uses: actions/checkout@v3

- name: Record Version
id: vars
run: echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT

- name: Get changed files
id: changed-files-yaml
uses: tj-actions/changed-files@v41
with:
files_yaml: |
server:
- apps/server/**
cli:
- apps/cli/**
web:
- apps/web/**
common:
- packages/**
- apps/server**
- Dockerfile
- package.json
- .github/workflows/deploy.yml
migrations:
- apps/**/migrations/*.sql
- packages/**/migrations/*.sql
- .github/workflows/deploy.yml
- name: Update Migrate DB
uses: northflank/deploy-to-northflank@v1
with:
northflank-api-key: ${{ secrets.NORTHFLANK_API_KEY }}
project-id: ${{ env.NF_PROJECT_ID }}
service-id: migrate-db
image-path: cli-${{ steps.meta.outputs.tags }}
credentials-id: ${{ env.NF_CREDENTIALS_ID }}

# - name: Run Migrate DB
# if: ${{ inputs.force || steps.changed-files-yaml.outputs.migrations_any_changed == 'true' }}
# run: |-
# gcloud run jobs execute cli \
# --region ${{ env.REGION }} \
# --args db,migrate \
# --wait

- name: Deploy API
if: ${{ inputs.force || steps.changed-files-yaml.outputs.server_any_changed == 'true' || steps.changed-files-yaml.outputs.common_any_changed == 'true' }}
uses: northflank/deploy-to-northflank@v1
with:
northflank-api-key: ${{ secrets.NORTHFLANK_API_KEY }}
project-id: ${{ env.NF_PROJECT_ID }}
service-id: api
image-path: api-${{ steps.meta.outputs.tags }}
credentials-id: ${{ env.NF_CREDENTIALS_ID }}

- name: Deploy Web
if: ${{ inputs.force || steps.changed-files-yaml.outputs.web_any_changed == 'true' || steps.changed-files-yaml.outputs.common_any_changed == 'true' }}
uses: northflank/deploy-to-northflank@v1
with:
northflank-api-key: ${{ secrets.NORTHFLANK_API_KEY }}
project-id: ${{ env.NF_PROJECT_ID }}
service-id: web
image-path: web-${{ steps.meta.outputs.tags }}
credentials-id: ${{ env.NF_CREDENTIALS_ID }}

- name: Deploy Worker
if: ${{ inputs.force || steps.changed-files-yaml.outputs.worker_any_changed == 'true' || steps.changed-files-yaml.outputs.common_any_changed == 'true' }}
uses: northflank/deploy-to-northflank@v1
with:
northflank-api-key: ${{ secrets.NORTHFLANK_API_KEY }}
project-id: ${{ env.NF_PROJECT_ID }}
service-id: worker
image-path: worker-${{ steps.meta.outputs.tags }}
credentials-id: ${{ env.NF_CREDENTIALS_ID }}

- name: Discord notification (success)
if: success()
env:
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
uses: Ilshidur/[email protected]
with:
args: |
"${{ github.actor }} deployed version [${{ steps.vars.outputs.sha_short }}](https://github.com/{{ EVENT_PAYLOAD.repository.full_name }}/commit/${{ github.sha }})."
- name: Discord notification (failure)
if: failure()
env:
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
uses: Ilshidur/[email protected]
with:
args: |
"ERROR: Failed to deploy version [${{ steps.vars.outputs.sha_short }}](https://github.com/{{ EVENT_PAYLOAD.repository.full_name }}/commit/${{ github.sha }})."
- name: Update deployment status (success)
if: success()
uses: chrnorm/deployment-status@v2
with:
token: "${{ github.token }}"
environment-url: ${{ steps.deployment.outputs.environment_url }}
deployment-id: ${{ steps.deployment.outputs.deployment_id }}
state: "success"

- name: Update deployment status (failure)
if: failure()
uses: chrnorm/deployment-status@v2
with:
token: "${{ github.token }}"
environment-url: ${{ steps.deployment.outputs.environment_url }}
deployment-id: ${{ steps.deployment.outputs.deployment_id }}
state: "failure"
8 changes: 4 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,14 @@ ADD . .
ARG VERSION
ARG SENTRY_PROJECT
ARG SENTRY_ORG
ARG SENTRY_AUTH_TOKEN
ENV VERSION=$VERSION \
SENTRY_RELEASE=$VERSION \
SENTRY_ORG=$SENTRY_ORG \
SENTRY_PROJECT=$SENTRY_PROJECT \
SENTRY_AUTH_TOKEN=$SENTRY_AUTH_TOKEN
SENTRY_PROJECT=$SENTRY_PROJECT

RUN pnpm build
RUN --mount=type=secret,id=SENTRY_AUTH_TOKEN \
SENTRY_AUTH_TOKEN="$(cat /run/secrets/SENTRY_AUTH_TOKEN)" \
pnpm build

# web service
FROM base-env as web
Expand Down

0 comments on commit d29f1e9

Please sign in to comment.