-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathMakefile
More file actions
153 lines (134 loc) · 7.27 KB
/
Copy pathMakefile
File metadata and controls
153 lines (134 loc) · 7.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
.PHONY: build test lint lint-js quality cover-gaps hooks vet clean sidecar sidecar-test release release-signed release-all npm stage sign package drivers
BINARY := devicedeck
PKG := github.com/devicelab-dev/DeviceDeck
VERSION ?= dev
COMMIT := $(shell git rev-parse --short HEAD 2>/dev/null || echo none)
LDFLAGS := -X $(PKG)/internal/version.Version=$(VERSION) -X $(PKG)/internal/version.Commit=$(COMMIT)
# ARCH is the macOS architecture a release is built for: arm64 or x86_64 (the
# names the install script uses). It defaults to this Mac's, and release-all
# builds both on one machine.
ARCH ?= $(shell uname -m)
GOARCH := $(if $(filter x86_64,$(ARCH)),amd64,arm64)
DIST := dist/$(BINARY)-$(VERSION)-darwin-$(ARCH)
# RELEASE_DIR holds one release, ready to upload to devicedeck/<version>/ —
# the path the install script downloads from: each archive with an
# <archive>.sha256 beside it.
RELEASE_DIR := dist/$(VERSION)
SIDECAR_BIN = $(shell swift build --package-path sidecar -c release --arch $(ARCH) --show-bin-path)
# -trimpath strips filesystem paths (module-cache and repo paths under
# /Users/…) from the binary, so panic stack traces and debug info carry
# module@version paths, not the author's home directory.
build:
go build -trimpath -o $(BINARY) ./cmd/devicedeck
test:
go test ./... -race -coverprofile=coverage.out
go tool cover -func=coverage.out | tail -1
sidecar:
swift build --package-path sidecar -c release
sidecar-test:
swift test --package-path sidecar
# lint runs the full linter set across the whole tree. gofmt is checked as a
# hard failure (not just listed), then the token-slice guard, then golangci-lint.
lint:
@unformatted=$$(gofmt -l . | grep -vE '^\.claude/|^\.git/' || true); \
if [ -n "$$unformatted" ]; then echo "gofmt needs: $$unformatted"; exit 1; fi
bash scripts/lint-token-slice.sh
go vet ./...
golangci-lint run ./...
# lint-js lints and type-checks the console and device page scripts
# (internal/web/static). Needs `npm install` once; the files are served as-is.
lint-js:
npm run lint:js
npm run typecheck:device
# quality is the fast gate that runs on every code change: it checks only what
# changed against HEAD, so it stays quick. This is what the pre-commit hook and
# the /code-quality command call. Pass ALL=1 to sweep the whole tree instead.
quality:
bash scripts/check-quality.sh $(if $(ALL),--all,)
# cover-gaps lists hand-written Go files that are below 100% statement coverage
# — the non-negotiable target for changed files. Generated files are excluded.
cover-gaps:
@go test ./... -coverprofile=coverage.out >/dev/null 2>&1 || true
@go tool cover -func=coverage.out | awk '$$3 != "100.0%" && $$1 !~ /\.pb\.go|_generated\.go/ && $$1 != "total:" {print}' \
| sort -t% -k1 || echo " all changed files at 100%"
# hooks installs the pre-commit quality gate into this clone's .git/hooks.
# Run once after cloning so the gate runs on every commit.
hooks:
@printf '#!/usr/bin/env bash\nexec bash scripts/check-quality.sh\n' > .git/hooks/pre-commit
@chmod +x .git/hooks/pre-commit
@echo "installed .git/hooks/pre-commit → scripts/check-quality.sh"
# oldlint keeps the original quick vet available under a plain name.
vet:
go vet ./...
# drivers re-copies the Android driver APKs and the prebuilt iOS agent from
# the pinned maestro-runner module into the binary's embed folders. Run it
# after every maestro-runner bump; a test fails until the two match.
RUNNER_MOD := github.com/devicelab-dev/maestro-runner
drivers:
@src="$$(go list -m -f '{{.Dir}}' $(RUNNER_MOD))/drivers/android"; \
for apk in devicelab-android-driver.apk devicelab-android-driver-test.apk; do \
install -m 0644 "$$src/$$apk" internal/home/android/$$apk; \
done; echo "synced driver APKs from $$src"
@src="$$(go list -m -f '{{.Dir}}' $(RUNNER_MOD))/drivers/ios/devicelab-ios-agent/simulator"; \
dst=internal/home/ios/devicelab-ios-agent/simulator; \
mkdir -p $$dst && rsync -r --delete "$$src/" $$dst/ && chmod -R u+w $$dst; \
echo "synced iOS agent from $$src"
@# The agents are proprietary binaries whose licence must travel with them.
@install -m 0644 "$$(go list -m -f '{{.Dir}}' $(RUNNER_MOD))/drivers/LICENSE-BINARIES.md" internal/home/LICENSE-BINARIES.md; \
echo "synced driver binary licence"
# stage lays the archive out the way it is installed: the three binaries in
# bin/ (the server finds each sidecar next to its own executable), the
# licence files beside it. The Android driver is embedded in the binary, so
# nothing else ships. macOS only — the sidecars talk to CoreSimulator.
stage:
swift build --package-path sidecar -c release --arch $(ARCH)
GOOS=darwin GOARCH=$(GOARCH) CGO_ENABLED=0 go build -trimpath -ldflags "$(LDFLAGS) -s -w" -o $(DIST)/bin/$(BINARY) ./cmd/devicedeck
cp $(SIDECAR_BIN)/devicedeck-hid $(SIDECAR_BIN)/devicedeck-video $(DIST)/bin/
# Scrub any absolute local paths (embedded dep contents, Swift build paths)
# and fail the build if any survive. Runs before signing.
./scripts/redact-local-paths.sh $(DIST)/bin
# The archive is a distribution, so it carries the terms with it:
# Apache-2.0 asks that recipients get the licence, and the upstream
# notices travel with the sidecars they describe.
cp LICENSE ATTRIBUTION.md README.md internal/home/LICENSE-BINARIES.md $(DIST)/
# sign signs and notarizes the staged binaries in place (a no-op without
# DEVELOPER_ID, so it is safe to call on a dev machine).
sign:
./scripts/macos-sign-notarize.sh $(DIST)/bin
# package tars the staged (and possibly signed) dir for distribution, and
# copies it into RELEASE_DIR with its checksum, which the install script
# verifies ("<sha256> <archive>", as shasum writes it).
package:
cd dist && tar czf $(notdir $(DIST)).tar.gz $(notdir $(DIST))
mkdir -p $(RELEASE_DIR)
cp $(DIST).tar.gz $(RELEASE_DIR)/
cd $(RELEASE_DIR) && shasum -a 256 $(notdir $(DIST)).tar.gz > $(notdir $(DIST)).tar.gz.sha256
@echo "packaged $(RELEASE_DIR)/$(notdir $(DIST)).tar.gz (+ .sha256)"
# release and release-signed both sign before tarring: with DEVELOPER_ID set
# the binaries are signed and notarized (Gatekeeper-clean); without it they
# are ad-hoc signed, which redaction makes mandatory — Apple Silicon kills a
# binary whose bytes no longer match its signature.
release: stage sign package
release-signed: release
# release-all builds, signs, notarizes and packages both macOS architectures
# on this Mac, into RELEASE_DIR, ready to upload — the maestro-runner release
# shape. Signing uses scripts/macos-sign-notarize.sh, so it reads the
# Developer ID and notarization credentials from the environment or the
# keychain, never from this file; without them the archives are ad-hoc signed.
# make release-all VERSION=0.1.1
release-all:
@if [ "$(VERSION)" = dev ]; then echo "set a version: make release-all VERSION=0.1.1"; exit 1; fi
rm -rf $(RELEASE_DIR)
$(MAKE) release VERSION=$(VERSION) ARCH=arm64
$(MAKE) release VERSION=$(VERSION) ARCH=x86_64
@echo; echo "ready to upload:"; ls -l $(RELEASE_DIR)
# npm builds DeviceDeck's npm packages from a release in dist/<version>/:
# devicedeck (the launcher people install) and one @devicelab/devicedeck-darwin-*
# package per Mac architecture, carrying that release's signed binaries.
# It does not publish; it prints the publish commands.
# make npm VERSION=0.1.1
npm:
VERSION=$(VERSION) ./npm/build-npm.sh
clean:
rm -f $(BINARY) coverage.out
rm -rf sidecar/.build dist