From dbce678914e5d8a6000c4511d9703a54a93f7be6 Mon Sep 17 00:00:00 2001 From: Shirou-kun Date: Sun, 10 Nov 2024 18:34:56 +0900 Subject: [PATCH] ft: add ci build to automate deployment --- .../composite/build-push-gcloud/action.yaml | 79 +++++++++++++++++++ .github/workflows/cd-build.yaml | 40 ++++++++++ backend.Dockerfile | 29 +++++++ frontend.Dockerfile | 21 +++++ frontend/src/generated/notes.client.ts | 3 +- frontend/src/generated/notes.ts | 3 +- frontend/tsconfig.app.tsbuildinfo | 2 +- frontend/tsconfig.node.tsbuildinfo | 2 +- proto-gen.sh | 11 +-- 9 files changed, 181 insertions(+), 9 deletions(-) create mode 100644 .github/composite/build-push-gcloud/action.yaml create mode 100644 .github/workflows/cd-build.yaml create mode 100644 backend.Dockerfile create mode 100644 frontend.Dockerfile diff --git a/.github/composite/build-push-gcloud/action.yaml b/.github/composite/build-push-gcloud/action.yaml new file mode 100644 index 00000000..27dd2ef3 --- /dev/null +++ b/.github/composite/build-push-gcloud/action.yaml @@ -0,0 +1,79 @@ +name: "Docker build & push to Artifact Registry" +description: "Builds the docker image and pushes it to Google Artifact Registry" +on: + workflow_call: + inputs: + repo: + description: "Repository name" + required: true + registry: + description: "Google Artifact registry" + required: false + default: "docker.pkg.dev" + dockerfile: + description: "Dockerfile path" + required: false + default: "Dockerfile" + context: + description: "Docker context" + required: false + default: "." + project_id: + description: "Google project ID" + required: true + google_key: + description: "Google service account key in BASE64" + required: true + outputs: + imageid: + description: "Image ID" + value: ${{ jobs.push.outputs.imageid }} + tag: + description: "Image tag" + value: ${{ jobs.push.outputs.tag }} +jobs: + push: + name: "Build & Push" + runs-on: ubuntu-latest + outputs: + imageid: + description: "Image ID" + value: ${{ steps.build.outputs.imageid }} + tag: + description: "Image tag" + value: ${{ steps.vars.outputs.branch }}-${{ steps.vars.outputs.sha_short }} + steps: + - name: Docker login to Google Cloud + id: vars + run: | + echo "$B64_GOOGLE_KEY" | docker login -u _json_key_base64 --password-stdin https://$REGISTRY + echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT + branch=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}} + echo "branch=$(echo "$branch" | tr '/\' '-')" >> $GITHUB_OUTPUT + shell: bash + env: + B64_GOOGLE_KEY: ${{ inputs.google_key }} + REGISTRY: ${{ inputs.registry }} +# - name: Check image +# id: image_exists +# continue-on-error: true +# uses: cloudposse/github-action-docker-image-exists@main +# with: +# registry: ${{ inputs.registry }} +# image_name: ${{ inputs.project_id }}/${{ inputs.repo }} +# tag: ${{ steps.vars.outputs.branch }}-${{ steps.vars.outputs.sha_short }} + - uses: docker/setup-buildx-action@v3 + if: steps.image_exists.outcome == 'failure' + - uses: docker/build-push-action@v5 +# if: steps.image_exists.outcome == 'failure' + id: build + with: + context: ${{ inputs.context }} + file: ${{ inputs.dockerfile }} +# cache-from: type=gha +# cache-to: type=gha,mode=max + push: true + labels: | + ci.run_id=${{ github.run_id }} + tags: | + ${{ inputs.registry }}/${{ inputs.project_id }}/${{ inputs.repo }}:${{ steps.vars.outputs.branch }}-${{ steps.vars.outputs.sha_short }} diff --git a/.github/workflows/cd-build.yaml b/.github/workflows/cd-build.yaml new file mode 100644 index 00000000..1f5988fc --- /dev/null +++ b/.github/workflows/cd-build.yaml @@ -0,0 +1,40 @@ +name: CD + +on: + push: + branches: + - main + tags: + - v* + +jobs: + push-backend: + name: Build backend + runs-on: ubuntu-latest + outputs: + version: ${{ steps.build.outputs.tag }} + steps: + - uses: actions/checkout@v4 + - uses: ../composite/build-push-gcloud/action.yaml + id: build + with: + google_key: ${{ secrets.GCLOUD_SECRET_KEY }} + repo: services/whisper-notes-backend + dockerfile: backend.Dockerfile + registry: europe-north1-docker.pkg.dev + project_id: ${{ secrets.GCLOUD_PROJECT }} + push-frontend: + name: Build frontend + runs-on: ubuntu-latest + outputs: + version: ${{ steps.build.outputs.tag }} + steps: + - uses: actions/checkout@v4 + - uses: ../composite/build-push-gcloud/action.yaml + id: build + with: + google_key: ${{ secrets.GCLOUD_SECRET_KEY }} + repo: services/whisper-notes-frontend + dockerfile: frontend.Dockerfile + registry: europe-north1-docker.pkg.dev + project_id: ${{ secrets.GCLOUD_PROJECT }} diff --git a/backend.Dockerfile b/backend.Dockerfile new file mode 100644 index 00000000..023e1b67 --- /dev/null +++ b/backend.Dockerfile @@ -0,0 +1,29 @@ +FROM node:23-alpine AS build + +WORKDIR /build +COPY backend . +COPY protos ./protos + +RUN yarn --frozen-lockfile + +RUN yarn proto-loader-gen-types \ + --grpcLib=@grpc/grpc-js \ + --outDir=./src/generated/ \ + ./protos/*.proto + +RUN yarn build + +FROM node:23-alpine AS app + +RUN apk add --no-cache tini + +WORKDIR /app +COPY --from=build /build/node_modules ./node_modules +COPY --from=build /build/dist ./dist +COPY --from=build /build/protos ./protos + +ENV PROTO_PATH="/app/protos" +EXPOSE 8080 + +ENTRYPOINT ["/sbin/tini", "--"] +CMD [ "node", "dist/server.js" ] diff --git a/frontend.Dockerfile b/frontend.Dockerfile new file mode 100644 index 00000000..3e7099d8 --- /dev/null +++ b/frontend.Dockerfile @@ -0,0 +1,21 @@ +FROM node:23-alpine AS build + +WORKDIR /build +COPY frontend . +COPY protos ./protos + +RUN yarn --frozen-lockfile + +RUN yarn protoc \ + --ts_out src/generated/ \ + --ts_opt long_type_string \ + --proto_path ./protos \ + --ts_opt ts_nocheck \ + ./protos/*.proto + +RUN yarn build + +FROM flashspys/nginx-static:latest AS app + +COPY --from=build /build/dist /static +EXPOSE 80 diff --git a/frontend/src/generated/notes.client.ts b/frontend/src/generated/notes.client.ts index 6165fe78..64527181 100644 --- a/frontend/src/generated/notes.client.ts +++ b/frontend/src/generated/notes.client.ts @@ -1,6 +1,7 @@ -// @generated by protobuf-ts 2.9.4 with parameter long_type_string +// @generated by protobuf-ts 2.9.4 with parameter long_type_string,ts_nocheck // @generated from protobuf file "notes.proto" (package "notes", syntax proto3) // tslint:disable +// @ts-nocheck import type { RpcTransport } from "@protobuf-ts/runtime-rpc"; import type { ServiceInfo } from "@protobuf-ts/runtime-rpc"; import { NoteService } from "./notes"; diff --git a/frontend/src/generated/notes.ts b/frontend/src/generated/notes.ts index ad67d206..2337e4d2 100644 --- a/frontend/src/generated/notes.ts +++ b/frontend/src/generated/notes.ts @@ -1,6 +1,7 @@ -// @generated by protobuf-ts 2.9.4 with parameter long_type_string +// @generated by protobuf-ts 2.9.4 with parameter long_type_string,ts_nocheck // @generated from protobuf file "notes.proto" (package "notes", syntax proto3) // tslint:disable +// @ts-nocheck import { ServiceType } from "@protobuf-ts/runtime-rpc"; import type { BinaryWriteOptions } from "@protobuf-ts/runtime"; import type { IBinaryWriter } from "@protobuf-ts/runtime"; diff --git a/frontend/tsconfig.app.tsbuildinfo b/frontend/tsconfig.app.tsbuildinfo index c8dd673e..405e3e37 100644 --- a/frontend/tsconfig.app.tsbuildinfo +++ b/frontend/tsconfig.app.tsbuildinfo @@ -1 +1 @@ -{"root":["./src/App.tsx","./src/index.tsx","./src/vite-env.d.ts","./src/components/AudioManager.tsx","./src/components/AudioPlayer.tsx","./src/components/AudioRecorder.tsx","./src/components/Progress.tsx","./src/components/TranscribeButton.tsx","./src/components/Transcript.tsx","./src/components/modal/Modal.tsx","./src/components/modal/UrlInput.tsx","./src/hooks/useTranscriber.ts","./src/hooks/useWorker.ts","./src/utils/AudioUtils.ts","./src/utils/BlobFix.ts","./src/utils/Constants.ts"],"errors":true,"version":"5.6.2"} \ No newline at end of file +{"root":["./src/app.tsx","./src/index.tsx","./src/vite-env.d.ts","./src/components/audiomanager.tsx","./src/components/audioplayer.tsx","./src/components/audiorecorder.tsx","./src/components/progress.tsx","./src/components/transcribebutton.tsx","./src/components/transcript.tsx","./src/components/modal/modal.tsx","./src/components/modal/urlinput.tsx","./src/generated/notes.client.ts","./src/generated/notes.ts","./src/hooks/usetranscriber.ts","./src/hooks/useworker.ts","./src/services/index.ts","./src/utils/audioutils.ts","./src/utils/blobfix.ts","./src/utils/constants.ts"],"version":"5.6.3"} \ No newline at end of file diff --git a/frontend/tsconfig.node.tsbuildinfo b/frontend/tsconfig.node.tsbuildinfo index 98ef2f99..75ea0011 100644 --- a/frontend/tsconfig.node.tsbuildinfo +++ b/frontend/tsconfig.node.tsbuildinfo @@ -1 +1 @@ -{"root":["./vite.config.ts"],"version":"5.6.2"} \ No newline at end of file +{"root":["./vite.config.ts"],"version":"5.6.3"} \ No newline at end of file diff --git a/proto-gen.sh b/proto-gen.sh index 5be101f8..1bf03fb4 100755 --- a/proto-gen.sh +++ b/proto-gen.sh @@ -3,11 +3,11 @@ SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) # Backend -# cd $SCRIPT_DIR/backend -# yarn proto-loader-gen-types \ -# --grpcLib=@grpc/grpc-js \ -# --outDir=./src/generated/ \ -# $SCRIPT_DIR/protos/*.proto +cd $SCRIPT_DIR/backend +yarn proto-loader-gen-types \ + --grpcLib=@grpc/grpc-js \ + --outDir=./src/generated/ \ + $SCRIPT_DIR/protos/*.proto echo "Backend stubs generated..." # Frontend @@ -22,5 +22,6 @@ npx protoc \ --ts_out src/generated/ \ --ts_opt long_type_string \ --proto_path $SCRIPT_DIR/protos \ + --ts_opt ts_nocheck \ $SCRIPT_DIR/protos/*.proto echo "Frontend Stubs generated..."