Ctrl K
ComunidadGuías…

Makefile

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
.PHONY: help test verify-all check screenshots build-android build-desktop run run-debug clean \
       package-deb package-dmg package-msi package-all \
       release release-patch release-minor release-major _release \
       generate-keystore setup-secrets lint \
       install-hooks version

VERSION ?= $(shell (git describe --tags --abbrev=0 2>/dev/null || echo v1.0.0) | sed 's/^v//')
NEXT_PATCH = $(shell echo $(VERSION) | awk -F. '{printf "%d.%d.%d", $$1, $$2, $$3+1}')
NEXT_MINOR = $(shell echo $(VERSION) | awk -F. '{printf "%d.%d.0", $$1, $$2+1}')
NEXT_MAJOR = $(shell echo $(VERSION) | awk -F. '{printf "%d.0.0", $$1+1}')
SKIP_RELEASE_CHECK ?= 0

help: ## Show this help
	@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | \
		awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}'

# ---------------------------------------------------------------------------
# Gradle invocation (verification targets)
# ---------------------------------------------------------------------------
# The macOS Kotlin compiler daemon writes its `*.alive` flag file to the system
# temp dir (java.io.tmpdir), which the Claude Code sandbox denies with
# "Operation not permitted". Route Kotlin's temp to a project-local dir and
# compile in-process so the verify targets run cleanly under the sandbox. The
# trade-off — no persistent compiler daemon, so slightly slower warm builds — is
# why only the verification targets use this; interactive/packaging targets keep
# plain ./gradlew and its daemon. --no-configuration-cache avoids caching a failed
# sandboxed run (org.gradle.configuration-cache=true is on by default).
KOTLIN_TMP := $(CURDIR)/build/tmp-kotlin
GRADLEW_VERIFY = TMPDIR=$(KOTLIN_TMP) ./gradlew --no-configuration-cache \
	-Dkotlin.compiler.execution.strategy=in-process -Djava.io.tmpdir=$(KOTLIN_TMP)

# Per-source-set ktlint checks. The top-level `ktlintCheck` also scans generated
# Compose resource collectors and is unreliable — see
# docs/patterns/kotlin-multiplatform/testing.md in the workspace.
KTLINT_CHECK_TASKS = shared:runKtlintCheckOverCommonMainSourceSet \
	shared:runKtlintCheckOverAndroidMainSourceSet \
	shared:runKtlintCheckOverJvmMainSourceSet \
	shared:runKtlintCheckOverCommonTestSourceSet \
	shared:runKtlintCheckOverJvmTestSourceSet

$(KOTLIN_TMP):
	@mkdir -p $(KOTLIN_TMP)

# ---------------------------------------------------------------------------
# Development
# ---------------------------------------------------------------------------

test: | $(KOTLIN_TMP) ## Run all tests (JVM)
	$(GRADLEW_VERIFY) shared:jvmTest --stacktrace

verify-all: | $(KOTLIN_TMP) ## Compile every target (jvm+android+ios) and run JVM tests
	$(GRADLEW_VERIFY) \
		shared:compileKotlinJvm \
		shared:compileAndroidMain \
		shared:compileKotlinIosArm64 \
		shared:jvmTest --stacktrace

screenshots: ## Regenerate documentation screenshots into screenshots/companionapp
	./gradlew shared:jvmTest --tests "com.pulseweaver.heartbeat.ui.DocScreenshotsTest" \
		-Dpw.screenshots=true --rerun-tasks

lint: | $(KOTLIN_TMP) ## Run ktlint (per-source-set; top-level ktlintCheck is unreliable)
	$(GRADLEW_VERIFY) $(KTLINT_CHECK_TASKS)

run: ## Run desktop app
	./gradlew :shared:run

# Debug interval in seconds for `run-debug` (override: make run-debug PW_INTERVAL=10)
PW_INTERVAL ?= 5
run-debug: ## Run desktop app in debug mode (verbose logs + PW_INTERVAL beat, default 5s)
	PW_DEBUG=1 PW_INTERVAL=$(PW_INTERVAL) ./gradlew :shared:run

clean: ## Clean build outputs
	./gradlew clean

check: lint test ## Lint + tests

# ---------------------------------------------------------------------------
# Build
# ---------------------------------------------------------------------------

build-android: ## Build Android debug APK
	./gradlew assembleDebug --stacktrace

build-android-release: ## Build Android release APK (requires keystore env vars)
	./gradlew assembleRelease -PappVersion=$(VERSION) --stacktrace

build-desktop: ## Compile desktop JVM target
	./gradlew :shared:compileKotlinJvm --stacktrace

# ---------------------------------------------------------------------------
# Package native installers
# ---------------------------------------------------------------------------

package-deb: ## Package Linux .deb
	./gradlew :shared:packageDeb -PappVersion=$(VERSION) --stacktrace

package-dmg: ## Package macOS .dmg
	./gradlew :shared:packageDmg -PappVersion=$(VERSION) --stacktrace

package-msi: ## Package Windows .msi
	./gradlew :shared:packageMsi -PappVersion=$(VERSION) --stacktrace

package-all: package-deb package-dmg package-msi build-android-release ## Build all platform packages

# ---------------------------------------------------------------------------
# Release
# ---------------------------------------------------------------------------

release-patch: ## Changelog → commit → tag → push (patch: x.y.Z+1)
	@$(MAKE) _release V=$(NEXT_PATCH)

release-minor: ## Changelog → commit → tag → push (minor: x.Y+1.0)
	@$(MAKE) _release V=$(NEXT_MINOR)

release-major: ## Changelog → commit → tag → push (major: X+1.0.0)
	@$(MAKE) _release V=$(NEXT_MAJOR)

# Internal: run as $(MAKE) _release V=x.y.z — never call directly
_release:
	@git diff --quiet && git diff --staged --quiet || (echo "❌ Dirty working tree — commit or stash changes first" && exit 1)
	@echo "Current: v$(VERSION) → Next: v$(V)"
	@read -p "Confirm? [y/N] " confirm && [ "$$confirm" = "y" ] || exit 1
	@if [ "$(SKIP_RELEASE_CHECK)" != "1" ]; then $(MAKE) check; fi
	git-cliff --unreleased --tag "v$(V)" --prepend CHANGELOG.md
	@echo "Review and edit CHANGELOG.md before continuing"
	@read -p "Continue? [y/N] " confirm && [ "$$confirm" = "y" ] || exit 1
	git add CHANGELOG.md
	git diff --staged --quiet || git commit -m "chore: release v$(V)"
	git tag -a "v$(V)" -m "Release v$(V)"
	git push origin main --tags

# ---------------------------------------------------------------------------
# Setup
# ---------------------------------------------------------------------------

version: ## Show current version
	@echo "v$(VERSION)"

generate-keystore: ## Generate a new Android release keystore
	@if [ -f release.keystore ]; then echo "release.keystore already exists"; exit 1; fi
	keytool -genkeypair -v -keystore release.keystore -alias pulseweaver \
		-keyalg RSA -keysize 2048 -validity 10000 \
		-dname "CN=PulseWeaver, O=PulseWeaver"
	@echo ""
	@echo "Created release.keystore — keep this file safe and never commit it."
	@echo "To set up GitHub Secrets, run: make setup-secrets"

setup-secrets: ## Print instructions for GitHub Actions secrets
	@echo ""
	@echo "Add these secrets to your GitHub repo (Settings → Secrets → Actions):"
	@echo ""
	@echo "  KEYSTORE_BASE64     base64 < release.keystore | pbcopy  (or base64 -w0 on Linux)"
	@echo "  KEYSTORE_PASSWORD   the password you chose during keytool"
	@echo "  KEY_ALIAS           pulseweaver  (or whatever alias you used)"
	@echo ""

# ---------------------------------------------------------------------------
# Hooks
# ---------------------------------------------------------------------------

install-hooks: ## Install git hooks (run once after cloning)
	@ln -sf "$(PWD)/scripts/commit-msg" "$(PWD)/.git/hooks/commit-msg"
	@chmod +x "$(PWD)/.git/hooks/commit-msg"
	@echo "✅ Git hooks installed."