Skip to content

Commit 9f42cf7

Browse files
committed
fix: release script supports --force for re-releases
1 parent f7bc4c2 commit 9f42cf7

1 file changed

Lines changed: 78 additions & 33 deletions

File tree

scripts/release.sh

Lines changed: 78 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
# Validates changelog, syncs version across files, creates tag, and pushes.
44
#
55
# Usage:
6-
# ./scripts/release.sh 0.3.0
6+
# ./scripts/release.sh 0.3.0 # New release
7+
# ./scripts/release.sh 0.3.0 --force # Re-release (deletes existing tag)
78
# ./scripts/release.sh 0.3.0 --dry-run # Preview without changes
89
#
910
# Prerequisites:
@@ -24,23 +25,33 @@ CHANGELOG="$PROJECT_DIR/CHANGELOG.md"
2425
PACKAGE_JSON="$PROJECT_DIR/package.json"
2526
TAURI_CONF="$PROJECT_DIR/src-tauri/tauri.conf.json"
2627

27-
VERSION="$1"
28+
VERSION=""
2829
DRY_RUN=false
30+
FORCE=false
2931

30-
if [ "$2" = "--dry-run" ]; then
31-
DRY_RUN=true
32-
fi
32+
for arg in "$@"; do
33+
case "$arg" in
34+
--dry-run) DRY_RUN=true ;;
35+
--force) FORCE=true ;;
36+
-*) echo -e "${RED}Unknown flag: $arg${NC}"; exit 1 ;;
37+
*) VERSION="$arg" ;;
38+
esac
39+
done
3340

3441
# ── Validate input ──
3542

3643
if [ -z "$VERSION" ]; then
3744
echo -e "${RED}Error: version required${NC}"
3845
echo ""
39-
echo "Usage: ./scripts/release.sh <version> [--dry-run]"
40-
echo "Example: ./scripts/release.sh 0.4.0"
46+
echo "Usage: ./scripts/release.sh <version> [--dry-run] [--force]"
47+
echo ""
48+
echo "Examples:"
49+
echo " ./scripts/release.sh 0.4.0 # New release"
50+
echo " ./scripts/release.sh 0.3.0 --force # Re-release existing version"
51+
echo " ./scripts/release.sh 0.4.0 --dry-run # Preview"
4152
echo ""
4253
echo "Before running, document the release in CHANGELOG.md:"
43-
echo " ## [$VERSION] - $(date +%Y-%m-%d)"
54+
echo " ## [x.x.x] - $(date +%Y-%m-%d)"
4455
exit 1
4556
fi
4657

@@ -49,6 +60,9 @@ VERSION="${VERSION#v}"
4960

5061
echo ""
5162
echo "=== SQLMap UI Release v$VERSION ==="
63+
if [ "$FORCE" = true ]; then
64+
echo -e "${YELLOW}(force mode: will replace existing tag)${NC}"
65+
fi
5266
echo ""
5367

5468
# ── Check clean working tree ──
@@ -85,7 +99,7 @@ if [ -z "$CHANGELOG_ENTRY" ]; then
8599
fi
86100

87101
# Validate it has a date
88-
if ! echo "$CHANGELOG_ENTRY" | grep -qE "\d{4}-\d{2}-\d{2}"; then
102+
if ! echo "$CHANGELOG_ENTRY" | grep -qE "[0-9]{4}-[0-9]{2}-[0-9]{2}"; then
89103
echo -e "${RED}Error: version $VERSION in CHANGELOG.md has no date${NC}"
90104
echo "Expected format: ## [$VERSION] - YYYY-MM-DD"
91105
exit 1
@@ -99,23 +113,51 @@ fi
99113

100114
echo -e "${GREEN}CHANGELOG.md:${NC} $CHANGELOG_ENTRY"
101115

102-
# ── Validate tag doesn't already exist ──
116+
# ── Detect remote ──
103117

104-
if git -C "$PROJECT_DIR" tag -l "v$VERSION" | grep -q "v$VERSION"; then
105-
echo -e "${RED}Error: tag v$VERSION already exists${NC}"
118+
REMOTE=$(git -C "$PROJECT_DIR" remote | head -1)
119+
if [ -z "$REMOTE" ]; then
120+
echo -e "${RED}Error: no git remote configured${NC}"
106121
exit 1
107122
fi
123+
BRANCH=$(git -C "$PROJECT_DIR" branch --show-current)
124+
125+
# ── Check if tag already exists ──
126+
127+
TAG_EXISTS_LOCAL=$(git -C "$PROJECT_DIR" tag -l "v$VERSION")
128+
TAG_EXISTS_REMOTE=$(git -C "$PROJECT_DIR" ls-remote --tags "$REMOTE" "v$VERSION" 2>/dev/null | head -1 || true)
129+
130+
if [ -n "$TAG_EXISTS_LOCAL" ] || [ -n "$TAG_EXISTS_REMOTE" ]; then
131+
if [ "$FORCE" = false ]; then
132+
echo -e "${RED}Error: tag v$VERSION already exists${NC}"
133+
echo "Use --force to re-release: ./scripts/release.sh $VERSION --force"
134+
exit 1
135+
fi
136+
echo -e "${YELLOW}Tag v$VERSION exists, will be replaced${NC}"
137+
fi
108138

109139
# ── Show what will change ──
110140

111141
CURRENT_PKG=$(grep '"version"' "$PACKAGE_JSON" | head -1 | sed 's/.*"version": "\(.*\)".*/\1/')
112142
CURRENT_TAURI=$(grep '"version"' "$TAURI_CONF" | head -1 | sed 's/.*"version": "\(.*\)".*/\1/')
113143

114144
echo ""
115-
echo "Version updates:"
116-
echo " package.json: $CURRENT_PKG -> $VERSION"
117-
echo " tauri.conf.json: $CURRENT_TAURI -> $VERSION"
118-
echo " git tag: v$VERSION"
145+
echo "Plan:"
146+
if [ "$CURRENT_PKG" != "$VERSION" ] || [ "$CURRENT_TAURI" != "$VERSION" ]; then
147+
echo " 1. Update package.json: $CURRENT_PKG -> $VERSION"
148+
echo " Update tauri.conf.json: $CURRENT_TAURI -> $VERSION"
149+
echo " Commit version bump"
150+
else
151+
echo " 1. Version already at $VERSION (no commit needed)"
152+
fi
153+
if [ -n "$TAG_EXISTS_LOCAL" ] || [ -n "$TAG_EXISTS_REMOTE" ]; then
154+
echo " 2. Delete existing tag v$VERSION (local + remote)"
155+
echo " 3. Create new tag v$VERSION"
156+
else
157+
echo " 2. Create tag v$VERSION"
158+
fi
159+
echo " *. Push $BRANCH + tags to $REMOTE"
160+
echo " -> GitHub Actions builds installers and creates release"
119161
echo ""
120162

121163
if [ "$DRY_RUN" = true ]; then
@@ -134,25 +176,15 @@ fi
134176

135177
# ── Update versions ──
136178

137-
# package.json
138-
sed -i.bak "s/\"version\": \"$CURRENT_PKG\"/\"version\": \"$VERSION\"/" "$PACKAGE_JSON"
139-
rm -f "$PACKAGE_JSON.bak"
140-
141-
# tauri.conf.json
142-
sed -i.bak "s/\"version\": \"$CURRENT_TAURI\"/\"version\": \"$VERSION\"/" "$TAURI_CONF"
143-
rm -f "$TAURI_CONF.bak"
144-
145-
echo -e "${GREEN}Updated versions in package.json and tauri.conf.json${NC}"
146-
147-
# ── Detect remote name ──
179+
if [ "$CURRENT_PKG" != "$VERSION" ]; then
180+
sed -i.bak "s/\"version\": \"$CURRENT_PKG\"/\"version\": \"$VERSION\"/" "$PACKAGE_JSON"
181+
rm -f "$PACKAGE_JSON.bak"
182+
fi
148183

149-
REMOTE=$(git -C "$PROJECT_DIR" remote | head -1)
150-
if [ -z "$REMOTE" ]; then
151-
echo -e "${RED}Error: no git remote configured${NC}"
152-
exit 1
184+
if [ "$CURRENT_TAURI" != "$VERSION" ]; then
185+
sed -i.bak "s/\"version\": \"$CURRENT_TAURI\"/\"version\": \"$VERSION\"/" "$TAURI_CONF"
186+
rm -f "$TAURI_CONF.bak"
153187
fi
154-
BRANCH=$(git -C "$PROJECT_DIR" branch --show-current)
155-
echo "Remote: $REMOTE ($BRANCH)"
156188

157189
# ── Commit version bump (only if there are changes) ──
158190

@@ -166,6 +198,19 @@ else
166198
echo -e "${GREEN}Committed version bump${NC}"
167199
fi
168200

201+
# ── Delete existing tag if force ──
202+
203+
if [ "$FORCE" = true ]; then
204+
if [ -n "$TAG_EXISTS_LOCAL" ]; then
205+
git tag -d "v$VERSION" 2>/dev/null || true
206+
echo -e "${YELLOW}Deleted local tag v$VERSION${NC}"
207+
fi
208+
if [ -n "$TAG_EXISTS_REMOTE" ]; then
209+
git push "$REMOTE" --delete "v$VERSION" 2>/dev/null || true
210+
echo -e "${YELLOW}Deleted remote tag v$VERSION${NC}"
211+
fi
212+
fi
213+
169214
# ── Create tag ──
170215

171216
git tag -a "v$VERSION" -m "Release v$VERSION"

0 commit comments

Comments
 (0)