diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 24a73d9..6664f2a 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -12,8 +12,8 @@ env: IMAGE_NAME: whilesmartphp/laravel-dev jobs: - build-and-push: - runs-on: ubuntu-latest + build: + runs-on: ${{ matrix.runner }} permissions: contents: read packages: write @@ -21,6 +21,11 @@ jobs: strategy: matrix: php_version: ['8.2', '8.4'] + include: + - runner: ubuntu-latest + platform: linux/amd64 + - runner: ubuntu-24.04-arm + platform: linux/arm64 steps: - name: Checkout @@ -36,6 +41,64 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 + - name: Build and push by digest + id: build + uses: docker/build-push-action@v6 + with: + context: . + platforms: ${{ matrix.platform }} + build-args: | + PHP_VERSION=${{ matrix.php_version }} + cache-from: type=gha,scope=${{ matrix.php_version }}-${{ matrix.platform }} + cache-to: type=gha,mode=max,scope=${{ matrix.php_version }}-${{ matrix.platform }} + outputs: type=image,name=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }},push-by-digest=true,name-canonical=true,push=${{ github.event_name != 'pull_request' }} + + - name: Export digest + if: github.event_name != 'pull_request' + run: | + mkdir -p /tmp/digests/${{ matrix.php_version }} + digest="${{ steps.build.outputs.digest }}" + touch "/tmp/digests/${{ matrix.php_version }}/${digest#sha256:}" + + - name: Upload digest + if: github.event_name != 'pull_request' + uses: actions/upload-artifact@v4 + with: + name: digest-${{ matrix.php_version }}-${{ matrix.runner }} + path: /tmp/digests/${{ matrix.php_version }} + if-no-files-found: error + retention-days: 1 + + merge: + runs-on: ubuntu-latest + if: github.event_name != 'pull_request' + needs: build + permissions: + contents: read + packages: write + + strategy: + matrix: + php_version: ['8.2', '8.4'] + + steps: + - name: Log in to Container Registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Download digests + uses: actions/download-artifact@v4 + with: + pattern: digest-${{ matrix.php_version }}-* + merge-multiple: true + path: /tmp/digests + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Extract metadata id: meta uses: docker/metadata-action@v5 @@ -45,14 +108,12 @@ jobs: type=raw,value=${{ matrix.php_version }} type=raw,value=${{ matrix.php_version }}-{{sha}} - - name: Build and push - uses: docker/build-push-action@v6 - with: - context: . - push: ${{ github.event_name != 'pull_request' }} - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - build-args: | - PHP_VERSION=${{ matrix.php_version }} - cache-from: type=gha - cache-to: type=gha,mode=max + - name: Create manifest list and push + working-directory: /tmp/digests + run: | + docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ + $(printf '${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@sha256:%s ' *) + + - name: Inspect image + run: | + docker buildx imagetools inspect ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ matrix.php_version }} diff --git a/README.md b/README.md index 926adc7..10b42a9 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,43 @@ include laravel.mk Port resolution is automatic — `make up` finds available ports starting from 8000 and stores them in `.ports`. +### Customizing for Your Project + +`laravel.mk` exposes hook variables you can set **before** the `include` to customize behavior without overriding targets: + +```makefile +# Extra port defaults +DEFAULT_DB_PORT ?= 3306 +DEFAULT_PMA_PORT ?= 8080 + +# Add extra ports to .ports file +EXTRA_PORTS_SCRIPT = \ + DB_PORT=$$(port=$(DEFAULT_DB_PORT); while nc -z 127.0.0.1 $$port 2>/dev/null || lsof -i :$$port >/dev/null 2>&1; do port=$$((port + 1)); done; echo $$port); \ + PMA_PORT=$$(port=$(DEFAULT_PMA_PORT); while nc -z 127.0.0.1 $$port 2>/dev/null || lsof -i :$$port >/dev/null 2>&1; do port=$$((port + 1)); done; echo $$port); \ + echo "FORWARD_DB_PORT=$$DB_PORT" >> $(PORTS_FILE); \ + echo "PMA_PORT=$$PMA_PORT" >> $(PORTS_FILE); + +# Show extra service URLs on 'make up' +EXTRA_UP_INFO = \ + echo " phpMyAdmin: http://localhost:$$PMA_PORT" && \ + echo " MySQL: localhost:$$FORWARD_DB_PORT" + +# Custom test and lint commands +TEST_CMD = php artisan test --coverage +LINT_CMD = composer phpcs:test && composer phpmd && composer pint:test + +include laravel.mk + +# Add project-specific targets below +``` + +| Variable | Default | Description | +|----------|---------|-------------| +| `EXTRA_PORTS_SCRIPT` | *(empty)* | Shell script appended to `.ports` generation | +| `EXTRA_UP_INFO` | *(empty)* | Extra `echo` commands shown after `make up` | +| `TEST_CMD` | `php artisan test` | Command used by `make test` | +| `LINT_CMD` | `composer pint:test` | Command used by `make lint` | + ### Available Targets | Target | Description | diff --git a/laravel.mk b/laravel.mk index d1573dc..6a6e540 100644 --- a/laravel.mk +++ b/laravel.mk @@ -12,6 +12,18 @@ define find_port $(shell port=$(1); while nc -z 127.0.0.1 $$port 2>/dev/null || lsof -i :$$port >/dev/null 2>&1; do port=$$((port + 1)); done; echo $$port) endef +# Projects can define EXTRA_PORTS_SCRIPT to add additional port assignments. +# Example: EXTRA_PORTS_SCRIPT = DB_PORT=$$(call find_port,3306); echo "DB_PORT=$$DB_PORT" >> $(PORTS_FILE); +EXTRA_PORTS_SCRIPT ?= + +# Projects can define EXTRA_UP_INFO to show additional service URLs after 'make up'. +# Example: EXTRA_UP_INFO = echo " MySQL: localhost:$$FORWARD_DB_PORT" +EXTRA_UP_INFO ?= + +# Projects can override TEST_CMD and LINT_CMD for custom test/lint behavior. +TEST_CMD ?= php artisan test +LINT_CMD ?= composer pint:test + .ports: @echo "Finding available ports..." @echo "# Auto-generated port assignments" > $(PORTS_FILE) @@ -20,17 +32,19 @@ endef MAILHOG_UI_PORT=$(call find_port,$(DEFAULT_MAILHOG_UI_PORT)); \ echo "APP_PORT=$$APP_PORT" >> $(PORTS_FILE); \ echo "MAILHOG_SMTP_PORT=$$MAILHOG_SMTP_PORT" >> $(PORTS_FILE); \ - echo "MAILHOG_UI_PORT=$$MAILHOG_UI_PORT" >> $(PORTS_FILE) + echo "MAILHOG_UI_PORT=$$MAILHOG_UI_PORT" >> $(PORTS_FILE); \ + $(EXTRA_PORTS_SCRIPT) @echo "Port assignments saved to $(PORTS_FILE)" -DC = $(shell if [ -f $(PORTS_FILE) ]; then cat $(PORTS_FILE) | tr '\n' ' '; fi) HOST_UID=$(HOST_UID) HOST_GID=$(HOST_GID) docker compose +DC = $(shell if [ -f $(PORTS_FILE) ]; then grep -v "^\#" $(PORTS_FILE) | xargs; fi) HOST_UID=$(HOST_UID) HOST_GID=$(HOST_GID) docker compose EXEC = $(DC) exec --user www-data app up: .ports ## Start the application @. ./$(PORTS_FILE) && $(DC) up -d @. ./$(PORTS_FILE) && echo "Services running on:" && \ echo " App: http://localhost:$$APP_PORT" && \ - echo " MailHog: http://localhost:$$MAILHOG_UI_PORT" + echo " MailHog: http://localhost:$$MAILHOG_UI_PORT" && \ + $(if $(EXTRA_UP_INFO),$(EXTRA_UP_INFO),:) setup: up composer-install ## First-time setup $(EXEC) php artisan key:generate @@ -59,10 +73,10 @@ composer-update: ## Update composer dependencies $(EXEC) composer update test: ## Run tests - $(EXEC) php artisan test + $(EXEC) $(TEST_CMD) lint: ## Check code formatting - $(EXEC) composer pint:test + $(EXEC) $(LINT_CMD) lint-fix: ## Fix code formatting $(EXEC) composer pint @@ -108,4 +122,4 @@ help: ## Show this help message @echo 'Usage: make [target]' @echo '' @echo 'Targets:' - @egrep '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-20s\033[0m %s\n", $$1, $$2}' + @egrep '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sed 's/^[^:]*://' | sort -u | awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-20s\033[0m %s\n", $$1, $$2}'