-
Notifications
You must be signed in to change notification settings - Fork 24
Expand file tree
/
Copy pathMakefile.release
More file actions
159 lines (137 loc) · 5.59 KB
/
Makefile.release
File metadata and controls
159 lines (137 loc) · 5.59 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
# -------- Release Makefile (robuste et reprenable) --------
#
# Compatible with strict GitHub repository rules:
# - main is protected: changes must go through a Pull Request
# - main must not contain merge commits (use SQUASH or REBASE in GitHub)
#
# Workflow:
# make -f Makefile.release release VERSION=vX.Y.Z
# -> prepares release on dev (commit + push) + prints PR instructions
# -> open PR dev -> main and merge using SQUASH/REBASE (no merge commit)
# make -f Makefile.release tag VERSION=vX.Y.Z
# -> creates annotated tag on main after PR merge (recommended)
#
# ----------------------------------------------------------
VERSION ?= v0.1.0
BRANCH_DEV = dev
BRANCH_MAIN = main
# If VERSION doesn't start with "v", prefix it.
# Examples:
# VERSION=1.9.0 -> TAG=v1.9.0
# VERSION=v1.9.0 -> TAG=v1.9.0
TAG := $(if $(filter v%,$(VERSION)),$(VERSION),v$(VERSION))
.PHONY: help \
release release-fast \
commit push \
tag resume-tag \
pr-instructions \
test changelog \
submodules submodules-remote \
gh-release \
assert-dev assert-main assert-clean
help:
@echo "Available commands:"
@echo " make -f Makefile.release release VERSION=vX.Y.Z - Prepare release on $(BRANCH_DEV): changelog + commit + push + PR instructions"
@echo " make -f Makefile.release release-fast VERSION=vX.Y.Z - Same as release but without changelog step"
@echo " make -f Makefile.release commit - Commit on $(BRANCH_DEV) (if there are changes)"
@echo " make -f Makefile.release push - Push $(BRANCH_DEV)"
@echo " make -f Makefile.release tag VERSION=vX.Y.Z - Create and push annotated tag on $(BRANCH_MAIN) (run after PR merge)"
@echo " make -f Makefile.release resume-tag VERSION=vX.Y.Z - Only (re)push the tag step"
@echo " make -f Makefile.release gh-release VERSION=vX.Y.Z - Create GitHub release from TAG (needs 'gh')"
@echo " make -f Makefile.release submodules - Sync/init submodules"
@echo " make -f Makefile.release test - Run ctest from ./build"
@echo "Current VERSION=$(VERSION) -> TAG=$(TAG)"
# --- Guards ---
assert-dev:
@if [ "$$(git rev-parse --abbrev-ref HEAD)" != "$(BRANCH_DEV)" ]; then \
echo "ℹ️ Switching to $(BRANCH_DEV)"; \
git checkout $(BRANCH_DEV); \
fi
assert-main:
@if [ "$$(git rev-parse --abbrev-ref HEAD)" != "$(BRANCH_MAIN)" ]; then \
echo "ℹ️ Switching to $(BRANCH_MAIN)"; \
git checkout $(BRANCH_MAIN); \
fi
assert-clean:
@if [ -n "$$(git status --porcelain)" ]; then \
echo "❌ Working tree not clean. Commit or stash before continuing."; \
exit 1; \
fi
# --- Steps ---
commit: assert-dev
@if [ -n "$$(git status --porcelain)" ]; then \
echo "📝 Committing changes on $(BRANCH_DEV)..."; \
git add .; \
git commit -m "chore(release): prepare $(TAG)"; \
else \
echo "✅ Nothing to commit on $(BRANCH_DEV)."; \
fi
push: assert-dev
@echo "⬆️ Pushing $(BRANCH_DEV)..."
@for i in 1 2 3; do \
git push origin $(BRANCH_DEV) && s=0 && break || s=$$?; \
echo "⚠️ Push $(BRANCH_DEV) failed (try $$i/3). Retrying in 2s..."; \
sleep 2; \
done; exit $$s
# Create and push annotated tag on main AFTER the PR is merged.
tag: assert-main assert-clean
@if git rev-parse --verify --quiet $(TAG) >/dev/null; then \
echo "ℹ️ Local tag $(TAG) already exists."; \
else \
echo "🏷️ Creating annotated tag $(TAG) on $(BRANCH_MAIN)..."; \
git tag -a $(TAG) -m "Release version $(TAG)"; \
fi; \
if git ls-remote --tags origin $(TAG) | grep -q "$(TAG)"; then \
echo "✅ Remote already has tag $(TAG). Nothing to push."; \
else \
echo "⬆️ Pushing tag $(TAG) to origin..."; \
for i in 1 2 3; do \
git push origin $(TAG) && s=0 && break || s=$$?; \
echo "⚠️ Push tag failed (try $$i/3). Retrying in 2s..."; \
sleep 2; \
done; exit $$s; \
fi
resume-tag:
@$(MAKE) -f Makefile.release tag VERSION=$(VERSION)
release:
@$(MAKE) -f Makefile.release changelog
@$(MAKE) -f Makefile.release commit VERSION=$(VERSION)
@$(MAKE) -f Makefile.release push
@$(MAKE) -f Makefile.release pr-instructions VERSION=$(VERSION)
@echo "✅ Release $(TAG) prepared on $(BRANCH_DEV)."
@echo "ℹ️ After merging the PR (SQUASH/REBASE), run:"
@echo " make -f Makefile.release tag VERSION=$(VERSION)"
release-fast:
@$(MAKE) -f Makefile.release commit VERSION=$(VERSION)
@$(MAKE) -f Makefile.release push
@$(MAKE) -f Makefile.release pr-instructions VERSION=$(VERSION)
@echo "✅ Release $(TAG) prepared on $(BRANCH_DEV) (fast)."
@echo "ℹ️ After merging the PR (SQUASH/REBASE), run:"
@echo " make -f Makefile.release tag VERSION=$(VERSION)"
pr-instructions:
@echo ""
@echo "Next step (required by repo rules):"
@echo " 1) Open a Pull Request: $(BRANCH_DEV) -> $(BRANCH_MAIN)"
@echo " 2) Merge using SQUASH (recommended) or REBASE."
@echo " Do NOT create a merge commit."
@echo " 3) After merge, tag on main:"
@echo " make -f Makefile.release tag VERSION=$(VERSION)"
@echo " 4) Optionally publish a GitHub Release from tag $(TAG)."
@echo ""
gh-release:
@if ! command -v gh >/dev/null 2>&1; then \
echo "❌ 'gh' CLI not found. Install GitHub CLI to use this target."; \
exit 1; \
fi
@echo "📦 Creating GitHub Release for $(TAG)..."
@gh release create $(TAG) --title "$(TAG)" --notes-file CHANGELOG.md || \
{ echo "⚠️ 'gh release' failed. Maybe it already exists?"; exit 0; }
test:
@cd build && ctest --output-on-failure
changelog:
@bash scripts/update_changelog.sh
submodules:
@./scripts/submodules-sync.sh
submodules-remote:
@./scripts/submodules-sync.sh remote
# ----------------------------------------------------------