-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMakefile
More file actions
135 lines (124 loc) · 6.92 KB
/
Makefile
File metadata and controls
135 lines (124 loc) · 6.92 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
# Makefile -- 1mb-dev/log reference deployment of markgo at log.1mb.dev.
#
# Targets:
# help Show this message.
# fetch-markgo Build the markgo binary into ./build/markgo.
# build Verify the deploy bundle is ready.
# deploy Push to a VPS, install systemd unit, restart, smoke-test.
# verify Run scripts/verify-deploy.sh against DOMAIN.
# clean Remove build artifacts.
#
# Tunables (env vars or make variables):
# MARKGO_REF Git ref of markgo to clone (only used when MARKGO_SRC is absent).
# Default: v3.17.0.
# MARKGO_SRC Path to a local markgo checkout. If present, builds the currently
# checked-out ref; if absent, MARKGO_REF is cloned to build/markgo-src.
# Default: ../markgo.
# GOOS, GOARCH Build target. Default: linux/amd64.
#
# Deploy tunables -- defaults match log.1mb.dev's production. Forkers override.
# DOMAIN Required. Public hostname. Example: log.1mb.dev.
# SSH_TARGET SSH destination for privileged ops. Default: root@$(DOMAIN).
# DEPLOY_USER System user that owns the deploy tree and runs markgo.
# Default: loguser. Forkers often pick `markgo` instead.
# DEPLOY_PATH Install prefix on the VPS. Default: /opt/$(DOMAIN).
# SERVICE_NAME Systemd unit basename. Default: log (=> log.service).
#
# Note: markgo releases ship linux/amd64, darwin/amd64, and windows/amd64
# binaries as of v3.17.0. This Makefile still builds from source so forkers can
# pin to any tag or commit and inspect the build line. A curl-based fetch of
# the published artifacts is a future simplification.
MARKGO_REF ?= v3.18.1
MARKGO_SRC ?= ../markgo
GOOS ?= linux
GOARCH ?= amd64
BUILD_DIR := build
BINARY := $(BUILD_DIR)/markgo
DOMAIN ?=
SSH_TARGET ?= root@$(DOMAIN)
DEPLOY_USER ?= loguser
DEPLOY_PATH ?= /opt/$(DOMAIN)
SERVICE_NAME ?= log
.PHONY: help fetch-markgo build deploy verify clean pull-from-vps confirm-env
help: ## Show this help
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf " \033[36m%-15s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)
fetch-markgo: ## Build the markgo binary for $(GOOS)/$(GOARCH)
@mkdir -p $(BUILD_DIR)
@if [ -d "$(MARKGO_SRC)" ]; then \
echo "==> Using local markgo checkout at $(MARKGO_SRC) (current ref)"; \
GOOS=$(GOOS) GOARCH=$(GOARCH) $(MAKE) -C $(MARKGO_SRC) build; \
cp $(MARKGO_SRC)/build/markgo $(BINARY); \
else \
echo "==> Cloning markgo $(MARKGO_REF) into $(BUILD_DIR)/markgo-src"; \
rm -rf $(BUILD_DIR)/markgo-src; \
git clone --depth 1 --branch $(MARKGO_REF) https://github.com/1mb-dev/markgo.git $(BUILD_DIR)/markgo-src; \
GOOS=$(GOOS) GOARCH=$(GOARCH) $(MAKE) -C $(BUILD_DIR)/markgo-src build; \
cp $(BUILD_DIR)/markgo-src/build/markgo $(BINARY); \
fi
@echo "==> Built $(BINARY) ($(GOOS)/$(GOARCH))"
build: fetch-markgo ## Verify the deploy bundle is ready
@test -x $(BINARY) || { echo "missing $(BINARY); run make fetch-markgo"; exit 1; }
@if ! strings $(BINARY) | grep -Fxq "$(MARKGO_REF)"; then \
echo "==> stamp mismatch: $(BINARY) does not embed $(MARKGO_REF) as a clean tag."; \
echo " Likely cause: $(MARKGO_SRC) is past the $(MARKGO_REF) tag (e.g. one commit ahead on main)."; \
echo " Fix: MARKGO_SRC=__none__ make fetch-markgo (forces clone of $(MARKGO_REF)),"; \
echo " or check out $(MARKGO_REF) in $(MARKGO_SRC) before building."; \
exit 1; \
fi
@ls articles/*.md >/dev/null 2>&1 || echo "warn: articles/ is empty -- replace _example.md before deploy"
@echo "==> Ready: $(BINARY) (stamped $(MARKGO_REF)) + articles/ + static/"
confirm-env: ## Pre-flight: surface local .env state, prompt to proceed
@test -f .env || { echo "missing .env -- cp .env.example .env, fill in values, then retry"; exit 1; }
@echo "==> Pre-flight: local .env is mirrored to prod (overwrites $(SSH_TARGET):$(DEPLOY_PATH)/.env)"
@env_mtime=$$(stat -f '%Sm' -t '%Y-%m-%d %H:%M' .env 2>/dev/null || stat -c '%y' .env 2>/dev/null | cut -d. -f1); \
env_lines=$$(wc -l < .env | tr -d ' '); \
echo " local .env: $${env_lines} lines, last modified $${env_mtime}"; \
echo " If env vars need adding or changing, abort, edit local .env, retry."; \
printf " Proceed with this .env? [y/N] "; \
read ans; \
case "$$ans" in [yY]|[yY][eE][sS]) ;; *) echo " aborted"; exit 1 ;; esac
deploy: confirm-env build ## Deploy to DOMAIN: push binary + content + .env, install unit, restart, verify
@test -n "$(DOMAIN)" || { echo "usage: make deploy DOMAIN=your.domain.example"; exit 1; }
@echo "==> deploy: $(SSH_TARGET):$(DEPLOY_PATH) (user=$(DEPLOY_USER), service=$(SERVICE_NAME))"
@mkdir -p $(BUILD_DIR)
@sed -e 's|/opt/log.1mb.dev|$(DEPLOY_PATH)|g' \
-e 's|^User=markgo|User=$(DEPLOY_USER)|' \
-e 's|^Group=markgo|Group=$(DEPLOY_USER)|' \
-e 's|^SyslogIdentifier=log|SyslogIdentifier=$(SERVICE_NAME)|' \
deploy/log.service.example > $(BUILD_DIR)/$(SERVICE_NAME).service
@echo "==> Provision (idempotent)"
@ssh $(SSH_TARGET) " \
id $(DEPLOY_USER) >/dev/null 2>&1 || useradd --system --no-create-home --shell /bin/false $(DEPLOY_USER); \
mkdir -p $(DEPLOY_PATH)/articles $(DEPLOY_PATH)/static $(DEPLOY_PATH)/uploads $(DEPLOY_PATH)/logs; \
mkdir -p /tmp/$(SERVICE_NAME)-bundle"
@echo "==> Sync binary + .env + unit"
@rsync -a $(BINARY) .env $(BUILD_DIR)/$(SERVICE_NAME).service $(SSH_TARGET):/tmp/$(SERVICE_NAME)-bundle/
@echo "==> Sync content (articles additive; static mirrored)"
@rsync -a articles/ $(SSH_TARGET):$(DEPLOY_PATH)/articles/
@rsync -a --delete static/ $(SSH_TARGET):$(DEPLOY_PATH)/static/
@echo "==> Install + restart"
@ssh $(SSH_TARGET) " \
install -o $(DEPLOY_USER) -g $(DEPLOY_USER) -m 0755 /tmp/$(SERVICE_NAME)-bundle/markgo $(DEPLOY_PATH)/markgo && \
install -o $(DEPLOY_USER) -g $(DEPLOY_USER) -m 0600 /tmp/$(SERVICE_NAME)-bundle/.env $(DEPLOY_PATH)/.env && \
chown -R $(DEPLOY_USER):$(DEPLOY_USER) $(DEPLOY_PATH) && \
install -m 0644 /tmp/$(SERVICE_NAME)-bundle/$(SERVICE_NAME).service /etc/systemd/system/$(SERVICE_NAME).service && \
systemctl daemon-reload && \
systemctl enable $(SERVICE_NAME) >/dev/null 2>&1 && \
systemctl restart $(SERVICE_NAME) && \
systemctl is-active $(SERVICE_NAME) >/dev/null && \
rm -rf /tmp/$(SERVICE_NAME)-bundle"
@echo "==> Verify"
@sleep 2
@./scripts/verify-deploy.sh $(DOMAIN)
verify: ## Run smoke tests against DOMAIN
@test -n "$(DOMAIN)" || { echo "usage: make verify DOMAIN=your.domain.example"; exit 1; }
@./scripts/verify-deploy.sh $(DOMAIN)
clean: ## Remove build artifacts
rm -rf $(BUILD_DIR)
pull-from-vps: ## Pull VPS-authored content (articles/) back to local clone
@test -n "$(DOMAIN)" || { echo "usage: make pull-from-vps DOMAIN=your.domain.example"; exit 1; }
@echo "==> pull articles/ from $(DEPLOY_USER)@$(DOMAIN):$(DEPLOY_PATH)/articles/"
@rsync -av $(DEPLOY_USER)@$(DOMAIN):$(DEPLOY_PATH)/articles/ articles/
@echo ""
@echo "==> git status articles/ (review + commit if anything new):"
@git status --short articles/ || true