name: CI on: push: branches: [main, develop] pull_request: branches: [main] jobs: lint-php: name: PHP Syntax Check runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - name: Setup PHP uses: shivammathur/setup-php@v2 with: php-version: '8.2' extensions: pdo_sqlite, curl, mbstring - name: Check PHP syntax run: | find api/ -name '*.php' -exec php -l {} \; lint-js: name: JavaScript Lint runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - name: Check JS syntax run: | node -c assets/js/app.js docker-build: name: Docker Build Test runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - name: Build Docker image run: docker build -t evershelf-test . - name: Test container starts run: | docker run -d --name test-evershelf -p 8080:80 evershelf-test sleep 5 curl -f http://localhost:8080/ || exit 1 docker stop test-evershelf validate-translations: name: Validate Translation Files runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - name: Validate JSON syntax run: | for f in translations/*.json; do echo "Checking $f..." python3 -c "import json; json.load(open('$f'))" || exit 1 done echo "All translation files valid." - name: Check translation completeness run: | python3 -c " import json, sys base = json.load(open('translations/it.json')) base_keys = set(base.keys()) ok = True import glob for f in glob.glob('translations/*.json'): if 'it.json' in f: continue lang = json.load(open(f)) lang_keys = set(lang.keys()) missing = base_keys - lang_keys if missing: print(f'{f}: {len(missing)} missing keys') for k in sorted(missing)[:10]: print(f' - {k}') if len(missing) > 10: print(f' ... and {len(missing)-10} more') else: print(f'{f}: complete ✓') " # ── Auto-merge develop → main ──────────────────────────────────────────── # Runs automatically after ALL checks pass on develop. # You never need to merge manually again — just push to develop. auto-merge-to-main: name: Auto-merge develop → main needs: [lint-php, lint-js, docker-build, validate-translations] if: github.ref == 'refs/heads/develop' runs-on: ubuntu-latest permissions: contents: write steps: - name: Checkout (full history) uses: actions/checkout@v6 with: fetch-depth: 0 token: ${{ secrets.GITHUB_TOKEN }} - name: Configure git bot identity run: | git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" - name: Merge develop → main run: | LAST=$(git log --oneline -1 origin/develop) git checkout main git pull --ff-only origin main git merge --no-ff origin/develop \ -m "chore: auto-merge develop → main Triggered by: $LAST" git push origin main # ── Auto-create GitHub Release on main ─────────────────────────────────── # Runs after auto-merge succeeds. Reads version from index.html, # creates a release tag vX.Y.Z if it doesn't exist yet. # This powers the in-app update badge for self-hosted users. create-release: name: Create GitHub Release needs: [auto-merge-to-main] if: github.ref == 'refs/heads/develop' runs-on: ubuntu-latest permissions: contents: write steps: - name: Checkout main uses: actions/checkout@v6 with: ref: main fetch-depth: 0 token: ${{ secrets.GITHUB_TOKEN }} - name: Extract version from index.html id: version run: | VER=$(grep -oP 'header-version">v\K[\d.]+' index.html | head -1) echo "version=v${VER}" >> $GITHUB_OUTPUT echo "Detected version: v${VER}" - name: Check if tag already exists id: tag_check run: | if git ls-remote --tags origin "refs/tags/${{ steps.version.outputs.version }}" | grep -q .; then echo "exists=true" >> $GITHUB_OUTPUT else echo "exists=false" >> $GITHUB_OUTPUT fi - name: Read CHANGELOG entry for this version id: changelog if: steps.tag_check.outputs.exists == 'false' run: | VER="${{ steps.version.outputs.version }}" # Extract the section for this version from CHANGELOG.md BODY=$(awk "/^## \[?${VER#v}\]?|^## ${VER}/,/^## [0-9]/" CHANGELOG.md | head -50 | tail -n +1 | grep -v "^## [0-9]" || true) if [ -z "$BODY" ]; then BODY="See [CHANGELOG.md](https://github.com/${{ github.repository }}/blob/main/CHANGELOG.md) for details." fi # Multiline output echo "body<> $GITHUB_OUTPUT echo "$BODY" >> $GITHUB_OUTPUT echo "EOF" >> $GITHUB_OUTPUT - name: Create release if: steps.tag_check.outputs.exists == 'false' uses: softprops/action-gh-release@v2 with: tag_name: ${{ steps.version.outputs.version }} name: "EverShelf ${{ steps.version.outputs.version }}" body: ${{ steps.changelog.outputs.body }} target_commitish: main make_latest: true