diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml new file mode 100644 index 0000000..4793079 --- /dev/null +++ b/.github/workflows/main.yaml @@ -0,0 +1,221 @@ +name: Telegram Mini App Shop Builder + +on: + push: + branches: + - master + - 'issue/**' + - develop + pull_request: + types: + - opened + - synchronize + - reopened + +permissions: + contents: write + +jobs: + version_meta: + name: Compute version metadata + runs-on: ubuntu-latest + outputs: + tag: ${{ steps.meta.outputs.tag }} + filename: ${{ steps.meta.outputs.filename }} + is_release: ${{ steps.meta.outputs.is_release }} + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Extract tag and set filename + id: meta + run: | + set -euo pipefail + + RELEASE_TAG=$(git tag --points-at HEAD | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' | head -n 1 || true) + + if [ -n "$RELEASE_TAG" ]; then + echo "Это полноценный релиз" + TAG="$RELEASE_TAG" + FILENAME="oc_telegram_shop_${TAG}.ocmod.zip" + IS_RELEASE=true + else + echo "Это dev-сборка" + LAST_TAG=$(git tag --sort=-v:refname | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' | head -n 1 || true) + [ -z "$LAST_TAG" ] && LAST_TAG="v0.0.0" + SHORT_SHA=$(git rev-parse --short=7 HEAD) + DATE=$(date +%Y%m%d%H%M) + TAG="${LAST_TAG}-dev.${DATE}+${SHORT_SHA}" + FILENAME="oc_telegram_shop_${TAG}.ocmod.zip" + IS_RELEASE=false + fi + + echo "is_release=$IS_RELEASE" >> $GITHUB_OUTPUT + echo "tag=$TAG" >> $GITHUB_OUTPUT + echo "filename=$FILENAME" >> $GITHUB_OUTPUT + + test_frontend: + name: Run Frontend tests + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v6 + + - name: Install dependencies + working-directory: frontend/spa + run: npm install + + - name: Run tests + working-directory: frontend/spa + env: + APP_ENV: testing + run: npm run test + + test_backend: + name: Run Backend tests + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Setup PHP 7.4 + uses: shivammathur/setup-php@v2 + with: + php-version: '7.4' + tools: composer + extensions: mbstring + + - name: Install Composer dependencies + working-directory: module/oc_telegram_shop/upload/oc_telegram_shop + run: composer install --no-progress --no-interaction + + - name: Run tests + working-directory: module/oc_telegram_shop/upload/oc_telegram_shop + env: + APP_ENV: testing + run: ./vendor/bin/phpunit --testdox tests/Unit tests/Telegram + + - name: Static Analyzer + working-directory: module/oc_telegram_shop/upload/oc_telegram_shop + run: ./vendor/bin/phpstan analyse + + phpcs: + name: Run PHP_CodeSniffer + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Setup PHP 7.4 + uses: shivammathur/setup-php@v2 + with: + php-version: '7.4' + tools: phpcs + + - name: Run PHP_CodeSniffer + working-directory: module/oc_telegram_shop/upload/oc_telegram_shop + run: phpcs --standard=PSR12 bastion framework src + + module-build: + name: Build module. + runs-on: ubuntu-latest + needs: version_meta + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v6 + + - name: Setup PHP 7.4 + uses: shivammathur/setup-php@v2 + with: + php-version: '7.4' + tools: composer + + - name: Write version.txt + run: | + set -euo pipefail + MODULE_ROOT="module/oc_telegram_shop/upload/oc_telegram_shop" + echo "${{ needs.version_meta.outputs.tag }}" > "${MODULE_ROOT}/version.txt" + + - name: Build module + run: | + bash scripts/ci/build.sh "${GITHUB_WORKSPACE}" + + - name: Upload build artifact + uses: actions/upload-artifact@v4 + with: + name: oc_telegram_shop.ocmod.zip + path: ./build/oc_telegram_shop.ocmod.zip + retention-days: 1 + + release: + runs-on: ubuntu-latest + needs: [ version_meta, test_frontend, test_backend, module-build ] + if: github.ref == 'refs/heads/master' || github.event_name == 'pull_request' + steps: + - uses: actions/checkout@v4 + + - name: Download build artifact + uses: actions/download-artifact@v4 + with: + name: oc_telegram_shop.ocmod.zip + path: ./build + + - name: Rename artifact file + run: mv ./build/oc_telegram_shop.ocmod.zip ./build/${{ needs.version_meta.outputs.filename }} + + - name: Delete existing GitHub release and tag + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + TAG=${{ needs.version_meta.outputs.tag }} + echo "⛔ Deleting existing release and tag (if any): $TAG" + gh release delete "$TAG" --cleanup-tag --yes || true + git push origin ":refs/tags/$TAG" || true + + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 + with: + draft: ${{ needs.version_meta.outputs.is_release == 'false' }} + tag_name: ${{ needs.version_meta.outputs.tag }} + files: ./build/${{ needs.version_meta.outputs.filename }} + generate_release_notes: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Delete draft releases older than 7 days + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const daysToKeep = 7; + const cutoffDate = new Date(Date.now() - daysToKeep * 24 * 60 * 60 * 1000); + + const releases = await github.rest.repos.listReleases({ + owner: context.repo.owner, + repo: context.repo.repo, + per_page: 100 + }); + + for (const release of releases.data) { + if (release.draft) { + const created = new Date(release.created_at); + if (created < cutoffDate) { + console.log(`Deleting draft release: ${release.name || release.tag_name} (${release.id})`); + await github.rest.repos.deleteRelease({ + owner: context.repo.owner, + repo: context.repo.repo, + release_id: release.id + }); + + try { + await github.rest.git.deleteRef({ + owner: context.repo.owner, + repo: context.repo.repo, + ref: `tags/${release.tag_name}` + }); + console.log(`Deleted tag: ${release.tag_name}`); + } catch (err) { + console.log(`Tag ${release.tag_name} not found or already deleted.`); + } + } + } + } diff --git a/Makefile b/Makefile index 86f7ebb..af53c88 100644 --- a/Makefile +++ b/Makefile @@ -70,7 +70,7 @@ test-coverage: docker compose exec -w /module/oc_telegram_shop/upload/oc_telegram_shop web bash -c "./vendor/bin/phpunit --coverage-html coverage tests/" phar: - docker build -t telecart_local_build -f ./docker/build.dockerfile . && \ + docker build -t telecart_local_build -f ./deployment/build.dockerfile . && \ docker run -v "./src/upload/system/library/oc_telegram_shop:/build" telecart_local_build sh -c 'sh /scripts/build_phar.sh' cli: diff --git a/README.md b/README.md index 8e944b8..97e9e10 100644 --- a/README.md +++ b/README.md @@ -1,83 +1 @@ -# TeleCart 2.0 - -[![CI/CD](https://github.com/telecart-labs/telecart/actions/workflows/main.yaml/badge.svg)](https://github.com/telecart-labs/telecart/actions/workflows/main.yaml) -[![License](https://img.shields.io/badge/license-Commercial-red.svg)](LICENSE) -[![PHP Version](https://img.shields.io/badge/PHP-%3E%3D7.4-blue.svg)](https://php.net) -[![Vue.js](https://img.shields.io/badge/Vue.js-3.5.22-4FC08D?logo=vue.js&logoColor=white)](https://vuejs.org) -[![Docker](https://img.shields.io/badge/Docker-Ready-2496ED?logo=docker&logoColor=white)](docker-compose.yaml) -[![OpenCart](https://img.shields.io/badge/OpenCart-Module-FF6B35?logo=opencart)](https://www.opencart.com) - -Telegram магазин на базе OpenCart. Позволяет создать полноценный интернет-магазин в виде Telegram Mini App. - -## 🚀 Возможности - -- 📱 Telegram Mini App интерфейс -- 🛒 Полноценная корзина и оформление заказов -- 🎨 Адаптивный дизайн с поддержкой темной/светлой темы -- 📊 Административная панель для управления настройками -- 🔍 Поиск и фильтрация товаров -- 📦 Интеграция с OpenCart - -## 🛠 Технологии - -- **Backend**: PHP (OpenCart), Composer -- **Frontend**: Vue.js 3, Vite, Tailwind CSS, Pinia -- **Инфраструктура**: Docker, Docker Compose -- **Тестирование**: PHPUnit, Vitest - -## 📦 Структура проекта - -``` -telecart/ -├── frontend/ -│ ├── admin/ # Административная панель -│ └── spa/ # Telegram Mini App -├── module/ # Модуль OpenCart -├── docker/ # Docker конфигурации -└── src/ # Исходный код OpenCart -``` - -## 🚀 Быстрый старт - -### Требования - -- Docker и Docker Compose -- PHP >= 7.4 -- Node.js >= 20.19.0 или >= 22.12.0 - -### Установка - -```bash -# Клонировать репозиторий -git clone git@github.com:telecart-labs/telecart.git -cd telecart - -# Настроить проект -make setup - -# Запустить в режиме разработки -make dev -``` - -### Доступные команды - -- `make setup` - Первоначальная настройка проекта -- `make start` - Запустить контейнеры -- `make stop` - Остановить контейнеры -- `make dev` - Запустить в режиме разработки -- `make dev-admin` - Запустить админ-панель в режиме разработки -- `make test` - Запустить тесты -- `make lint` - Проверить код линтером - -## 📝 Лицензия - -Это коммерческий платный модуль. Все права защищены. Использование модуля возможно только после приобретения лицензии. - -## 🤝 Вклад в проект - -Мы приветствуем вклад в развитие проекта! Пожалуйста, создавайте issue и pull request'ы. - -## 📄 Документация - -Дополнительная документация находится в папке [`docs/`](docs/). - +# Demo code for interviewing \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml index e1997da..682dc2d 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -7,7 +7,6 @@ services: - "./scripts:/scripts" - "./module:/module" - "./build:/build" -# - "/Users/nikitakiselev/code/italy-moda/image/catalog:/web/upload/image/catalog" ports: - "8000:80" restart: always @@ -61,7 +60,7 @@ services: volumes: - mysql_data:/var/lib/mysql - ./sql_dumps:/sql_dumps - - ./docker/mysql/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d + - ./deployment/mysql/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d cron: image: ghcr.io/telecart-labs/scheduler:latest