Files
shahondin1624 a9f3dc82ae Add Makefile test target for running PHPUnit inside container
Supports:
  make test              # all suites (Unit, Integration, DatabasePortability)
  make test suite=Unit
  make test suite=Integration
  make test suite=DatabasePortability

Also switches composer to install dev dependencies so PHPUnit is available.
2026-04-22 09:59:06 +02:00

241 lines
13 KiB
Makefile

.PHONY: build deps up down setup deploy redeploy logs clean package release \
up-postgres setup-postgres deploy-postgres clean-postgres \
up-sqlite setup-sqlite deploy-sqlite clean-sqlite \
test
# Install dependencies (composer via Docker since PHP may not be local)
deps:
npm install --no-audit --no-fund
docker run --rm -v "$$(pwd):/app" -w /app composer:2 install --optimize-autoloader --no-interaction
# Build frontend
build: deps
rm -f js/mitgliederverwaltung-main-*.js js/mitgliederverwaltung-main-*.js.LICENSE.txt
npx webpack --node-env production --progress
# Start containers (detached)
up:
docker compose up -d
# Wait for NC to be ready, install it, copy app in, enable it
setup:
@echo "Waiting for Nextcloud container to be ready..."
@until docker compose exec -T nextcloud test -f config/CAN_INSTALL 2>/dev/null || \
docker compose exec -T nextcloud test -f config/config.php 2>/dev/null; do \
sleep 3; \
echo " still waiting..."; \
done
@sleep 5
@echo "Fixing custom_apps ownership..."
docker compose exec nextcloud chown www-data:www-data /var/www/html/custom_apps
@echo "Installing Nextcloud..."
docker compose exec -u www-data nextcloud php occ maintenance:install \
--database=mysql \
--database-host=db \
--database-name=$${MYSQL_DATABASE:-nextcloud} \
--database-user=$${MYSQL_USER:-nextcloud} \
--database-pass=$$(grep MYSQL_PASSWORD .env | head -1 | cut -d= -f2) \
--admin-user=$$(grep NEXTCLOUD_ADMIN_USER .env | cut -d= -f2) \
--admin-pass=$$(grep NEXTCLOUD_ADMIN_PASSWORD .env | cut -d= -f2) \
2>&1 || true
@echo "Copying app into Nextcloud..."
docker compose exec nextcloud mkdir -p /var/www/html/custom_apps/mitgliederverwaltung
docker compose exec nextcloud cp -a /app-src/appinfo /var/www/html/custom_apps/mitgliederverwaltung/
docker compose exec nextcloud cp -a /app-src/lib /var/www/html/custom_apps/mitgliederverwaltung/
docker compose exec nextcloud cp -a /app-src/templates /var/www/html/custom_apps/mitgliederverwaltung/
docker compose exec nextcloud cp -a /app-src/js /var/www/html/custom_apps/mitgliederverwaltung/
docker compose exec nextcloud cp -a /app-src/vendor /var/www/html/custom_apps/mitgliederverwaltung/
docker compose exec nextcloud chown -R www-data:www-data /var/www/html/custom_apps/mitgliederverwaltung
@echo "Enabling app..."
docker compose exec -u www-data nextcloud php occ app:enable mitgliederverwaltung
@echo ""
@echo "Done! Nextcloud is running at http://localhost:8080"
@echo "Login with credentials from .env (NEXTCLOUD_ADMIN_USER / NEXTCLOUD_ADMIN_PASSWORD)"
# Full deploy: build, start, install, enable
deploy: build up setup
# Rebuild and redeploy app into running NC
redeploy: build
docker compose exec nextcloud rm -rf /var/www/html/custom_apps/mitgliederverwaltung
docker compose exec nextcloud mkdir -p /var/www/html/custom_apps/mitgliederverwaltung
docker compose exec nextcloud cp -a /app-src/appinfo /var/www/html/custom_apps/mitgliederverwaltung/
docker compose exec nextcloud cp -a /app-src/lib /var/www/html/custom_apps/mitgliederverwaltung/
docker compose exec nextcloud cp -a /app-src/templates /var/www/html/custom_apps/mitgliederverwaltung/
docker compose exec nextcloud cp -a /app-src/js /var/www/html/custom_apps/mitgliederverwaltung/
docker compose exec nextcloud cp -a /app-src/vendor /var/www/html/custom_apps/mitgliederverwaltung/
docker compose exec nextcloud chown -R www-data:www-data /var/www/html/custom_apps/mitgliederverwaltung
docker compose exec -u www-data nextcloud php occ upgrade 2>/dev/null || true
@echo "App redeployed."
down:
docker compose down
logs:
docker compose logs -f nextcloud
# Create a distributable tar.gz for production installation
package: build
$(eval VERSION := $(shell grep '<version>' appinfo/info.xml | sed 's/.*<version>\(.*\)<\/version>.*/\1/'))
@echo "Packaging mitgliederverwaltung v$(VERSION)..."
mkdir -p artifacts
rm -rf /tmp/mitgliederverwaltung
mkdir -p /tmp/mitgliederverwaltung
cp -a appinfo lib templates js vendor img /tmp/mitgliederverwaltung/
@for f in LICENSE README.md CHANGELOG.md; do \
[ -f "$$f" ] && cp "$$f" /tmp/mitgliederverwaltung/ || true; \
done
cd /tmp && tar -czf mitgliederverwaltung-$(VERSION).tar.gz mitgliederverwaltung
mv /tmp/mitgliederverwaltung-$(VERSION).tar.gz artifacts/
rm -rf /tmp/mitgliederverwaltung
@# Sign the tarball with Ed25519
@if [ -f "$$HOME/.mv-release-key" ]; then \
docker run --rm -v "$$(pwd):/app" -v "$$HOME/.mv-release-key:$$HOME/.mv-release-key:ro" -e HOME="$$HOME" -w /app php:8.1-cli php scripts/sign-release.php artifacts/mitgliederverwaltung-$(VERSION).tar.gz; \
else \
echo "WARNING: ~/.mv-release-key not found — tarball NOT signed."; \
echo " Run: php scripts/generate-keypair.php"; \
fi
@echo ""
@echo "Package created: artifacts/mitgliederverwaltung-$(VERSION).tar.gz"
@echo "Size: $$(du -h artifacts/mitgliederverwaltung-$(VERSION).tar.gz | cut -f1)"
# Build, package, tag, and create a Gitea release with the tarball attached
release: package
$(eval VERSION := $(shell grep '<version>' appinfo/info.xml | sed 's/.*<version>\(.*\)<\/version>.*/\1/'))
@echo "Creating release v$(VERSION) on Gitea..."
git tag -a "v$(VERSION)" -m "Release v$(VERSION)" 2>/dev/null || echo "Tag v$(VERSION) already exists, skipping"
git push origin "v$(VERSION)" 2>/dev/null || echo "Tag already pushed"
@# Create Gitea release via API
@RELEASE_ID=$$(curl -s -X POST \
"https://git.shahondin1624.de/api/v1/repos/shahondin1624/Mitgliederverwaltung/releases" \
-H "Content-Type: application/json" \
-H "Authorization: token $$(cat ~/.gitea-token 2>/dev/null || echo '')" \
-d '{"tag_name": "v$(VERSION)", "name": "v$(VERSION)", "body": "Release v$(VERSION)", "draft": false, "prerelease": false}' \
| python3 -c "import sys,json; print(json.load(sys.stdin).get('id',''))" 2>/dev/null) && \
if [ -n "$$RELEASE_ID" ] && [ "$$RELEASE_ID" != "" ]; then \
echo "Uploading tarball to release $$RELEASE_ID..."; \
curl -s -X POST \
"https://git.shahondin1624.de/api/v1/repos/shahondin1624/Mitgliederverwaltung/releases/$$RELEASE_ID/assets?name=mitgliederverwaltung-$(VERSION).tar.gz" \
-H "Authorization: token $$(cat ~/.gitea-token 2>/dev/null || echo '')" \
-F "attachment=@artifacts/mitgliederverwaltung-$(VERSION).tar.gz" \
>/dev/null && echo " Tarball uploaded."; \
if [ -f "artifacts/mitgliederverwaltung-$(VERSION).tar.gz.sig" ]; then \
curl -s -X POST \
"https://git.shahondin1624.de/api/v1/repos/shahondin1624/Mitgliederverwaltung/releases/$$RELEASE_ID/assets?name=mitgliederverwaltung-$(VERSION).tar.gz.sig" \
-H "Authorization: token $$(cat ~/.gitea-token 2>/dev/null || echo '')" \
-F "attachment=@artifacts/mitgliederverwaltung-$(VERSION).tar.gz.sig" \
>/dev/null && echo " Signature uploaded."; \
else \
echo " WARNING: No .sig file found — release is UNSIGNED."; \
fi; \
echo "Release v$(VERSION) created."; \
else \
echo "WARNING: Could not create Gitea release (missing ~/.gitea-token?). Tarball is in artifacts/."; \
fi
# ── PostgreSQL variant ──────────────────────────────────────────────
up-postgres:
docker compose -f docker/postgres/docker-compose.yml up -d
setup-postgres: build
@echo "Waiting for Nextcloud (PostgreSQL) container to be ready..."
@until docker compose -f docker/postgres/docker-compose.yml exec -T nextcloud test -f config/CAN_INSTALL 2>/dev/null || \
docker compose -f docker/postgres/docker-compose.yml exec -T nextcloud test -f config/config.php 2>/dev/null; do \
sleep 3; \
echo " still waiting..."; \
done
@sleep 5
docker compose -f docker/postgres/docker-compose.yml exec nextcloud chown www-data:www-data /var/www/html/custom_apps
docker compose -f docker/postgres/docker-compose.yml exec -u www-data nextcloud php occ maintenance:install \
--database=pgsql \
--database-host=db \
--database-name=nextcloud \
--database-user=nextcloud \
--database-pass=nextcloud \
--admin-user=admin \
--admin-pass=admin \
2>&1 || true
docker compose -f docker/postgres/docker-compose.yml exec nextcloud mkdir -p /var/www/html/custom_apps/mitgliederverwaltung
docker compose -f docker/postgres/docker-compose.yml exec nextcloud cp -a /app-src/appinfo /var/www/html/custom_apps/mitgliederverwaltung/
docker compose -f docker/postgres/docker-compose.yml exec nextcloud cp -a /app-src/lib /var/www/html/custom_apps/mitgliederverwaltung/
docker compose -f docker/postgres/docker-compose.yml exec nextcloud cp -a /app-src/templates /var/www/html/custom_apps/mitgliederverwaltung/
docker compose -f docker/postgres/docker-compose.yml exec nextcloud cp -a /app-src/js /var/www/html/custom_apps/mitgliederverwaltung/
docker compose -f docker/postgres/docker-compose.yml exec nextcloud cp -a /app-src/vendor /var/www/html/custom_apps/mitgliederverwaltung/
docker compose -f docker/postgres/docker-compose.yml exec nextcloud chown -R www-data:www-data /var/www/html/custom_apps/mitgliederverwaltung
docker compose -f docker/postgres/docker-compose.yml exec -u www-data nextcloud php occ app:enable mitgliederverwaltung
@echo "Done! Nextcloud (PostgreSQL) running at http://localhost:8081"
deploy-postgres: build up-postgres setup-postgres
clean-postgres:
docker compose -f docker/postgres/docker-compose.yml down -v
# ── SQLite variant ──────────────────────────────────────────────────
up-sqlite:
docker compose -f docker/sqlite/docker-compose.yml up -d
setup-sqlite: build
@echo "Waiting for Nextcloud (SQLite) container to be ready..."
@until docker compose -f docker/sqlite/docker-compose.yml exec -T nextcloud test -f config/CAN_INSTALL 2>/dev/null || \
docker compose -f docker/sqlite/docker-compose.yml exec -T nextcloud test -f config/config.php 2>/dev/null; do \
sleep 3; \
echo " still waiting..."; \
done
@sleep 5
docker compose -f docker/sqlite/docker-compose.yml exec nextcloud chown www-data:www-data /var/www/html/custom_apps
docker compose -f docker/sqlite/docker-compose.yml exec -u www-data nextcloud php occ maintenance:install \
--database=sqlite \
--admin-user=admin \
--admin-pass=admin \
2>&1 || true
docker compose -f docker/sqlite/docker-compose.yml exec nextcloud mkdir -p /var/www/html/custom_apps/mitgliederverwaltung
docker compose -f docker/sqlite/docker-compose.yml exec nextcloud cp -a /app-src/appinfo /var/www/html/custom_apps/mitgliederverwaltung/
docker compose -f docker/sqlite/docker-compose.yml exec nextcloud cp -a /app-src/lib /var/www/html/custom_apps/mitgliederverwaltung/
docker compose -f docker/sqlite/docker-compose.yml exec nextcloud cp -a /app-src/templates /var/www/html/custom_apps/mitgliederverwaltung/
docker compose -f docker/sqlite/docker-compose.yml exec nextcloud cp -a /app-src/js /var/www/html/custom_apps/mitgliederverwaltung/
docker compose -f docker/sqlite/docker-compose.yml exec nextcloud cp -a /app-src/vendor /var/www/html/custom_apps/mitgliederverwaltung/
docker compose -f docker/sqlite/docker-compose.yml exec nextcloud chown -R www-data:www-data /var/www/html/custom_apps/mitgliederverwaltung
docker compose -f docker/sqlite/docker-compose.yml exec -u www-data nextcloud php occ app:enable mitgliederverwaltung
@echo "Done! Nextcloud (SQLite) running at http://localhost:8082"
deploy-sqlite: build up-sqlite setup-sqlite
clean-sqlite:
docker compose -f docker/sqlite/docker-compose.yml down -v
# Run all tests inside the Nextcloud container
# Supports: make test [suite=Unit] [suite=Integration] [suite=DatabasePortability]
test:
@if ! docker compose exec -T nextcloud test -f config/config.php 2>/dev/null; then \
echo "ERROR: Nextcloud container is not running."; \
echo " Start it with: make up && make setup"; \
exit 1; \
fi
@# Ensure app code is up to date inside the container
docker compose exec nextcloud cp -a /app-src/appinfo /var/www/html/custom_apps/mitgliederverwaltung/
docker compose exec nextcloud cp -a /app-src/lib /var/www/html/custom_apps/mitgliederverwaltung/
docker compose exec nextcloud cp -a /app-src/tests /var/www/html/custom_apps/mitgliederverwaltung/
docker compose exec nextcloud cp -a /app-src/phpunit.xml /var/www/html/custom_apps/mitgliederverwaltung/
docker compose exec nextcloud chown -R www-data:www-data /var/www/html/custom_apps/mitgliederverwaltung
@# Copy composer vendor dir with dev deps into app for PHPUnit
docker compose exec nextcloud cp -a /app-src/vendor /var/www/html/custom_apps/mitgliederverwaltung/
@# Determine which test suite to run (default: all)
@if [ "$(suite)" = "" ]; then \
echo "Running all tests..."; \
docker compose exec -u www-data -T nextcloud \
php /var/www/html/custom_apps/mitgliederverwaltung/vendor/bin/phpunit \
-c /var/www/html/custom_apps/mitgliederverwaltung/phpunit.xml \
--colors=always; \
else \
echo "Running suite $(suite)..."; \
docker compose exec -u www-data -T nextcloud \
php /var/www/html/custom_apps/mitgliederverwaltung/vendor/bin/phpunit \
-c /var/www/html/custom_apps/mitgliederverwaltung/phpunit.xml \
--testsuite $(suite) \
--colors=always; \
fi
# Remove volumes (full reset)
clean:
docker compose down -v