From 36678b4b57de0dd2c421da9b2798e0a0a0196a8a Mon Sep 17 00:00:00 2001 From: myrmidex Date: Sat, 2 May 2026 10:19:26 +0200 Subject: [PATCH] 27 - Add Forgejo CI: PHP tests, lint, coverage, asset build --- .env.testing | 4 ++ .forgejo/workflows/ci.yml | 141 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 145 insertions(+) create mode 100644 .forgejo/workflows/ci.yml diff --git a/.env.testing b/.env.testing index 04b46cf..e0b6eaa 100644 --- a/.env.testing +++ b/.env.testing @@ -1,7 +1,11 @@ APP_ENV=testing APP_KEY=base64:+7T2RuonhTIij1yLp3rTOv2uQlYJh0TQulu20MlCA+s= +DB_CONNECTION=mysql +DB_HOST=db DB_DATABASE=testing +DB_USERNAME=incr_user +DB_PASSWORD=incr_password SESSION_DRIVER=array CACHE_STORE=array diff --git a/.forgejo/workflows/ci.yml b/.forgejo/workflows/ci.yml new file mode 100644 index 0000000..69862fa --- /dev/null +++ b/.forgejo/workflows/ci.yml @@ -0,0 +1,141 @@ +name: CI + +on: + push: + branches: ['release/*'] + pull_request: + branches: [main] + +jobs: + ci: + runs-on: docker + container: + image: catthehacker/ubuntu:act-latest + + services: + db: + image: mysql:8.0 + env: + MYSQL_DATABASE: testing + MYSQL_USER: incr_user + MYSQL_PASSWORD: incr_password + MYSQL_ROOT_PASSWORD: root_password + options: --health-cmd="mysqladmin ping -u root -proot_password" --health-interval=10s --health-timeout=5s --health-retries=10 + + steps: + - uses: https://data.forgejo.org/actions/checkout@v4 + + - name: Set up PHP + uses: https://github.com/shivammathur/setup-php@v2 + with: + php-version: '8.3' + extensions: pdo_mysql, mbstring, xml, dom, bcmath, gd, exif, pcntl + coverage: pcov + + - name: Cache Composer dependencies + uses: https://data.forgejo.org/actions/cache@v4 + with: + path: ~/.composer/cache + key: composer-${{ hashFiles('composer.lock') }} + restore-keys: composer- + + - name: Install PHP dependencies + run: composer install --no-interaction --prefer-dist --no-progress + + - name: Prepare environment + run: cp .env.testing .env + + - name: Run migrations + run: php artisan migrate --force + + - name: Lint + run: vendor/bin/pint --test + + - name: Tests + run: php artisan test --coverage-clover coverage.xml --coverage-text + + - name: Parse coverage + if: github.event_name == 'pull_request' + id: coverage + run: | + COVERAGE=$(php -r ' + $xml = simplexml_load_file("coverage.xml"); + if ($xml === false || !isset($xml->project->metrics)) { + echo "0"; + exit; + } + $metrics = $xml->project->metrics; + $statements = (int) $metrics["statements"]; + $covered = (int) $metrics["coveredstatements"]; + echo $statements > 0 ? round(($covered / $statements) * 100, 2) : 0; + ') + echo "percentage=$COVERAGE" >> "$GITHUB_OUTPUT" + + - name: Comment coverage on PR + if: github.event_name == 'pull_request' + env: + FORGEJO_TOKEN: ${{ secrets.FORGEJO_TOKEN }} + PR_NUMBER: ${{ github.event.pull_request.number }} + COVERAGE: ${{ steps.coverage.outputs.percentage }} + REPO: ${{ github.repository }} + SERVER_URL: ${{ github.server_url }} + COMMIT_SHA: ${{ github.sha }} + run: | + API_URL="${SERVER_URL}/api/v1/repos/${REPO}/issues/${PR_NUMBER}/comments" + MARKER="" + + BODY="${MARKER} + ## Code Coverage Report + + | Metric | Value | + |--------|-------| + | **Line Coverage** | ${COVERAGE}% | + + _Updated by CI — commit ${COMMIT_SHA}_" + + EXISTING=$(curl -sf -H "Authorization: token ${FORGEJO_TOKEN}" \ + "${API_URL}?limit=50" | \ + php -r ' + $comments = json_decode(file_get_contents("php://stdin"), true); + if (!is_array($comments)) exit; + foreach ($comments as $c) { + if (str_contains($c["body"], "")) { + echo $c["id"]; + exit; + } + } + ' || true) + + if [ -n "$EXISTING" ]; then + curl -sf -X PATCH \ + -H "Authorization: token ${FORGEJO_TOKEN}" \ + -H "Content-Type: application/json" \ + -d "$(php -r 'echo json_encode(["body" => $argv[1]]);' "$BODY")" \ + "${SERVER_URL}/api/v1/repos/${REPO}/issues/comments/${EXISTING}" > /dev/null + else + curl -sf -X POST \ + -H "Authorization: token ${FORGEJO_TOKEN}" \ + -H "Content-Type: application/json" \ + -d "$(php -r 'echo json_encode(["body" => $argv[1]]);' "$BODY")" \ + "${API_URL}" > /dev/null + fi + + build: + runs-on: docker + container: + image: catthehacker/ubuntu:act-latest + + steps: + - uses: https://data.forgejo.org/actions/checkout@v4 + + - name: Set up Node.js + uses: https://data.forgejo.org/actions/setup-node@v4 + with: + node-version: '20' + cache: 'npm' + + - name: Install JS dependencies + run: npm ci + + - name: Build assets + run: npm run build