File: release.sh

package info (click to toggle)
ggml 0.9.4-7
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 17,140 kB
  • sloc: cpp: 107,161; ansic: 36,329; lisp: 9,094; python: 1,558; objc: 1,045; sh: 825; makefile: 77
file content (296 lines) | stat: -rwxr-xr-x 9,422 bytes parent folder | download
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
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
#!/bin/bash
#
# Automated release script for ggml.
#
# Note: Sync from llama.cpp should be done separately via PR process
# prior to running this script.
#
# Usage:
#   ./scripts/release.sh prepare [major|minor|patch] [--dry-run]
#   ./scripts/release.sh finalize [--dry-run]
#
# Two-stage release process:
#
# Stage 1 - Prepare:
# $ ./scripts/release.sh prepare minor
# This creates a release candidate branch with version bump and removes -dev suffix.
# The branch should then be manually pushed and a PR created, reviewed, and merged.
#
# Stage 2 - Finalize:
# $ ./scripts/release.sh finalize
# After the RC PR is merged, this reads the current version from CMakeLists.txt,
# creates the release tag, and prepares the next development cycle.
#
# Prepare stage:
# 1. Creates release candidate branch
# 2. Updates version and removes -dev suffix
# 3. Commits the version bump
#
# Finalize stage:
# 1. Reads current release version from CMakeLists.txt
# 2. Creates signed git tag on master
# 3. Adds -dev suffix back for next development cycle
# 4. Creates branch and commit for development version
#

set -e

if [ ! -f "CMakeLists.txt" ] || [ ! -d "scripts" ]; then
    echo "Error: Must be run from ggml root directory"
    exit 1
fi

# Parse command line arguments
COMMAND=""
VERSION_TYPE=""
DRY_RUN=false

# First argument should be the command
if [ $# -eq 0 ]; then
    echo "Error: Missing command"
    echo "Usage: $0 prepare [major|minor|patch] [--dry-run]"
    echo "       $0 finalize [--dry-run]"
    exit 1
fi

COMMAND="$1"
shift

# Parse remaining arguments
for arg in "$@"; do
    case $arg in
        --dry-run)
            DRY_RUN=true
            ;;
        major|minor|patch)
            if [ "$COMMAND" = "prepare" ]; then
                VERSION_TYPE="$arg"
            else
                echo "Error: Version type only valid for 'prepare' command"
                exit 1
            fi
            ;;
        *)
            echo "Error: Unknown argument '$arg'"
            echo "Usage: $0 prepare [major|minor|patch] [--dry-run]"
            echo "       $0 finalize [--dry-run]"
            exit 1
            ;;
    esac
done

# Validate command
if [[ ! "$COMMAND" =~ ^(prepare|finalize)$ ]]; then
    echo "Error: Command must be 'prepare' or 'finalize'"
    echo "Usage: $0 prepare [major|minor|patch] [--dry-run]"
    echo "       $0 finalize [--dry-run]"
    exit 1
fi

# For prepare command, default to patch if no version type specified
if [ "$COMMAND" = "prepare" ]; then
    VERSION_TYPE="${VERSION_TYPE:-patch}"
    if [[ ! "$VERSION_TYPE" =~ ^(major|minor|patch)$ ]]; then
        echo "Error: Version type must be 'major', 'minor', or 'patch'"
        echo "Usage: $0 prepare [major|minor|patch] [--dry-run]"
        exit 1
    fi
fi

# Common validation functions
check_git_status() {
    # Check for uncommitted changes (skip in dry-run)
    if [ "$DRY_RUN" = false ] && ! git diff-index --quiet HEAD --; then
        echo "Error: You have uncommitted changes. Please commit or stash them first."
        exit 1
    fi
}

check_master_branch() {
    # Ensure we're on master branch
    CURRENT_BRANCH=$(git branch --show-current)
    if [ "$CURRENT_BRANCH" != "master" ]; then
        if [ "$DRY_RUN" = true ]; then
            echo "[dry run] Warning: Not on master branch (currently on: $CURRENT_BRANCH). Continuing with dry-run..."
            echo ""
        else
            echo "Error: Must be on master branch. Currently on: $CURRENT_BRANCH"
            exit 1
        fi
    fi
}

check_master_up_to_date() {
    # Check if we have the latest from master (skip in dry-run)
    if [ "$DRY_RUN" = false ]; then
        echo "Checking if local master is up-to-date with remote..."
        git fetch origin master
        LOCAL=$(git rev-parse HEAD)
        REMOTE=$(git rev-parse origin/master)

        if [ "$LOCAL" != "$REMOTE" ]; then
            echo "Error: Your local master branch is not up-to-date with origin/master."
            echo "Please run 'git pull origin master' first."
            exit 1
        fi
        echo "✓ Local master is up-to-date with remote"
        echo ""
    elif [ "$(git branch --show-current)" = "master" ]; then
        echo "[dry run] Warning: Dry-run mode - not checking if master is up-to-date with remote"
        echo ""
    fi
}

prepare_release() {
    if [ "$DRY_RUN" = true ]; then
        echo "[dry-run] Preparing release (no changes will be made)"
    else
        echo "Starting release preparation..."
    fi
    echo ""

    check_git_status
    check_master_branch
    check_master_up_to_date

    # Extract current version from CMakeLists.txt
    echo "Step 1: Reading current version..."
    MAJOR=$(grep "set(GGML_VERSION_MAJOR" CMakeLists.txt | sed 's/.*MAJOR \([0-9]*\).*/\1/')
    MINOR=$(grep "set(GGML_VERSION_MINOR" CMakeLists.txt | sed 's/.*MINOR \([0-9]*\).*/\1/')
    PATCH=$(grep "set(GGML_VERSION_PATCH" CMakeLists.txt | sed 's/.*PATCH \([0-9]*\).*/\1/')

    echo "Current version: $MAJOR.$MINOR.$PATCH"

    # Calculate new version
    case $VERSION_TYPE in
        major)
            NEW_MAJOR=$((MAJOR + 1))
            NEW_MINOR=0
            NEW_PATCH=0
            ;;
        minor)
            NEW_MAJOR=$MAJOR
            NEW_MINOR=$((MINOR + 1))
            NEW_PATCH=0
            ;;
        patch)
            NEW_MAJOR=$MAJOR
            NEW_MINOR=$MINOR
            NEW_PATCH=$((PATCH + 1))
            ;;
    esac

    NEW_VERSION="$NEW_MAJOR.$NEW_MINOR.$NEW_PATCH"
    RC_BRANCH="ggml-rc-v$NEW_VERSION"
    echo "New release version: $NEW_VERSION"
    echo "Release candidate branch: $RC_BRANCH"
    echo ""

    # Create release candidate branch
    echo "Step 2: Creating release candidate branch..."
    if [ "$DRY_RUN" = true ]; then
        echo "  [dry-run] Would create branch: $RC_BRANCH"
    else
        git checkout -b "$RC_BRANCH"
        echo "✓ Created and switched to branch: $RC_BRANCH"
    fi
    echo ""

    # Update CMakeLists.txt for release
    echo "Step 3: Updating version in CMakeLists.txt..."
    if [ "$DRY_RUN" = true ]; then
        echo "  [dry-run] Would update GGML_VERSION_MAJOR to $NEW_MAJOR"
        echo "  [dry-run] Would update GGML_VERSION_MINOR to $NEW_MINOR"
        echo "  [dry-run] Would update GGML_VERSION_PATCH to $NEW_PATCH"
    else
        sed -i'' -e "s/set(GGML_VERSION_MAJOR [0-9]*)/set(GGML_VERSION_MAJOR $NEW_MAJOR)/" CMakeLists.txt
        sed -i'' -e "s/set(GGML_VERSION_MINOR [0-9]*)/set(GGML_VERSION_MINOR $NEW_MINOR)/" CMakeLists.txt
        sed -i'' -e "s/set(GGML_VERSION_PATCH [0-9]*)/set(GGML_VERSION_PATCH $NEW_PATCH)/" CMakeLists.txt
    fi
    echo ""

    # Commit version bump
    echo "Step 4: Committing version bump..."
    if [ "$DRY_RUN" = true ]; then
        echo "  [dry-run] Would commit: 'ggml : bump version to $NEW_VERSION'"
    else
        git add CMakeLists.txt
        git commit -m "ggml : bump version to $NEW_VERSION"
    fi
    echo ""

    echo ""
    if [ "$DRY_RUN" = true ]; then
        echo "[dry-run] Summary (no changes were made):"
        echo "  • Would have created branch: $RC_BRANCH"
        echo "  • Would have updated version to: $NEW_VERSION"
    else
        echo "Release preparation completed!"
        echo "Summary:"
        echo "  • Created branch: $RC_BRANCH"
        echo "  • Updated version to: $NEW_VERSION"
        echo ""
        echo "Next steps:"
        echo "  • Push branch to remote: git push origin $RC_BRANCH"
        echo "  • Create a Pull Request from $RC_BRANCH to master"
        echo "  • After PR is merged, run: ./scripts/release.sh finalize"
    fi
}

finalize_release() {
    if [ "$DRY_RUN" = true ]; then
        echo "[dry-run] Finalizing release (no changes will be made)"
    else
        echo "Starting release finalization..."
    fi
    echo ""

    check_git_status
    check_master_branch
    check_master_up_to_date

    # Read current version from CMakeLists.txt
    echo "Step 1: Reading current release version..."
    MAJOR=$(grep "set(GGML_VERSION_MAJOR" CMakeLists.txt | sed 's/.*MAJOR \([0-9]*\).*/\1/')
    MINOR=$(grep "set(GGML_VERSION_MINOR" CMakeLists.txt | sed 's/.*MINOR \([0-9]*\).*/\1/')
    PATCH=$(grep "set(GGML_VERSION_PATCH" CMakeLists.txt | sed 's/.*PATCH \([0-9]*\).*/\1/')

    RELEASE_VERSION="$MAJOR.$MINOR.$PATCH"
    echo "Release version: $RELEASE_VERSION"
    echo ""

    # Create git tag
    echo "Step 2: Creating signed git tag..."
    if [ "$DRY_RUN" = true ]; then
        echo "  [dry-run] Would create signed tag: v$RELEASE_VERSION with message 'Release version $RELEASE_VERSION'"
    else
        git tag -s "v$RELEASE_VERSION" -m "Release version $RELEASE_VERSION"
        echo "✓ Created signed tag: v$RELEASE_VERSION"
    fi
    echo ""


    echo ""
    if [ "$DRY_RUN" = true ]; then
        echo "[dry-run] Summary (no changes were made):"
        echo "  • Would have created tag: v$RELEASE_VERSION"
    else
        echo "Release finalization completed!"
        echo "Summary:"
        echo "  • Created signed tag: v$RELEASE_VERSION"
        echo ""
        echo "Next steps:"
        echo "  • Push tag to remote: git push origin v$RELEASE_VERSION"
        echo "  • The release is now complete!"
    fi
}

# Execute the appropriate command
case $COMMAND in
    prepare)
        prepare_release
        ;;
    finalize)
        finalize_release
        ;;
esac