From 9946901044b124ebb5b9b846bab1cb5c3361608e Mon Sep 17 00:00:00 2001 From: msukkari Date: Thu, 30 Jan 2025 10:23:47 -0800 Subject: [PATCH] add initial logic for staging environment --- .github/workflows/staging-ghcr-public.yml | 130 ++++++++++++++++++ Dockerfile | 1 + entrypoint.sh | 1 - packages/web/src/actions.ts | 4 +- .../web/src/app/api/(server)/repos/route.ts | 3 +- .../web/src/app/api/(server)/search/route.ts | 2 +- .../web/src/app/api/(server)/source/route.ts | 2 +- staging/fly.toml | 27 ++++ 8 files changed, 164 insertions(+), 6 deletions(-) create mode 100644 .github/workflows/staging-ghcr-public.yml create mode 100644 staging/fly.toml diff --git a/.github/workflows/staging-ghcr-public.yml b/.github/workflows/staging-ghcr-public.yml new file mode 100644 index 00000000..09b2d8e4 --- /dev/null +++ b/.github/workflows/staging-ghcr-public.yml @@ -0,0 +1,130 @@ + +name: Publish to ghcr (staging) + +on: + push: + branches: ["v3"] + +env: + REGISTRY_IMAGE: ghcr.io/sourcebot-dev/sourcebot + +jobs: + build: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + id-token: write + strategy: + matrix: + platform: + - linux/amd64 + - linux/arm64 + + steps: + - name: Prepare + run: | + platform=${{ matrix.platform }} + echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV + + - name: Checkout repository + uses: actions/checkout@v4 + with: + submodules: "true" + + - name: Extract Docker metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY_IMAGE }} + tags: staging + + - name: Install cosign + uses: sigstore/cosign-installer@v3.5.0 + with: + cosign-release: "v2.2.4" + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to GitHub Packages Docker Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build Docker image + id: build + uses: docker/build-push-action@v6 + with: + context: . + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max + platforms: ${{ matrix.platform }} + outputs: type=image,name=${{ env.REGISTRY_IMAGE }},push-by-digest=true,name-canonical=true,push=true + build-args: | + SOURCEBOT_VERSION=${{ github.ref_name }} + POSTHOG_PAPIK=${{ secrets.POSTHOG_PAPIK }} + + - name: Export digest + run: | + mkdir -p /tmp/digests + digest="${{ steps.build.outputs.digest }}" + touch "/tmp/digests/${digest#sha256:}" + + - name: Upload digest + uses: actions/upload-artifact@v4 + with: + name: digests-${{ env.PLATFORM_PAIR }} + path: /tmp/digests/* + if-no-files-found: error + retention-days: 1 + + - name: Sign the published Docker image + env: + TAGS: ${{ steps.meta.outputs.tags }} + DIGEST: ${{ steps.build.outputs.digest }} + run: echo "${TAGS}" | xargs -I {} cosign sign --yes {}@${DIGEST} + + merge: + runs-on: ubuntu-latest + permissions: + packages: write + needs: + - build + steps: + - name: Download digests + uses: actions/download-artifact@v4 + with: + path: /tmp/digests + pattern: digests-* + merge-multiple: true + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Extract Docker metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY_IMAGE }} + tags: staging + + - name: Login to GitHub Packages Docker Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Create manifest list and push + working-directory: /tmp/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 }} \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 4c9ff7a2..12874727 100644 --- a/Dockerfile +++ b/Dockerfile @@ -78,6 +78,7 @@ ENV CONFIG_PATH=$DATA_DIR/config.json ENV DATA_CACHE_DIR=$DATA_DIR/.sourcebot ENV DB_DATA_DIR=$DATA_CACHE_DIR/db ENV DB_NAME=sourcebot +ENV DATABASE_URL="postgresql://postgres@localhost:5432/sourcebot" ARG SOURCEBOT_VERSION=unknown ENV SOURCEBOT_VERSION=$SOURCEBOT_VERSION diff --git a/entrypoint.sh b/entrypoint.sh index b0883428..0d96a120 100644 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -198,7 +198,6 @@ else fi # Run a Database migration -export DATABASE_URL="postgresql://postgres@localhost:5432/$DB_NAME" echo -e "\e[34m[Info] Running database migration...\e[0m" yarn workspace @sourcebot/db prisma:migrate:prod diff --git a/packages/web/src/actions.ts b/packages/web/src/actions.ts index 64798d54..9eca5f0c 100644 --- a/packages/web/src/actions.ts +++ b/packages/web/src/actions.ts @@ -2,7 +2,7 @@ import Ajv from "ajv"; import { auth, getCurrentUserOrg } from "./auth"; -import { notAuthenticated, notFound, ServiceError, unexpectedError } from "@/lib/serviceError"; +import { notAuthenticated, notFound, ServiceError, unexpectedError, serviceErrorResponse } from "@/lib/serviceError"; import { prisma } from "@/prisma"; import { StatusCodes } from "http-status-codes"; import { ErrorCode } from "@/lib/errorCodes"; @@ -30,7 +30,7 @@ export const createSecret = async (key: string, value: string): Promise<{ succes iv: encrypted.iv, } }); - } catch (e) { + } catch { return unexpectedError(`Failed to create secret`); } diff --git a/packages/web/src/app/api/(server)/repos/route.ts b/packages/web/src/app/api/(server)/repos/route.ts index eac6d2e3..b8989a6c 100644 --- a/packages/web/src/app/api/(server)/repos/route.ts +++ b/packages/web/src/app/api/(server)/repos/route.ts @@ -3,11 +3,12 @@ import { listRepositories } from "@/lib/server/searchService"; import { getCurrentUserOrg } from "../../../../auth"; import { isServiceError } from "@/lib/utils"; +import { serviceErrorResponse } from "@/lib/serviceError"; export const GET = async () => { const orgId = await getCurrentUserOrg(); if (isServiceError(orgId)) { - return orgId; + return serviceErrorResponse(orgId); } const response = await listRepositories(orgId); diff --git a/packages/web/src/app/api/(server)/search/route.ts b/packages/web/src/app/api/(server)/search/route.ts index 7301fc9c..0c402bde 100644 --- a/packages/web/src/app/api/(server)/search/route.ts +++ b/packages/web/src/app/api/(server)/search/route.ts @@ -10,7 +10,7 @@ import { getCurrentUserOrg } from "../../../../auth"; export const POST = async (request: NextRequest) => { const orgId = await getCurrentUserOrg(); if (isServiceError(orgId)) { - return orgId; + return serviceErrorResponse(orgId); } console.log(`Searching for org ${orgId}`); diff --git a/packages/web/src/app/api/(server)/source/route.ts b/packages/web/src/app/api/(server)/source/route.ts index d171a6c4..89c5a8bb 100644 --- a/packages/web/src/app/api/(server)/source/route.ts +++ b/packages/web/src/app/api/(server)/source/route.ts @@ -10,7 +10,7 @@ import { getCurrentUserOrg } from "@/auth"; export const POST = async (request: NextRequest) => { const orgId = await getCurrentUserOrg(); if (isServiceError(orgId)) { - return orgId; + return serviceErrorResponse(orgId); } const body = await request.json(); diff --git a/staging/fly.toml b/staging/fly.toml new file mode 100644 index 00000000..b77572f0 --- /dev/null +++ b/staging/fly.toml @@ -0,0 +1,27 @@ +# fly.toml app configuration file generated for sourcebot-staging on 2025-01-29T15:57:18-08:00 +# +# See https://fly.io/docs/reference/configuration/ for information about how to use this file. +# + +app = 'sourcebot-staging' +primary_region = 'sea' + +[build] + image = 'sourcebot-staging' + +[[mounts]] + source = 'sourcebot_staging_data' + destination = '/data' + +[http_service] + internal_port = 3000 + force_https = true + auto_stop_machines = 'off' + auto_start_machines = false + min_machines_running = 0 + processes = ['app'] + +[[vm]] + memory = '1gb' + cpu_kind = 'shared' + cpus = 1