-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathVersioning.sh
201 lines (167 loc) · 5.92 KB
/
Versioning.sh
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
#!/bin/sh
# Versioning.sh
# Created by Matthew Watkins on 14/06/2022.
# set -x
########## Add this file at the very top of your Xcode project
# Then:
# Edit Scheme... -> Build -> Pre-actions -> +
# Add script content below:
# "${WORKSPACE_PATH}"/../../Versioning.sh
# This will be the default version number for new projects
# Projects not using a three-part numbering scheme will be moved to one
VER_DEFAULT="0.1.1"
EPOCH_TIME=$(date +%s)
TMP_DIR="/tmp"
EPOCH_FILE="$TMP_DIR"/epoch.txt
### Shared functions
_setVersion() {
if [ $# -ne 1 ]; then
echo "An argument is required to the setVersion function"; exit 1
fi
if [ "$1" = "default" ]; then
echo "Setting default/initial version value"
echo ""
_setVersion "$VER_DEFAULT"
elif [ "$1" = "bump" ]; then
echo "Bumping current version number"
echo ""
CURRENT=$(echo "$VERSION" | awk -F "." "{'print $3}'")
TARGET=$("$CURRENT"+1)
PREFIX=$(echo "$VERSION" | cut -d. -f-2)
_setVersion "$PREFIX.$TARGET"
else
NEW_VERSION="$1"
echo "### Application Version ###"
# Display/print build versioning
echo "From: $VERSION"
echo "To: $NEW_VERSION"
echo ""
cp "$PROJECT_FILE" "$PROJECT_FILE".backup
sed "s/MARKETING_VERSION = $VERSION;/MARKETING_VERSION = $NEW_VERSION;/g" "$PROJECT_FILE" > /tmp/project.file
mv /tmp/project.file "$PROJECT_FILE"
fi
}
### Pre-flight checks
# Check for presence of avgtool binary
AGVTOOL=$(which agvtool)
if [ ! -x "$AGVTOOL" ]; then
echo "Xcode command line tool not found: agvtool"; exit 1
fi
if [ -z ${WORKSPACE_PATH+x} ]; then
echo "Script is NOT running in Xcode"
echo ""
PROJECT_PATH=$(pwd)
PROJECT_NAME=${PROJECT_PATH##*/}
WORKSPACE_PATH="$PROJECT_PATH/$PROJECT_NAME.xcodeproj/project.xcworkspace"
else
echo "Script is running in Xcode"
echo ""
if [ -d "$WORKSPACE_PATH" ]; then
# Set the current project root path
PROJECT_PATH="${WORKSPACE_PATH}/../../"
cd "${PROJECT_PATH}"
PROJECT_PATH=$(pwd)
PROJECT_NAME="${PROJECT_PATH##*/}"
else
echo "Error: could not resolve workspace path"; exit 1
fi
fi
# Need to handle condition when app/project directory != application name
if [ -n "$SCHEME_NAME" ]; then
PROJECT_FILE="$PROJECT_PATH/$SCHEME_NAME.xcodeproj/project.pbxproj"
else
PROJECT_FILE="$PROJECT_PATH/$PROJECT_NAME.xcodeproj/project.pbxproj"
fi
if [ ! -d "$PROJECT_PATH" ] || [ ! -d "$WORKSPACE_PATH" ]; then
echo "One of the folder paths is invalid; check script operation"; exit 1
elif [ ! -f "$PROJECT_FILE" ]; then
echo "The project file was not found; check script operation"
echo "The path that failed was: ${PROJECT_FILE}"; exit 1
fi
if ! (grep 'apple-generic' "$PROJECT_FILE" > /dev/null 2>&1)
then
echo "Project versioning needs to be set to apple-generic"; exit 1
fi
echo "### Project Metadata ###"
echo "Project name: ${PROJECT_NAME}"
echo "Project path: ${PROJECT_PATH}"
echo "Project file: ${PROJECT_FILE}"
echo "Workspace path: ${WORKSPACE_PATH}"
echo ""
# Exit the script when a command fails or if it tries to use an undeclared variable
set -o errexit
set -o nounset
# Temporarily enable script debugging output
#set -x
# Obtain the current application version
VERSION=$(agvtool what-marketing-version -terse1)
# If version number empty send warning, use alternate code path
if [ -z "$VERSION" ]; then
# agvtool cannot enumerate versioning unless the option below is set
# Build Settings -> Generate Info.plist File -> No
echo "Warning: agvtool could not enumerate current application version string"
echo ""
# Example below of version stored in ${PROJECT_FILE}
# MARKETING_VERSION = 0.1;
# Alternate code path for recent Xcode versions
VERSION=$(grep MARKETING_VERSION "$PROJECT_FILE" | tail -n 1 | awk '{print $3}' | sed 's:;::')
if [ -z "$VERSION" ]; then
echo "Unable to get version from project.pbxproj file"; exit 1
else
echo "Version retrieved from project.pbxproj file: $VERSION"
echo ""
fi
fi
if [ $# -eq 1 ] && [ "$1" = "archive" ]; then
echo "Script was triggered by Xcode archive generation"
_setVersion bump
exit 0
fi
if [ "$VERSION" = "1" ] || [ "$VERSION" = "1.0" ]; then
_setVersion default
fi
# Get parameters from GIT repository
# NUM_COMMITS=$(git --git-dir="${PROJECT_PATH}/.git" --work-tree="${PROJECT_PATH}/" log | grep commit | wc -l)
NUM_COMMITS=$(git --git-dir="${PROJECT_PATH}/.git" --work-tree="${PROJECT_PATH}/" log | grep -c commit)
LAST_COMMIT=$(git --git-dir="${PROJECT_PATH}/.git" --work-tree="${PROJECT_PATH}/" log -n 1 | grep commit | awk '{print $2}')
echo "Number of GIT commits: $NUM_COMMITS"
# Use only the last eight characters of last GIT commit
SHORT_COMMIT=$(echo "${LAST_COMMIT}" | tail -c 8)
OLD_BUILD=$(agvtool what-version -terse)
# OLD_BUILD_NUMBER=$(echo "$OLD_BUILD" | awk -F "." {'print $1'})
OLD_BUILD_NUMBER=$(cut -d. -f1 << EOF
$OLD_BUILD
EOF
)
# Set new value
NEW_BUILD_NUMBER=$((OLD_BUILD_NUMBER + 1))
NEW_BUILD="${NEW_BUILD_NUMBER}.${SHORT_COMMIT}"
# Append git dirty flag, if necessary
if [ "$(git status --porcelain)" ]; then
NEW_BUILD="$NEW_BUILD.dirty"
else
NEW_BUILD="$NEW_BUILD.clean"
fi
### Set new build version
# Performed conditionally, only if the last build was over sixty seconds ago
if [ -f "$EPOCH_FILE" ]; then
LAST_RUN=$(cat "$EPOCH_FILE")
ELAPSED=$((EPOCH_TIME - LAST_RUN))
echo "Invocation time since UNIX epoch: $EPOCH_TIME"
echo "Time elapsed since last build attempt: $ELAPSED"
echo ""
if [ "$ELAPSED" -gt 60 ]; then
echo "$EPOCH_TIME" > "$EPOCH_FILE"
agvtool new-version -all "${NEW_BUILD}" > /dev/null 2>&1
fi
else
echo "$EPOCH_TIME" > "$EPOCH_FILE"
echo "Invocation time since UNIX epoch: $EPOCH_TIME"
echo ""
agvtool new-version -all "${NEW_BUILD}" > /dev/null 2>&1
fi
# Display/print build versioning
echo "### Build Version ###"
echo "From: ${OLD_BUILD}"
echo "To: ${NEW_BUILD}"
echo ""