-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
352 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters