From 091294f7f39a4c17743ad3a6a636e835266ddcd2 Mon Sep 17 00:00:00 2001 From: Batmanisko Date: Wed, 29 Apr 2026 19:31:20 +0200 Subject: [PATCH] feat: migrace CI z Woodpecker na Gitea Actions Co-Authored-By: Claude Opus 4.7 --- .gitea/workflows/ci.yaml | 256 ++++++++++++++++++++++++++++++++++++++ .woodpecker/workflow.yaml | 123 ------------------ 2 files changed, 256 insertions(+), 123 deletions(-) create mode 100644 .gitea/workflows/ci.yaml delete mode 100644 .woodpecker/workflow.yaml diff --git a/.gitea/workflows/ci.yaml b/.gitea/workflows/ci.yaml new file mode 100644 index 0000000..f44b363 --- /dev/null +++ b/.gitea/workflows/ci.yaml @@ -0,0 +1,256 @@ +name: CI + +on: + push: + branches: + - '**' + pull_request: + +concurrency: + group: ${{ github.ref }} + cancel-in-progress: true + +jobs: + + # ─── 1. Generate OpenAPI types ──────────────────────────────────────────── + + generate-types: + name: Generate TypeScript types + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: '22' + cache: yarn + cache-dependency-path: types/yarn.lock + + - run: cd types && yarn install --frozen-lockfile && yarn openapi-ts + + - uses: actions/upload-artifact@v4 + with: + name: types-gen + path: types/gen + + # ─── 2a. Server unit tests ──────────────────────────────────────────────── + + server-test: + name: Server unit tests + runs-on: ubuntu-latest + needs: generate-types + env: + NODE_ENV: test + JWT_SECRET: test-secret-min-32-chars-aaaaaaa! + MOCK_DATA: 'true' + STORAGE: json + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: '22' + cache: yarn + cache-dependency-path: server/yarn.lock + + - uses: actions/download-artifact@v4 + with: + name: types-gen + path: types/gen + + - run: cd server && yarn install --frozen-lockfile && yarn test + + # ─── 2b. Build server ───────────────────────────────────────────────────── + + server-build: + name: Build server + runs-on: ubuntu-latest + needs: generate-types + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: '22' + cache: yarn + cache-dependency-path: server/yarn.lock + + - uses: actions/download-artifact@v4 + with: + name: types-gen + path: types/gen + + - run: cd server && yarn install --frozen-lockfile && yarn build + + - uses: actions/upload-artifact@v4 + with: + name: server-dist + path: server/dist + + # ─── 2c. Build client ───────────────────────────────────────────────────── + + client-build: + name: Build client + runs-on: ubuntu-latest + needs: generate-types + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: '22' + cache: yarn + cache-dependency-path: client/yarn.lock + + - uses: actions/download-artifact@v4 + with: + name: types-gen + path: types/gen + + - run: cd client && yarn install --frozen-lockfile && yarn build + + - uses: actions/upload-artifact@v4 + with: + name: client-dist + path: client/dist + + # ─── 3. Playwright E2E tests ────────────────────────────────────────────── + + e2e: + name: Playwright E2E tests + runs-on: ubuntu-latest + needs: [server-build, client-build] + container: mcr.microsoft.com/playwright:v1.59.1-jammy + services: + redis: + image: redis/redis-stack-server:7.4.0-v1 + env: + REDIS_ARGS: "--save '' --loglevel warning" + env: + CI: 'true' + NODE_ENV: test + JWT_SECRET: test-secret-min-32-chars-aaaaaaa! + MOCK_DATA: 'true' + STORAGE: redis + REDIS_HOST: redis + REDIS_PORT: '6379' + HTTP_REMOTE_USER_ENABLED: 'true' + HTTP_REMOTE_USER_HEADER_NAME: remote-user + HTTP_REMOTE_TRUSTED_IPS: '127.0.0.1,::1,::ffff:127.0.0.1' + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: '22' + cache: yarn + cache-dependency-path: | + server/yarn.lock + e2e/yarn.lock + + - uses: actions/download-artifact@v4 + with: + name: server-dist + path: server/dist + + - uses: actions/download-artifact@v4 + with: + name: client-dist + path: client/dist + + - name: Install server dependencies + run: cd server && yarn install --frozen-lockfile + + - name: Copy client build into server/public + run: cp -r client/dist server/public + + - name: Install e2e dependencies and browsers + run: cd e2e && yarn install --frozen-lockfile && yarn playwright install firefox --with-deps + + - name: Run Playwright tests + run: cd e2e && yarn test + + - uses: actions/upload-artifact@v4 + if: failure() + with: + name: playwright-report + path: | + e2e/playwright-report + e2e/test-results + + # ─── 4. Build and push Docker image (master only) ───────────────────────── + + docker-build: + name: Build and push Docker image + runs-on: ubuntu-latest + needs: [server-build, client-build, server-test, e2e] + if: github.event_name == 'push' && github.ref == 'refs/heads/master' + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: '22' + cache: yarn + cache-dependency-path: server/yarn.lock + + - uses: actions/download-artifact@v4 + with: + name: server-dist + path: server/dist + + - uses: actions/download-artifact@v4 + with: + name: client-dist + path: client/dist + + - name: Install server production dependencies + run: cd server && yarn install --frozen-lockfile --production + + - uses: docker/setup-buildx-action@v3 + + - uses: docker/login-action@v3 + with: + registry: ${{ secrets.REPO_URL }} + username: ${{ secrets.REPO_USERNAME }} + password: ${{ secrets.REPO_PASSWORD }} + + - uses: docker/build-push-action@v5 + with: + context: . + file: Dockerfile-Woodpecker + platforms: linux/amd64 + push: true + tags: ${{ secrets.REPO_URL }}/${{ secrets.REPO_NAME }}:latest + + # ─── 5. Discord notification (master only, always) ──────────────────────── + + discord-notify: + name: Discord notification + runs-on: ubuntu-latest + needs: docker-build + if: always() && github.event_name == 'push' && github.ref == 'refs/heads/master' + steps: + - name: Send webhook + env: + DISCORD_WEBHOOK_ID: ${{ secrets.DISCORD_WEBHOOK_ID }} + DISCORD_WEBHOOK_TOKEN: ${{ secrets.DISCORD_WEBHOOK_TOKEN }} + BUILD_RESULT: ${{ needs.docker-build.result }} + RUN_NUMBER: ${{ github.run_number }} + RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + COMMIT_MESSAGE: ${{ github.event.head_commit.message }} + COMMIT_AUTHOR: ${{ github.event.head_commit.author.name }} + run: | + if [ "$BUILD_RESULT" = "success" ]; then + MSG="✅ Sestavení #${RUN_NUMBER} proběhlo úspěšně." + else + MSG="❌ Sestavení #${RUN_NUMBER} selhalo." + fi + FULL_MSG="${MSG} + +Pipeline: ${RUN_URL} +Poslední commit: ${COMMIT_MESSAGE}Autor: ${COMMIT_AUTHOR}" + curl -s -X POST \ + "https://discord.com/api/webhooks/${DISCORD_WEBHOOK_ID}/${DISCORD_WEBHOOK_TOKEN}" \ + -H "Content-Type: application/json" \ + --data "$(jq -n --arg content "$FULL_MSG" '{content: $content}')" diff --git a/.woodpecker/workflow.yaml b/.woodpecker/workflow.yaml deleted file mode 100644 index 2c529c6..0000000 --- a/.woodpecker/workflow.yaml +++ /dev/null @@ -1,123 +0,0 @@ -variables: - - &node_image "node:22-alpine" - - &playwright_image "mcr.microsoft.com/playwright:v1.59.1-jammy" - - &branch "master" - -# Spustit na všech větvích a pull requestech. -# Docker build probíhá jen na master větvi (viz when: v posledních krocích). -when: - - event: [push, pull_request] - -services: - redis: - image: redis/redis-stack-server:7.4.0-v1 - environment: - REDIS_ARGS: "--save '' --loglevel warning" - -steps: - - name: Generate TypeScript types - image: *node_image - commands: - - cd types - - yarn install --frozen-lockfile - - yarn openapi-ts - - - name: Install server dependencies - image: *node_image - commands: - - cd server - - yarn install --frozen-lockfile - depends_on: [Generate TypeScript types] - - - name: Install client dependencies - image: *node_image - commands: - - cd client - - yarn install --frozen-lockfile - depends_on: [Generate TypeScript types] - - - name: Install e2e dependencies - image: *playwright_image - commands: - - cd e2e - - yarn install --frozen-lockfile - depends_on: [Generate TypeScript types] - - - name: Server unit tests - image: *node_image - environment: - NODE_ENV: test - JWT_SECRET: test-secret-min-32-chars-aaaaaaa! - MOCK_DATA: "true" - STORAGE: json - commands: - - cd server - - yarn test - depends_on: [Install server dependencies] - - - name: Build server - image: *node_image - commands: - - cd server - - yarn build - depends_on: [Install server dependencies] - - - name: Build client - image: *node_image - commands: - - cd client - - yarn build - depends_on: [Install client dependencies] - - - name: Playwright E2E tests - image: *playwright_image - environment: - CI: "true" - NODE_ENV: test - JWT_SECRET: test-secret-min-32-chars-aaaaaaa! - MOCK_DATA: "true" - STORAGE: redis - REDIS_HOST: redis - REDIS_PORT: "6379" - HTTP_REMOTE_USER_ENABLED: "true" - HTTP_REMOTE_USER_HEADER_NAME: remote-user - HTTP_REMOTE_TRUSTED_IPS: "127.0.0.1,::1,::ffff:127.0.0.1" - commands: - # Zkopírujeme build klienta do server/public, aby Express mohl SPA servírovat - - cp -r client/dist server/public - - cd e2e - - yarn playwright install firefox --with-deps - - yarn test - depends_on: [Build server, Build client, Install e2e dependencies] - - - name: Build Docker image - depends_on: [Build server, Build client] - image: woodpeckerci/plugin-docker-buildx - when: - - event: push - branch: *branch - settings: - dockerfile: Dockerfile-Woodpecker - platforms: linux/amd64 - registry: - from_secret: REPO_URL - username: - from_secret: REPO_USERNAME - password: - from_secret: REPO_PASSWORD - repo: - from_secret: REPO_NAME - - - name: Discord notification - build - image: appleboy/drone-discord - depends_on: [Build Docker image] - when: - - status: [success, failure] - event: push - branch: *branch - settings: - webhook_id: - from_secret: DISCORD_WEBHOOK_ID - webhook_token: - from_secret: DISCORD_WEBHOOK_TOKEN - message: "{{#success build.status}}✅ Sestavení {{build.number}} proběhlo úspěšně.{{else}}❌ Sestavení {{build.number}} selhalo.{{/success}}\n\nPipeline: {{build.link}}\nPoslední commit: {{commit.message}}Autor: {{commit.author}}"