From cec1b42da34849591dd3f5c5d357c1f6cd9701ae Mon Sep 17 00:00:00 2001 From: Michael Schiemer Date: Thu, 17 Jul 2025 19:13:47 +0200 Subject: [PATCH] chore: .gitea folder and RoutingMiddleware.php --- .gitea/workflows/ci-cd.yml | 274 ++++++++++++++++++ .../Http/Middlewares/RoutingMiddleware.php | 4 +- 2 files changed, 277 insertions(+), 1 deletion(-) create mode 100644 .gitea/workflows/ci-cd.yml diff --git a/.gitea/workflows/ci-cd.yml b/.gitea/workflows/ci-cd.yml new file mode 100644 index 00000000..95afc277 --- /dev/null +++ b/.gitea/workflows/ci-cd.yml @@ -0,0 +1,274 @@ +name: CI/CD Pipeline für michaelschiemer.de + +on: + push: + branches: [ main, develop ] + pull_request: + branches: [ main ] + +env: + REGISTRY_URL: registry.michaelschiemer.de + IMAGE_NAME: michaelschiemer + PHP_VERSION: "8.4" + +jobs: + test: + runs-on: ubuntu-latest + container: + image: php:8.4-cli + services: + redis: + image: redis:8-alpine + mariadb: + image: mariadb:latest + env: + MYSQL_ROOT_PASSWORD: test + MYSQL_DATABASE: test + + steps: + - name: Checkout Code + uses: actions/checkout@v4 + + - name: Install System Dependencies + run: | + apt-get update && apt-get install -y \ + git unzip libzip-dev libpng-dev libjpeg-dev \ + libfreetype6-dev libwebp-dev libavif-dev \ + libxpm-dev curl + + - name: Install PHP Extensions + run: | + docker-php-ext-configure gd \ + --with-freetype --with-jpeg --with-webp \ + --with-avif --with-xpm + docker-php-ext-install -j$(nproc) \ + gd zip pdo pdo_mysql opcache pcntl posix shmop + + - name: Install Composer + run: | + curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer + + - name: Cache Composer Dependencies + uses: actions/cache@v3 + with: + path: ~/.composer/cache + key: composer-${{ hashFiles('**/composer.lock') }} + restore-keys: composer- + + - name: Install Dependencies + run: | + composer install --no-progress --prefer-dist --optimize-autoloader + + - name: Run PHP CS Fixer (Check) + run: | + composer cs + + - name: Run Tests + run: | + ./vendor/bin/pest + env: + DB_HOST: mariadb + DB_PORT: 3306 + DB_DATABASE: test + DB_USERNAME: root + DB_PASSWORD: test + REDIS_HOST: redis + REDIS_PORT: 6379 + + security-scan: + runs-on: ubuntu-latest + needs: test + + steps: + - name: Checkout Code + uses: actions/checkout@v4 + + - name: Run Security Scan + run: | + # Composer-Audit für bekannte Vulnerabilities + composer audit --format=json || true + + # Grundlegende Sicherheitsscans + find . -name "*.php" -exec grep -l "eval\|system\|exec\|shell_exec" {} \; || true + + build: + needs: [test, security-scan] + runs-on: ubuntu-latest + if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop' + + steps: + - name: Checkout Code + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to Private Registry + run: | + echo ${{ secrets.REGISTRY_PASSWORD }} | docker login ${{ env.REGISTRY_URL }} -u ${{ secrets.REGISTRY_USERNAME }} --password-stdin + + - name: Determine Image Tag + id: tag + run: | + if [ "${{ github.ref }}" = "refs/heads/main" ]; then + echo "tag=latest" >> $GITHUB_OUTPUT + echo "env=production" >> $GITHUB_OUTPUT + else + echo "tag=develop" >> $GITHUB_OUTPUT + echo "env=staging" >> $GITHUB_OUTPUT + fi + + - name: Build and Push PHP Image + run: | + docker buildx build --push \ + --platform linux/amd64,linux/arm64 \ + --build-arg ENV=${{ steps.tag.outputs.env }} \ + --build-arg COMPOSER_INSTALL_FLAGS="--no-scripts --no-autoloader --optimize-autoloader" \ + -t ${{ env.REGISTRY_URL }}/${{ env.IMAGE_NAME }}/php:${{ steps.tag.outputs.tag }} \ + -t ${{ env.REGISTRY_URL }}/${{ env.IMAGE_NAME }}/php:${{ github.sha }} \ + -f docker/php/Dockerfile . + + - name: Build and Push Nginx Image + run: | + docker buildx build --push \ + --platform linux/amd64,linux/arm64 \ + -t ${{ env.REGISTRY_URL }}/${{ env.IMAGE_NAME }}/nginx:${{ steps.tag.outputs.tag }} \ + -t ${{ env.REGISTRY_URL }}/${{ env.IMAGE_NAME }}/nginx:${{ github.sha }} \ + -f docker/nginx/Dockerfile . + + - name: Build and Push Worker Image + run: | + docker buildx build --push \ + --platform linux/amd64,linux/arm64 \ + -t ${{ env.REGISTRY_URL }}/${{ env.IMAGE_NAME }}/worker:${{ steps.tag.outputs.tag }} \ + -t ${{ env.REGISTRY_URL }}/${{ env.IMAGE_NAME }}/worker:${{ github.sha }} \ + -f docker/worker/Dockerfile . + + - name: Update Image Tags in Deployment + run: | + # Für spätere Ansible-Integration + echo "Built images with tag: ${{ steps.tag.outputs.tag }}" + echo "SHA: ${{ github.sha }}" + + deploy-staging: + needs: build + runs-on: ubuntu-latest + if: github.ref == 'refs/heads/develop' + environment: staging + + steps: + - name: Checkout Code + uses: actions/checkout@v4 + + - name: Setup SSH + run: | + mkdir -p ~/.ssh + echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa + chmod 600 ~/.ssh/id_rsa + ssh-keyscan -H ${{ secrets.STAGING_HOST }} >> ~/.ssh/known_hosts + + - name: Deploy to Staging + run: | + ssh -i ~/.ssh/id_rsa ${{ secrets.STAGING_USER }}@${{ secrets.STAGING_HOST }} << 'EOF' + cd /var/www/michaelschiemer + + # Registry-Login + echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login ${{ env.REGISTRY_URL }} -u ${{ secrets.REGISTRY_USERNAME }} --password-stdin + + # Images pullen + docker pull ${{ env.REGISTRY_URL }}/${{ env.IMAGE_NAME }}/php:develop + docker pull ${{ env.REGISTRY_URL }}/${{ env.IMAGE_NAME }}/nginx:develop + docker pull ${{ env.REGISTRY_URL }}/${{ env.IMAGE_NAME }}/worker:develop + + # Environment auf develop setzen + sed -i 's/IMAGE_TAG=.*/IMAGE_TAG=develop/' .env + + # Services neustarten + docker compose pull + docker compose up -d + + # Aufräumen + docker system prune -f + EOF + + - name: Health Check Staging + run: | + sleep 30 + curl -f https://staging.michaelschiemer.de/health || exit 1 + + deploy-production: + needs: build + runs-on: ubuntu-latest + if: github.ref == 'refs/heads/main' + environment: production + + steps: + - name: Checkout Code + uses: actions/checkout@v4 + + - name: Setup SSH + run: | + mkdir -p ~/.ssh + echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa + chmod 600 ~/.ssh/id_rsa + ssh-keyscan -H ${{ secrets.PRODUCTION_HOST }} >> ~/.ssh/known_hosts + + - name: Deploy to Production + run: | + ssh -i ~/.ssh/id_rsa ${{ secrets.PRODUCTION_USER }}@${{ secrets.PRODUCTION_HOST }} << 'EOF' + cd /var/www/michaelschiemer + + # Registry-Login + echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login ${{ env.REGISTRY_URL }} -u ${{ secrets.REGISTRY_USERNAME }} --password-stdin + + # Images pullen + docker pull ${{ env.REGISTRY_URL }}/${{ env.IMAGE_NAME }}/php:latest + docker pull ${{ env.REGISTRY_URL }}/${{ env.IMAGE_NAME }}/nginx:latest + docker pull ${{ env.REGISTRY_URL }}/${{ env.IMAGE_NAME }}/worker:latest + + # Environment auf latest setzen + sed -i 's/IMAGE_TAG=.*/IMAGE_TAG=latest/' .env + + # Services neustarten + docker compose pull + docker compose up -d + + # Aufräumen + docker system prune -f + EOF + + - name: Health Check Production + run: | + sleep 30 + curl -f https://michaelschiemer.de/health || exit 1 + + cleanup: + needs: [deploy-staging, deploy-production] + runs-on: ubuntu-latest + if: always() + + steps: + - name: Clean up old images + run: | + echo "Cleanup läuft..." + # Hier könnten Sie Registry-API-Calls für Cleanup implementieren + echo "Cleanup abgeschlossen" + + notify: + needs: [deploy-staging, deploy-production] + runs-on: ubuntu-latest + if: always() + + steps: + - name: Notify Deployment Status + run: | + STATUS="${{ job.status }}" + BRANCH="${{ github.ref_name }}" + + if [ "$STATUS" = "success" ]; then + echo "✅ Deployment erfolgreich für Branch: $BRANCH" + else + echo "❌ Deployment fehlgeschlagen für Branch: $BRANCH" + fi + + # Hier könnten Sie Slack/Email-Benachrichtigungen hinzufügen diff --git a/src/Framework/Http/Middlewares/RoutingMiddleware.php b/src/Framework/Http/Middlewares/RoutingMiddleware.php index d8c00df1..6d9f671f 100644 --- a/src/Framework/Http/Middlewares/RoutingMiddleware.php +++ b/src/Framework/Http/Middlewares/RoutingMiddleware.php @@ -4,6 +4,7 @@ declare(strict_types=1); namespace App\Framework\Http\Middlewares; use App\Framework\Auth\Auth; +use App\Framework\Config\TypedConfiguration; use App\Framework\Http\HttpMiddleware; use App\Framework\Http\MiddlewareContext; use App\Framework\Http\MiddlewarePriority; @@ -25,6 +26,7 @@ final readonly class RoutingMiddleware implements HttpMiddleware public function __construct( private HttpRouter $router, private RouteDispatcher $dispatcher, + private TypedConfiguration $config, ) {} /** @@ -47,7 +49,7 @@ final readonly class RoutingMiddleware implements HttpMiddleware throw new RouteNotFound($routeContext->path); } - if (in_array(Auth::class, $routeContext->match->route->attributes)) { + if (!$this->config->app->debug && in_array(Auth::class, $routeContext->match->route->attributes)) { #debug($request->server->getClientIp()); $wireguardIp = '172.20.0.1';