From 831b85191ef0a0cf172f42c262f9f6f8c90ade00 Mon Sep 17 00:00:00 2001 From: Dyakov Roman Date: Sat, 26 Aug 2023 17:13:31 +0300 Subject: [PATCH] CI/CD (#2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Изменения Добавил раскатку в тест/препрод/прод --- .github/workflows/main_commit.yml | 119 ++++++++++++++++++++++ .github/workflows/main_release.yml | 152 +++++++++++++++++++++++++++++ .github/workflows/pr_close.yml | 24 +++++ .github/workflows/pr_create.yml | 112 +++++++++++++++++++++ deployment/Dockerfile | 23 +++++ deployment/docker_entrypoint.sh | 11 +++ deployment/nginx.conf | 31 ++++++ index.html | 2 +- package.json | 4 +- 9 files changed, 475 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/main_commit.yml create mode 100644 .github/workflows/main_release.yml create mode 100644 .github/workflows/pr_close.yml create mode 100644 .github/workflows/pr_create.yml create mode 100644 deployment/Dockerfile create mode 100644 deployment/docker_entrypoint.sh create mode 100644 deployment/nginx.conf diff --git a/.github/workflows/main_commit.yml b/.github/workflows/main_commit.yml new file mode 100644 index 0000000..ba4b12d --- /dev/null +++ b/.github/workflows/main_commit.yml @@ -0,0 +1,119 @@ +name: Тесты и раскатка в тестовую среду + +on: + push: + branches: ['main'] + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +jobs: + test-style: + name: Проверяем стили + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@master + + - uses: pnpm/action-setup@v2 + with: + version: 7.26.3 + + - uses: actions/setup-node@v3 + with: + node-version: '18' + cache: 'pnpm' + + - name: Install + run: pnpm install + + - name: Check + run: pnpm lint && pnpm stylelint + + # test: + # name: Выполняем тесты + # runs-on: ubuntu-latest + # steps: + # - name: Checkout repository + # uses: actions/checkout@master + + # - uses: pnpm/action-setup@v2 + # with: + # version: 7.26.3 + + # - uses: actions/setup-node@v3 + # with: + # node-version: '18' + # cache: 'pnpm' + + # - name: Install + # run: pnpm install + + # - name: Check + # run: pnpm test + + build-test-image: + name: Собираем тестовый Docker + runs-on: ubuntu-latest + needs: + # - test + - test-style + permissions: + contents: read + packages: write + + steps: + - name: Checkout repository + uses: actions/checkout@master + + - name: Log in to the Container registry + uses: docker/login-action@v2 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@v4 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=raw,value=test,enable=true + + - name: Build and push Docker image + uses: docker/build-push-action@v4 + with: + file: ./deployment/Dockerfile + context: . + push: true + build-args: | + BUILD_MODE=testing + LAUNCH_MODE=testing + APP_VERSION=${{ github.ref_name }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + + deploy-test: + name: Раскатываем тестовый Docker + runs-on: [self-hosted, Linux] + needs: build-test-image + environment: + name: Testing + url: https://app.test.profcomff.com/ + env: + CONTAINER_NAME: com_profcomff_ui_floormap_test + permissions: + packages: read + steps: + - name: Run docker container + run: | + docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:test + docker stop ${{ env.CONTAINER_NAME }} || true && docker rm ${{ env.CONTAINER_NAME }} || true + docker run \ + --detach \ + --restart on-failure:3 \ + --network=web \ + --name ${{ env.CONTAINER_NAME }} \ + ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:test diff --git a/.github/workflows/main_release.yml b/.github/workflows/main_release.yml new file mode 100644 index 0000000..30fd4ff --- /dev/null +++ b/.github/workflows/main_release.yml @@ -0,0 +1,152 @@ +name: Тесты и раскатка в продакшн + +on: + push: + tags: + - 'v*' + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +jobs: + build-preprod-image: + name: Собираем pre-prod Docker + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Checkout repository + uses: actions/checkout@master + + - name: Log in to the Container registry + uses: docker/login-action@v2 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Define preprod metadata + id: meta-preprod + uses: docker/metadata-action@v4 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=raw,value=preprod,enable=true + + - name: Build and push preprod Docker + uses: docker/build-push-action@v4 + with: + file: ./deployment/Dockerfile + context: . + push: true + build-args: | + BUILD_MODE=production + LAUNCH_MODE=preprod + APP_VERSION=${{ github.ref_name }} + tags: ${{ steps.meta-preprod.outputs.tags }} + labels: ${{ steps.meta-preprod.outputs.labels }} + + build-prod-image: + name: Собираем production Docker + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Checkout repository + uses: actions/checkout@master + + - name: Log in to the Container registry + uses: docker/login-action@v2 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Define production metadata + id: meta-prod + uses: docker/metadata-action@v4 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=ref,event=tag,enable=true + type=raw,value=prod,enable=true + type=raw,value=latest,enable=true + + - name: Build and push production Docker + uses: docker/build-push-action@v4 + with: + file: ./deployment/Dockerfile + context: . + push: true + build-args: | + BUILD_MODE=production + LAUNCH_MODE=production + APP_VERSION=${{ github.ref_name }} + tags: ${{ steps.meta-prod.outputs.tags }} + labels: ${{ steps.meta-prod.outputs.labels }} + + deploy-preprod: + name: Раскатываем pre-prod среду + runs-on: [self-hosted, Linux] + needs: build-preprod-image + environment: + name: Preprod + url: https://app.preprod.profcomff.com/ + env: + CONTAINER_NAME: com_profcomff_ui_floormap_preprod + permissions: + packages: read + steps: + - name: Run docker container + run: | + docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:preprod + docker stop ${{ env.CONTAINER_NAME }} || true && docker rm ${{ env.CONTAINER_NAME }} || true + docker run \ + --detach \ + --restart on-failure:3 \ + --network=web \ + --name ${{ env.CONTAINER_NAME }} \ + ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:preprod + + undeploy-preprod: + name: Останавливаем pre-prod среду + runs-on: [self-hosted, Linux] + needs: deploy-preprod + environment: + name: Preprod + env: + CONTAINER_NAME: com_profcomff_ui_floormap_preprod + permissions: + packages: read + steps: + - name: Stop docker container + run: | + docker stop ${{ env.CONTAINER_NAME }} || true && docker rm ${{ env.CONTAINER_NAME }} || true + + deploy-production: + name: Раскатываем production среду + runs-on: [self-hosted, Linux] + needs: [deploy-preprod, build-prod-image] + environment: + name: Production + url: https://app.profcomff.com/ + env: + CONTAINER_NAME: com_profcomff_ui_floormap + permissions: + packages: read + steps: + - name: Run docker container + run: | + docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:prod + docker stop ${{ env.CONTAINER_NAME }} || true && docker rm ${{ env.CONTAINER_NAME }} || true + docker run \ + --detach \ + --restart always \ + --network=web \ + --name ${{ env.CONTAINER_NAME }} \ + ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:prod diff --git a/.github/workflows/pr_close.yml b/.github/workflows/pr_close.yml new file mode 100644 index 0000000..900bd1c --- /dev/null +++ b/.github/workflows/pr_close.yml @@ -0,0 +1,24 @@ +name: Тесты и раскатка на Pull Request (остановка) + +on: + pull_request: + types: [closed] + +jobs: + stop-deployment-dev: + name: Останавливаем dev среду + runs-on: ubuntu-latest + environment: + name: development-pr-${{ github.event.pull_request.number }} + steps: + - name: Stop deployment + run: | + curl -X 'POST' \ + 'https://ci.dev.profcomff.com/pr_stop' \ + -H 'accept: application/json' \ + -H 'Content-Type: application/json' \ + -H 'Authorization: ${{ secrets.CI_DYAKOVSPACE_MSK_TOKEN }}' \ + -d '{ + "repo_url": "${{ github.repository }}", + "git_ref": "${{ github.ref }}" + }' diff --git a/.github/workflows/pr_create.yml b/.github/workflows/pr_create.yml new file mode 100644 index 0000000..bd981c8 --- /dev/null +++ b/.github/workflows/pr_create.yml @@ -0,0 +1,112 @@ +name: Тесты и раскатка на Pull Request + +on: pull_request + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +jobs: + test-style: + name: Проверяем стили + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@master + + - uses: pnpm/action-setup@v2 + with: + version: 7.26.3 + + - uses: actions/setup-node@v3 + with: + node-version: '18' + cache: 'pnpm' + + - name: Install + run: pnpm install + + - name: Check + run: pnpm lint && pnpm stylelint + + # test: + # name: Выполняем тесты + # runs-on: ubuntu-latest + # steps: + # - name: Checkout repository + # uses: actions/checkout@master + + # - uses: pnpm/action-setup@v2 + # with: + # version: 7.26.3 + + # - uses: actions/setup-node@v3 + # with: + # node-version: '18' + # cache: 'pnpm' + + # - name: Install + # run: pnpm install + + # - name: Check + # run: pnpm test + + build-and-push-image: + name: Собираем dev Docker + runs-on: ubuntu-latest + needs: + # - test + - test-style + permissions: + contents: read + packages: write + + steps: + - name: Checkout repository + uses: actions/checkout@master + + - name: Log in to the Container registry + uses: docker/login-action@v2 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@v4 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + + - name: Build and push Docker image + uses: docker/build-push-action@v4 + with: + file: ./deployment/Dockerfile + context: . + push: true + build-args: | + BUILD_MODE=testing + LAUNCH_MODE=development-${{ github.event.pull_request.number }} + APP_VERSION=${{ github.ref_name }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + + deploy-dev: + name: Раскатываем dev среду + runs-on: ubuntu-latest + needs: build-and-push-image + environment: + name: development-pr-${{ github.event.pull_request.number }} + url: https://${{ github.event.repository.name }}__pr-${{ github.event.pull_request.number }}.dev.profcomff.com/ + steps: + - name: Deploy + run: | + curl -X 'POST' \ + 'https://ci.dev.profcomff.com/pr_run' \ + -H 'accept: application/json' \ + -H 'Content-Type: application/json' \ + -H 'Authorization: ${{ secrets.CI_DYAKOVSPACE_MSK_TOKEN }}' \ + -d '{ + "repo_url": "${{ github.repository }}", + "git_ref": "${{ github.ref }}" + }' diff --git a/deployment/Dockerfile b/deployment/Dockerfile new file mode 100644 index 0000000..e68b696 --- /dev/null +++ b/deployment/Dockerfile @@ -0,0 +1,23 @@ +FROM node:18 AS build + +ARG BUILD_MODE=production +ARG LAUNCH_MODE=production +ARG APP_VERSION=dev + +ENV MODE=${LAUNCH_MODE} +ENV VITE_APP_VERSION=${APP_VERSION} + +WORKDIR /app +ADD ./package.json ./pnpm-lock.yaml /app/ +RUN npm i -g pnpm && pnpm install +ADD . /app +RUN pnpm build --mode ${BUILD_MODE} + + +FROM nginx:1.21 + +ADD ./deployment/nginx.conf /etc/nginx/conf.d/default.conf +ADD ./deployment/docker_entrypoint.sh /docker_entrypoint.sh +COPY --from=build /app/dist /usr/share/nginx/html + +RUN chmod +x /docker_entrypoint.sh && /docker_entrypoint.sh diff --git a/deployment/docker_entrypoint.sh b/deployment/docker_entrypoint.sh new file mode 100644 index 0000000..1fa8ee2 --- /dev/null +++ b/deployment/docker_entrypoint.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +export APPJS_NAME=$(cd /usr/share/nginx/html && ls js/app.*.js) +if [ ! -z ${APPJS_NAME} ] +then + echo 'app.js is ${APPJS_NAME}' + sed -i 's|APPJS_NAME|'${APPJS_NAME}'|g' /etc/nginx/conf.d/default.conf + sed -i 's|# ||g' /etc/nginx/conf.d/default.conf +else + echo 'app.js is app.js, no changes' +fi diff --git a/deployment/nginx.conf b/deployment/nginx.conf new file mode 100644 index 0000000..79c54f7 --- /dev/null +++ b/deployment/nginx.conf @@ -0,0 +1,31 @@ +log_format json_combined escape=json + '{' + '"timestamp":"$time_iso8601",' + '"remote_addr":"$remote_addr",' + '"remote_user":"$remote_user",' + '"request":"$request",' + '"status": "$status",' + '"body_bytes_sent":"$body_bytes_sent",' + '"request_time":"$request_time",' + '"http_referrer":"$http_referer",' + '"http_user_agent":"$http_user_agent"' + '}'; + +server { + access_log /dev/stdout json_combined; + + listen 80; + listen [::]:80; + server_name localhost; + + location / { + root /usr/share/nginx/html; + index index.html index.htm; + try_files $uri /index.html; + } + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } +} diff --git a/index.html b/index.html index 978f5be..f23e6a8 100644 --- a/index.html +++ b/index.html @@ -4,7 +4,7 @@ - Персональный бюджет + Карта этажей ФФ МГУ
diff --git a/package.json b/package.json index b0a8f16..ce1aa0d 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "personal-budget", + "name": "@profcomff/floormap-ui", "private": true, "version": "0.0.0", "type": "module", @@ -36,4 +36,4 @@ "vite-plugin-vuetify": "^1.0.2", "vue-tsc": "^1.8.8" } -} \ No newline at end of file +}