-
Notifications
You must be signed in to change notification settings - Fork 74
Expand file tree
/
Copy pathMakefile
More file actions
224 lines (191 loc) · 9.11 KB
/
Copy pathMakefile
File metadata and controls
224 lines (191 loc) · 9.11 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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
# Copyright (c) Microsoft Corporation.
# Licensed under the PostgreSQL License.
# pg_durable Makefile
# PostgreSQL major version for pgrx (override with: make ... PG_VERSION=pg18)
PG_VERSION ?= pg17
CARGO ?= cargo
EXTRA_FEATURES ?=
ACR_REGISTRY ?= myregistry.azurecr.io
ACR_IMAGE ?= pg_durable
.PHONY: all build package install uninstall test test-unit test-e2e test-regress pg-clean docker-build docker-push pg-install pgxn-zip
# Default target
all: package
# Build the extension
build:
cargo build
# Build release artifacts for source installation. This runs without elevated
# privileges; `install` only copies the resulting package tree.
package:
@if test -e "$(PGRX_PACKAGE_DIR)" \
&& test "$(PGRX_PACKAGE_DIR)" != "$(DEFAULT_PGRX_PACKAGE_DIR)" \
&& test ! -f "$(PGRX_PACKAGE_MARKER)" \
&& { test ! -d "$(PGRX_PACKAGE_DIR)" \
|| test -n "$$(ls -A "$(PGRX_PACKAGE_DIR)" 2>/dev/null)"; }; then \
echo "refusing to replace unowned package directory: $(PGRX_PACKAGE_DIR)" >&2; \
exit 1; \
fi
rm -rf "$(PGRX_PACKAGE_DIR)"
$(CARGO) pgrx package --pg-config "$(PG_CONFIG)" \
--out-dir "$(PGRX_PACKAGE_DIR)" \
--no-default-features --features "$(strip pg$(PG_MAJOR) $(EXTRA_FEATURES))"
@touch "$(PGRX_PACKAGE_MARKER)"
# Run all tests (unit + E2E)
test:
./scripts/test.sh --all
# Run only pgrx unit tests
test-unit:
./scripts/test.sh --unit
# Run only E2E tests (Docker-based)
test-e2e:
./scripts/test.sh --e2e
# Build Docker image
docker-build:
docker build --platform linux/amd64 -t pg_durable:latest .
# Build and push to ACR
docker-push: docker-build
docker tag pg_durable:latest $(ACR_REGISTRY)/$(ACR_IMAGE):latest
REGISTRY_NAME="$(ACR_REGISTRY)"; az acr login --name "$${REGISTRY_NAME%%.*}"
docker push $(ACR_REGISTRY)/$(ACR_IMAGE):latest
# Run local development server
run:
cargo pgrx run pg17
# Clean build artifacts (renamed to avoid PGXS conflict)
pg-clean:
cargo clean
rm -rf target/
rm -f META.json $(DISTNAME)-$(DISTVERSION).zip
# Install extension locally (renamed to avoid PGXS conflict)
pg-install:
cargo pgrx install --features http-allow-test-domains
# Run pg_regress tests (convenience target)
# Override version: make test-regress PG_VERSION=pg18
test-regress:
@echo "Resetting PostgreSQL..."
./scripts/pg-reset.sh $(subst pg,,$(PG_VERSION))
@echo "Starting PostgreSQL with PGDATABASE=contrib_regression..."
PGDATABASE=contrib_regression ./scripts/pg-start.sh --pg-version $(subst pg,,$(PG_VERSION))
@echo "Running pg_regress tests..."
PGHOST=$(HOME)/.pgrx PGUSER=postgres PG_CONFIG=$$(cargo pgrx info pg-config $(PG_VERSION)) $(MAKE) -e installcheck
# Help
help:
@echo "pg_durable Makefile targets:"
@echo ""
@echo " all - Build release artifacts for source installation"
@echo " build - Build the extension in debug mode"
@echo " package - Build release artifacts for source installation"
@echo " test - Run all tests (unit + E2E)"
@echo " test-unit - Run pgrx unit tests only"
@echo " test-e2e - Run E2E tests only (Docker)"
@echo " test-regress - Run pg_regress tests (resets and starts PostgreSQL)"
@echo " installcheck - Run pg_regress tests (requires PostgreSQL running, via PGXS)"
@echo " docker-build - Build Docker image"
@echo " docker-push - Build and push to ACR"
@echo " run - Start local pgrx dev server"
@echo " pg-clean - Clean build artifacts"
@echo " install - Install prebuilt artifacts for the selected PostgreSQL"
@echo " uninstall - Remove installed artifacts for the selected PostgreSQL"
@echo " pg-install - Install extension locally"
@echo " pgxn-zip - Build the PGXN release bundle (META.json + zip)"
# ============================================================================
# PGXN packaging
# ============================================================================
# The distribution version is read from Cargo.toml so the PGXN metadata can
# never drift from the crate version. META.json is generated, not committed.
DISTNAME = pg_durable
DISTVERSION = $(shell sed -n 's/^version = "\(.*\)"/\1/p' Cargo.toml | head -1)
# Render the PGXN metadata, stamping in the Cargo.toml version. This reuses the
# same @CARGO_VERSION@ token that pgrx substitutes into pg_durable.control.
META.json: META.json.in Cargo.toml
sed 's/@CARGO_VERSION@/$(DISTVERSION)/g' $< > $@
# Build the PGXN release bundle. git archive ships only committed files, so the
# generated META.json is added explicitly.
pgxn-zip: META.json
git archive --format zip --prefix $(DISTNAME)-$(DISTVERSION)/ \
--add-file META.json -o $(DISTNAME)-$(DISTVERSION).zip HEAD
# ============================================================================
# pg_regress (PGXS) configuration
# ============================================================================
EXTENSION = pg_durable
REGRESS = 00_init simple sequence variables parallel conditional
REQUESTED_GOALS := $(if $(MAKECMDGOALS),$(MAKECMDGOALS),all)
PG_CONFIG_GOALS := all package install uninstall installcheck
ifneq ($(filter $(PG_CONFIG_GOALS),$(REQUESTED_GOALS)),)
ifndef PG_CONFIG
PG_CONFIG := $(shell $(CARGO) pgrx info pg-config $(PG_VERSION) 2>/dev/null)
ifeq ($(PG_CONFIG),)
PG_CONFIG := $(shell command -v pg_config 2>/dev/null)
endif
endif
ifeq ($(PG_CONFIG),)
$(error PG_CONFIG is not set and pg_config could not be found via cargo-pgrx or PATH)
endif
PG_MAJOR := $(shell "$(PG_CONFIG)" --version 2>/dev/null | sed -nE 's/^PostgreSQL ([0-9]+).*/\1/p')
ifeq ($(filter $(PG_MAJOR),17 18),)
$(error unsupported PostgreSQL major '$(PG_MAJOR)'; pg_durable supports PostgreSQL 17 and 18)
endif
endif
ifneq ($(filter install uninstall,$(REQUESTED_GOALS)),)
ifneq ($(filter installcheck,$(REQUESTED_GOALS)),)
$(error run 'make install' or 'make uninstall' and 'make installcheck' as separate commands)
endif
endif
# PGXS is used only for the regression-test entry point. Keeping it out of
# normal builds prevents its `install` recipe from conflicting with ours.
ifneq ($(filter installcheck,$(REQUESTED_GOALS)),)
ifndef PGXS
PGXS := $(shell "$(PG_CONFIG)" --pgxs)
endif
include $(PGXS)
endif
# ============================================================================
# Source installation
# ============================================================================
DEFAULT_PGRX_PACKAGE_DIR = $(CURDIR)/target/release/pg_durable-pg$(PG_MAJOR)
PGRX_PACKAGE_DIR ?= $(DEFAULT_PGRX_PACKAGE_DIR)
PGRX_PACKAGE_MARKER = $(PGRX_PACKAGE_DIR).pg_durable-owned
PG_DLSUFFIX ?= $(if $(filter Darwin,$(shell uname -s)),.dylib,.so)
ifeq ($(filter installcheck,$(REQUESTED_GOALS)),)
PG_PKGLIBDIR = $(shell "$(PG_CONFIG)" --pkglibdir)
PG_EXTENSION_DIR = $(shell "$(PG_CONFIG)" --sharedir)/extension
PACKAGE_LIBRARY = $(PGRX_PACKAGE_DIR)$(PG_PKGLIBDIR)/pg_durable$(PG_DLSUFFIX)
PACKAGE_EXTENSION_DIR = $(PGRX_PACKAGE_DIR)$(PG_EXTENSION_DIR)
# Same directories relative to the package root, for auditing the packaged tree.
PG_PKGLIBDIR_REL = $(patsubst /%,%,$(PG_PKGLIBDIR))
PG_EXTENSION_DIR_REL = $(patsubst /%,%,$(PG_EXTENSION_DIR))
install:
@set -eu; \
package_library="$(PACKAGE_LIBRARY)"; \
package_extension_dir="$(PACKAGE_EXTENSION_DIR)"; \
test -f "$$package_library" || { echo "missing packaged library: $$package_library; run 'make package' first" >&2; exit 1; }; \
test -f "$$package_extension_dir/pg_durable.control" || { echo "missing packaged control file; run 'make package' first" >&2; exit 1; }; \
set -- "$$package_extension_dir"/pg_durable--*.sql; \
test -f "$$1" || { echo "missing packaged SQL files; run 'make package' first" >&2; exit 1; }; \
unexpected="$$(cd "$(PGRX_PACKAGE_DIR)" && find . -type f \
! -path "./$(PG_PKGLIBDIR_REL)/pg_durable$(PG_DLSUFFIX)" \
! -path "./$(PG_EXTENSION_DIR_REL)/pg_durable.control" \
! -path "./$(PG_EXTENSION_DIR_REL)/pg_durable--*.sql")"; \
test -z "$$unexpected" || { \
echo "packaged tree contains files this target does not install:" >&2; \
echo "$$unexpected" >&2; \
echo "the Debian package ships the whole tree, so a source install would silently differ from it; extend the install and uninstall recipes or exclude these files" >&2; \
exit 1; }; \
install -d -m 0755 "$(DESTDIR)$(PG_PKGLIBDIR)" "$(DESTDIR)$(PG_EXTENSION_DIR)"; \
install -m 0755 "$$package_library" "$(DESTDIR)$(PG_PKGLIBDIR)/pg_durable$(PG_DLSUFFIX)"; \
install -m 0644 "$$package_extension_dir/pg_durable.control" "$$@" "$(DESTDIR)$(PG_EXTENSION_DIR)/"
# `pgxn uninstall` runs this target directly, without building first, so it must
# not depend on a package tree. It removes only what `install` places, and is
# idempotent so a partial installation can always be cleaned up.
uninstall:
@set -eu; \
extension_dir="$(DESTDIR)$(PG_EXTENSION_DIR)"; \
library="$(DESTDIR)$(PG_PKGLIBDIR)/pg_durable$(PG_DLSUFFIX)"; \
removed=0; \
if test -e "$$library"; then rm -f "$$library"; removed=1; fi; \
if test -e "$$extension_dir/pg_durable.control"; then rm -f "$$extension_dir/pg_durable.control"; removed=1; fi; \
for sql in "$$extension_dir"/pg_durable--*.sql; do \
test -e "$$sql" || continue; \
rm -f "$$sql"; \
removed=1; \
done; \
test "$$removed" -eq 1 || echo "pg_durable is not installed for $(PG_CONFIG); nothing to remove"
endif