Some checks failed
CI / Scraper / Test (pull_request) Failing after 9s
CI / UI / Build (pull_request) Failing after 9s
CI / Scraper / Lint (pull_request) Failing after 12s
CI / Scraper / Build (pull_request) Has been skipped
iOS CI / Build (push) Has been cancelled
iOS CI / Test (push) Has been cancelled
iOS CI / Build (pull_request) Failing after 2s
iOS CI / Test (pull_request) Has been skipped
- justfile: extract ios_scheme/ios_sim/ios_spm/runner_temp variables; add ios-resolve (SPM dep cache), ios-archive, ios-export recipes; pipe xcodebuild through xcpretty with raw fallback in ios-build/ios-test - ios.yaml: replace raw xcodebuild calls with just ios-build / just ios-test; install just via brew; uncommented archive job stub now calls just ios-archive && just ios-export; add justfile to path trigger - ci-scraper.yaml: install just via extractions/setup-just@v2; use just lint / just test; fix upload-artifact v3 -> v4; add justfile to path trigger - ci-ui.yaml: install just; use just ui-install / just ui-check / just ui-build; add justfile to path trigger
213 lines
7.9 KiB
Makefile
213 lines
7.9 KiB
Makefile
# justfile — libnovel-v2 task runner
|
|
# Install just: https://just.systems
|
|
|
|
scraper_dir := "scraper"
|
|
ui_dir := "ui"
|
|
ios_dir := "ios/LibNovel"
|
|
ios_scheme := "LibNovel"
|
|
ios_sim := "platform=iOS Simulator,name=iPhone 17"
|
|
ios_spm := ".spm-cache"
|
|
runner_temp := env_var_or_default("RUNNER_TEMP", "/tmp")
|
|
|
|
# ─── Build ────────────────────────────────────────────────────────────────────
|
|
|
|
# Build the scraper binary
|
|
build:
|
|
cd {{scraper_dir}} && go build -o bin/scraper ./cmd/scraper
|
|
|
|
# Build and verify all Go packages compile cleanly
|
|
build-all:
|
|
cd {{scraper_dir}} && go build ./...
|
|
|
|
# ─── Tests ────────────────────────────────────────────────────────────────────
|
|
|
|
# Run unit tests only (no integration services required)
|
|
test:
|
|
cd {{scraper_dir}} && go test -race -count=1 -timeout=60s ./...
|
|
|
|
# Run integration tests (requires MinIO, PocketBase, optional Browserless)
|
|
# Override env vars as needed, e.g.:
|
|
# just test-integration MINIO_ENDPOINT=localhost:9000
|
|
test-integration:
|
|
cd {{scraper_dir}} && go test -v -tags integration -timeout 600s ./...
|
|
|
|
# Run unit + integration tests
|
|
test-all: test test-integration
|
|
|
|
# Run a specific package's integration tests, e.g.:
|
|
# just test-pkg internal/storage
|
|
test-pkg pkg:
|
|
cd {{scraper_dir}} && go test -v -tags integration -timeout 600s ./{{pkg}}/...
|
|
|
|
# Run end-to-end tests against live services.
|
|
# All services must be running first (docker compose up -d or just e2e-up).
|
|
# Override env vars as needed, e.g.:
|
|
# just test-e2e SCRAPER_URL=http://localhost:8080 KOKORO_VOICE=af_bella
|
|
test-e2e \
|
|
browserless_url="http://localhost:3030" \
|
|
minio_endpoint="localhost:9000" \
|
|
pocketbase_url="http://localhost:8090" \
|
|
scraper_url="http://localhost:8080":
|
|
cd {{scraper_dir}} && \
|
|
BROWSERLESS_URL={{browserless_url}} \
|
|
MINIO_ENDPOINT={{minio_endpoint}} \
|
|
POCKETBASE_URL={{pocketbase_url}} \
|
|
SCRAPER_URL={{scraper_url}} \
|
|
go test -v -tags integration -timeout 900s ./internal/e2e/...
|
|
|
|
# Start all services required for e2e tests, then run them
|
|
e2e: up test-e2e
|
|
|
|
# ─── Code quality ─────────────────────────────────────────────────────────────
|
|
|
|
# Run go vet on all packages (including integration build tag)
|
|
lint:
|
|
cd {{scraper_dir}} && go vet ./...
|
|
cd {{scraper_dir}} && go vet -tags integration ./...
|
|
|
|
# ─── UI ───────────────────────────────────────────────────────────────────────
|
|
|
|
# Type-check the SvelteKit UI
|
|
ui-check:
|
|
cd {{ui_dir}} && npx svelte-check
|
|
|
|
# Start the SvelteKit dev server
|
|
ui-dev:
|
|
cd {{ui_dir}} && npm run dev
|
|
|
|
# Install UI dependencies
|
|
ui-install:
|
|
cd {{ui_dir}} && npm install
|
|
|
|
# Build the UI for production
|
|
ui-build:
|
|
cd {{ui_dir}} && npm run build
|
|
|
|
# ─── iOS ──────────────────────────────────────────────────────────────────────
|
|
|
|
# Regenerate LibNovel.xcodeproj from project.yml (run after structural changes)
|
|
ios-gen:
|
|
cd {{ios_dir}} && xcodegen generate --spec project.yml --project .
|
|
|
|
# Resolve SPM package dependencies (cached to {{ios_spm}})
|
|
ios-resolve:
|
|
cd {{ios_dir}} && xcodebuild \
|
|
-project {{ios_scheme}}.xcodeproj \
|
|
-scheme {{ios_scheme}} \
|
|
-resolvePackageDependencies \
|
|
-clonedSourcePackagesDirPath {{ios_spm}}
|
|
|
|
# Build the iOS app for the simulator (no signing required)
|
|
# Runs ios-gen first to ensure the project is up to date.
|
|
ios-build: ios-gen ios-resolve
|
|
cd {{ios_dir}} && set -o pipefail && xcodebuild \
|
|
-project {{ios_scheme}}.xcodeproj \
|
|
-scheme {{ios_scheme}} \
|
|
-configuration Debug \
|
|
-destination 'generic/platform=iOS Simulator' \
|
|
-clonedSourcePackagesDirPath {{ios_spm}} \
|
|
CODE_SIGNING_ALLOWED=NO \
|
|
| xcpretty || xcodebuild \
|
|
-project {{ios_scheme}}.xcodeproj \
|
|
-scheme {{ios_scheme}} \
|
|
-configuration Debug \
|
|
-destination 'generic/platform=iOS Simulator' \
|
|
-clonedSourcePackagesDirPath {{ios_spm}} \
|
|
CODE_SIGNING_ALLOWED=NO
|
|
|
|
# Run unit tests on the simulator
|
|
# Runs ios-gen first to ensure the project is up to date.
|
|
ios-test: ios-gen ios-resolve
|
|
cd {{ios_dir}} && set -o pipefail && xcodebuild test \
|
|
-project {{ios_scheme}}.xcodeproj \
|
|
-scheme {{ios_scheme}} \
|
|
-configuration Debug \
|
|
-destination '{{ios_sim}}' \
|
|
-clonedSourcePackagesDirPath {{ios_spm}} \
|
|
CODE_SIGNING_ALLOWED=NO \
|
|
| xcpretty --report junit --output test-results.xml || true
|
|
|
|
# Archive a signed Release build (requires valid signing identity in keychain).
|
|
# Output: {{runner_temp}}/LibNovel.xcarchive
|
|
# Typically called from CI after importing certificate + provisioning profile.
|
|
ios-archive: ios-gen ios-resolve
|
|
cd {{ios_dir}} && xcodebuild archive \
|
|
-project {{ios_scheme}}.xcodeproj \
|
|
-scheme {{ios_scheme}} \
|
|
-configuration Release \
|
|
-clonedSourcePackagesDirPath {{ios_spm}} \
|
|
-archivePath {{runner_temp}}/LibNovel.xcarchive
|
|
|
|
# Export an IPA from the archive produced by ios-archive.
|
|
# Requires ios/LibNovel/ExportOptions.plist.
|
|
# Output: {{runner_temp}}/ipa/LibNovel.ipa
|
|
ios-export:
|
|
cd {{ios_dir}} && xcodebuild -exportArchive \
|
|
-archivePath {{runner_temp}}/LibNovel.xcarchive \
|
|
-exportPath {{runner_temp}}/ipa \
|
|
-exportOptionsPlist ExportOptions.plist
|
|
|
|
# ─── Docker Compose ───────────────────────────────────────────────────────────
|
|
|
|
# Start all services (browserless, kokoro, scraper, minio, pocketbase)
|
|
up:
|
|
docker compose up -d
|
|
|
|
# Stop all services
|
|
down:
|
|
docker compose down
|
|
|
|
# Tail logs for all services
|
|
logs:
|
|
docker compose logs -f
|
|
|
|
# Tail logs for a specific service, e.g.: just logs-service scraper
|
|
logs-service service:
|
|
docker compose logs -f {{service}}
|
|
|
|
# Rebuild and restart a specific service
|
|
restart service:
|
|
docker compose up -d --build {{service}}
|
|
|
|
# ─── Local dev: individual services ──────────────────────────────────────────
|
|
|
|
# Start only PocketBase (for local storage testing)
|
|
pb-up:
|
|
docker compose up -d pocketbase
|
|
|
|
# Start only MinIO (for local storage testing)
|
|
minio-up:
|
|
docker compose up -d minio
|
|
|
|
# Start only Browserless (for local scraping tests)
|
|
browserless-up:
|
|
docker compose up -d browserless
|
|
|
|
# Start storage backends only (MinIO + PocketBase)
|
|
storage-up:
|
|
docker compose up -d minio pocketbase
|
|
|
|
# ─── Convenience ─────────────────────────────────────────────────────────────
|
|
|
|
# Show status of all docker compose services
|
|
status:
|
|
docker compose ps
|
|
|
|
# Remove all stopped containers and unused images
|
|
prune:
|
|
docker compose down --remove-orphans
|
|
docker image prune -f
|
|
|
|
# One-shot scrape of the full catalogue (requires services to be running)
|
|
scrape-run: build
|
|
cd {{scraper_dir}} && ./bin/scraper run
|
|
|
|
# One-shot scrape of a single book URL, e.g.:
|
|
# just scrape-book https://novelfire.net/book/my-novel
|
|
scrape-book url: build
|
|
cd {{scraper_dir}} && ./bin/scraper run --url {{url}}
|
|
|
|
# Start the HTTP server
|
|
serve: build
|
|
cd {{scraper_dir}} && ./bin/scraper serve
|