forked from OpenLineage/OpenLineage
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrelease.sh
More file actions
executable file
·359 lines (315 loc) · 14.3 KB
/
Copy pathrelease.sh
File metadata and controls
executable file
·359 lines (315 loc) · 14.3 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
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
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
#!/bin/bash
#
# Copyright 2018-2026 contributors to the OpenLineage project
# SPDX-License-Identifier: Apache-2.0
#
# NOTE: This script was inspired by https://github.com/MarquezProject/marquez/blob/main/new-version.sh
#
# Requirements:
# * You're on the 'main' branch
# * You have the following dependencies installed: git, uv, bump-my-version
# (The script will check for these and provide installation instructions if missing)
#
# Usage: $ ./release.sh --release-version RELEASE_VERSION --next-version NEXT_VERSION
set -e
title() {
echo -e "\033[1m${1}\033[0m"
}
usage() {
echo "Usage: ./$(basename -- "${0}") --release-version RELEASE_VERSION --next-version NEXT_VERSION"
echo "A script used to release OpenLineage"
echo
title "EXAMPLES:"
echo " # Bump version ('-SNAPSHOT' will automatically be appended to '0.0.2')"
echo " $ ./release.sh -r 0.0.1 -n 0.0.2"
echo
echo " # Bump version (with '-SNAPSHOT' already appended to '0.0.2')"
echo " $ ./release.sh -r 0.0.1 -n 0.0.2-SNAPSHOT"
echo
echo " # Bump release candidate"
echo " $ ./release.sh -r 0.0.1-rc.1 -n 0.0.2-rc.2"
echo
echo " # Bump release candidate without push"
echo " $ ./release.sh -r 0.0.1-rc.1 -n 0.0.2-rc.2 -p"
echo
title "ARGUMENTS:"
echo " -r, --release-version string the release version (ex: X.Y.Z, X.Y.Z-rc.*)"
echo " -n, --next-version string the next version (ex: X.Y.Z, X.Y.Z-SNAPSHOT)"
echo
title "FLAGS:"
echo " -p, --no-push local changes are not automatically pushed to the remote repository"
exit 1
}
# Determine the bump type (major, minor, or patch) based on version comparison
# Arguments: current_version new_version
# Returns: "major", "minor", or "patch"
function determine_bump_type() {
local current="$1"
local new="$2"
# Strip any suffixes like -SNAPSHOT, -rc.X for comparison
local current_base
local new_base
current_base=$(echo "$current" | sed -E 's/(-rc\.[0-9]+)?(-SNAPSHOT)?$//')
new_base=$(echo "$new" | sed -E 's/(-rc\.[0-9]+)?(-SNAPSHOT)?$//')
# Parse version components
local current_major current_minor current_patch
local new_major new_minor new_patch
IFS='.' read -r current_major current_minor current_patch <<< "$current_base"
IFS='.' read -r new_major new_minor new_patch <<< "$new_base"
# Determine bump type
if [ "$new_major" != "$current_major" ]; then
echo "major"
elif [ "$new_minor" != "$current_minor" ]; then
echo "minor"
elif [ "$new_patch" != "$current_patch" ]; then
echo "patch"
else
echo "error: current and new versions are the same: $current vs $new" >&2
return 1
fi
}
# Update the python package version only if the current_version is different from the new_version
# We do this check because bumpversion screws up the search/replace if the current_version and
# new_version are the same
function update_py_version_if_needed() {
# shellcheck disable=SC2086,SC2046
current_version=$(uv run bump-my-version show --config-file pyproject.toml --format json current_version | grep -o '"current_version": "[^"]*"' | cut -d'"' -f4)
# shellcheck disable=SC2154
if [ "$1" != "$current_version" ]; then
# Determine the appropriate bump type
bump_type=$(determine_bump_type "$current_version" "$1")
# shellcheck disable=SC2086
uv run bump-my-version bump "$bump_type" --new-version $1 --config-file pyproject.toml --allow-dirty
fi
}
readonly SEMVER_REGEX="^[0-9]+(\.[0-9]+){2}((-rc\.[0-9]+)?(-SNAPSHOT)?)$" # X.Y.Z
# X.Y.Z-rc.*
# X.Y.Z-rc.*-SNAPSHOT
# X.Y.Z-SNAPSHOT
# Detect OS for installation instructions
detect_os() {
if [[ "$OSTYPE" == "darwin"* ]]; then
echo "macos"
elif [[ "$OSTYPE" == "linux-gnu"* ]]; then
echo "linux"
else
echo "unknown"
fi
}
# Check for required dependencies
check_dependencies() {
local missing_deps=()
local os_type
os_type=$(detect_os)
# Check for git
if ! command -v git &> /dev/null; then
missing_deps+=("git")
fi
# Check for uv
if ! command -v uv &> /dev/null; then
missing_deps+=("uv")
fi
# Check for bump-my-version (via uv)
if command -v uv &> /dev/null; then
if ! uv run which bump-my-version &> /dev/null; then
missing_deps+=("bump-my-version")
fi
fi
# If dependencies are missing, print installation instructions
if [ ${#missing_deps[@]} -gt 0 ]; then
echo "Error: Missing required dependencies: ${missing_deps[*]}"
echo
echo "Please install the missing dependencies:"
echo
for dep in "${missing_deps[@]}"; do
case $dep in
git)
if [[ "$os_type" == "macos" ]]; then
echo " git:"
echo " • Using Homebrew: brew install git"
echo " • Or install Xcode Command Line Tools: xcode-select --install"
elif [[ "$os_type" == "linux" ]]; then
echo " git:"
echo " • Debian/Ubuntu: sudo apt-get install git"
echo " • Fedora/RHEL: sudo dnf install git"
echo " • Arch: sudo pacman -S git"
fi
echo
;;
uv)
if [[ "$os_type" == "macos" ]]; then
echo " uv:"
echo " • Using Homebrew: brew install uv"
echo " • Or using curl: curl -LsSf https://astral.sh/uv/install.sh | sh"
elif [[ "$os_type" == "linux" ]]; then
echo " uv:"
echo " • Using curl: curl -LsSf https://astral.sh/uv/install.sh | sh"
echo " • Or download from: https://github.com/astral-sh/uv/releases"
fi
echo " • Documentation: https://docs.astral.sh/uv/getting-started/installation/"
echo
;;
bump-my-version)
echo " bump-my-version:"
echo " • Install via uv (recommended): uv tool install bump-my-version"
echo " • Or install via pip: pip install bump-my-version"
echo " • Documentation: https://github.com/callowayproject/bump-my-version#installation"
echo
;;
esac
done
exit 1
fi
}
# Verify all required dependencies are installed
check_dependencies
# Change working directory to project root
project_root=$(git rev-parse --show-toplevel)
cd "${project_root}/"
if [[ $# -eq 0 ]] ; then
usage
fi
PUSH="true"
while [ $# -gt 0 ]; do
case $1 in
-r|--release-version)
shift
RELEASE_VERSION="${1}"
;;
-n|--next-version)
shift
NEXT_VERSION="${1}"
;;
-p|--no-push)
PUSH="false"
;;
-h|--help)
usage
;;
*) exit 1
;;
esac
shift
done
branch=$(git symbolic-ref --short HEAD)
if [[ "${branch}" != "main" ]]; then
echo "error: you may only release on 'main'!"
exit 1;
fi
# Ensure no unstaged changes are present in working directory
if [[ -n "$(git status --porcelain --untracked-files=no)" ]] ; then
echo "error: you have unstaged changes in your working directory!"
exit 1;
fi
# Ensure we're on the latest main with no local changes
git fetch origin main
if [[ "$(git rev-parse HEAD)" != "$(git rev-parse origin/main)" ]]; then
echo "error: your local 'main' branch is not up to date with 'origin/main'!"
echo "Please run: git reset --hard origin/main"
exit 1;
fi
# Ensure there is no existing remote or local tag with the release version
git fetch --tags origin
if git ls-remote --tags origin "${RELEASE_VERSION}" | grep -q .; then
echo "error: Remote tag '${RELEASE_VERSION}' already exists on origin."
exit 1
fi
if git rev-parse -q --verify "refs/tags/${RELEASE_VERSION}" >/dev/null; then
echo "Removing existing local tag '${RELEASE_VERSION}'..."
git tag -d "${RELEASE_VERSION}"
fi
# Ensure valid versions
# shellcheck disable=SC2086,SC2206
VERSIONS=($RELEASE_VERSION $NEXT_VERSION)
for VERSION in "${VERSIONS[@]}"; do
if [[ ! "${VERSION}" =~ ${SEMVER_REGEX} ]]; then
echo "Error: Version '${VERSION}' must match '${SEMVER_REGEX}'"
exit 1
fi
done
# Ensure python module version matches X.Y.Z or X.Y.ZrcN (see: https://www.python.org/dev/peps/pep-0440/),
PYTHON_RELEASE_VERSION=${RELEASE_VERSION}
if [[ "${RELEASE_VERSION}" == *-rc.? ]]; then
RELEASE_CANDIDATE=${RELEASE_VERSION##*-}
PYTHON_RELEASE_VERSION="${RELEASE_VERSION%-*}${RELEASE_CANDIDATE//.}"
fi
# (1) Bump python module versions. Do this before the release in case the current release is not
# the same version as what was expected the last time we released. E.g., if the next expected
# release was a patch version, but a new minor version is being released, we need to update to the
# actual release version prior to committing/tagging
PYTHON_MODULES=(client/python/ integration/common/ integration/dbt/ integration/sql/iface-py/)
for PYTHON_MODULE in "${PYTHON_MODULES[@]}"; do
(cd "${PYTHON_MODULE}" && update_py_version_if_needed "${PYTHON_RELEASE_VERSION}")
done
# (2) Bump java module versions
perl -i -pe"s/^version=.*/version=${RELEASE_VERSION}/g" ./client/java/gradle.properties
perl -i -pe"s/^version=.*/version=${RELEASE_VERSION}/g" ./integration/sql/iface-java/gradle.properties
perl -i -pe"s/^version=.*/version=${RELEASE_VERSION}/g" ./integration/spark/gradle.properties
perl -i -pe"s/^version=.*/version=${RELEASE_VERSION}/g" ./integration/spark-extension-interfaces/gradle.properties
perl -i -pe"s/^version=.*/version=${RELEASE_VERSION}/g" ./integration/flink/gradle.properties
perl -i -pe"s/^version=.*/version=${RELEASE_VERSION}/g" ./integration/flink/examples/flink1-test-apps/gradle.properties
perl -i -pe"s/^version=.*/version=${RELEASE_VERSION}/g" ./integration/flink/examples/flink2-test-apps/gradle.properties
perl -i -pe"s/^version=.*/version=${RELEASE_VERSION}/g" ./integration/hive/gradle.properties
perl -i -pe"s/^version=.*/version=${RELEASE_VERSION}/g" ./integration/hive/hive-openlineage-hook/src/main/resources/io/openlineage/hive/client/version.properties
# (2.1) Bump Go client version
perl -i -pe"s/^const Version = .*/const Version = \"${RELEASE_VERSION}\"/g" ./client/go/pkg/openlineage/version.go
# (3) Bump version in docs
perl -i -pe"s/<version>.*/<version>${RELEASE_VERSION}<\/version>/g" ./integration/spark/README.md
perl -i -pe"s/openlineage-spark:[[:alnum:]\.-]*/openlineage-spark:${RELEASE_VERSION}/g" ./integration/spark/README.md
perl -i -pe"s/openlineage-spark-.*jar/openlineage-spark-${RELEASE_VERSION}.jar/g" ./integration/spark/README.md
perl -i -pe"s/<version>.*/<version>${RELEASE_VERSION}<\/version>/g" ./integration/flink/README.md
perl -i -pe"s/<version>.*/<version>${RELEASE_VERSION}<\/version>/g" ./client/java/README.md
perl -i -pe"s/openlineage-java:[[:alnum:]\.-]*/openlineage-java:${RELEASE_VERSION}/g" ./client/java/README.md
# (4) Prepare release commit
git commit --no-verify -sam "Prepare for release ${RELEASE_VERSION}" --signoff
# (5) Pull latest tags, then prepare release tag
git fetch --all --tags
git tag -a "${RELEASE_VERSION}" -m "openlineage ${RELEASE_VERSION}"
# Required for go client so it can be imported with from github.com/OpenLineage/openlineage/client/go@v${RELEASE_VERSION}
git tag -a "client/go/v${RELEASE_VERSION}" -m "openlineage go-style version client/go/v${RELEASE_VERSION}"
# (6) Prepare next development version
# Determine bump type based on release version and next version
NEXT_BUMP_TYPE=$(determine_bump_type "${PYTHON_RELEASE_VERSION}" "${NEXT_VERSION}")
for PYTHON_MODULE in "${PYTHON_MODULES[@]}"; do
(cd "${PYTHON_MODULE}" && uv run bump-my-version bump "${NEXT_BUMP_TYPE}" --new-version "${NEXT_VERSION}" --config-file pyproject.toml --allow-dirty)
done
# Append '-SNAPSHOT' to 'NEXT_VERSION' if a release candidate, or missing
# (ex: '-SNAPSHOT' will be appended to X.Y.Z or X.Y.Z-rc.N)
if [[ "${NEXT_VERSION}" == *-rc.? ||
! "${NEXT_VERSION}" == *-SNAPSHOT ]]; then
NEXT_VERSION="${NEXT_VERSION}-SNAPSHOT"
fi
perl -i -pe"s/^version=.*/version=${NEXT_VERSION}/g" ./client/java/gradle.properties
perl -i -pe"s/^version=.*/version=${NEXT_VERSION}/g" ./integration/sql/iface-java/gradle.properties
perl -i -pe"s/^version=.*/version=${NEXT_VERSION}/g" ./integration/spark/gradle.properties
perl -i -pe"s/^version=.*/version=${NEXT_VERSION}/g" ./integration/spark-extension-interfaces/gradle.properties
perl -i -pe"s/^version=.*/version=${NEXT_VERSION}/g" ./integration/flink/gradle.properties
perl -i -pe"s/^version=.*/version=${NEXT_VERSION}/g" ./integration/flink/examples/flink1-test-apps/gradle.properties
perl -i -pe"s/^version=.*/version=${NEXT_VERSION}/g" ./integration/flink/examples/flink2-test-apps/gradle.properties
perl -i -pe"s/^version=.*/version=${NEXT_VERSION}/g" ./integration/hive/gradle.properties
perl -i -pe"s/^version=.*/version=${NEXT_VERSION}/g" ./integration/hive/hive-openlineage-hook/src/main/resources/io/openlineage/hive/client/version.properties
perl -i -pe"s/^const Version = .*/const Version = \"${NEXT_VERSION}\"/g" ./client/go/pkg/openlineage/version.go
echo "version ${NEXT_VERSION}" > integration/spark/spark3/src/test/resources/io/openlineage/spark/agent/version.properties
echo "version ${NEXT_VERSION}" > integration/spark-extension-interfaces/src/test/resources/io/openlineage/spark/shade/extension/v1/lifecycle/plan/version.properties
echo "version ${NEXT_VERSION}" > integration/flink/shared/src/test/resources/io/openlineage/flink/client/version.properties
echo "version ${NEXT_VERSION}" > integration/flink/flink1/src/test/resources/io/openlineage/flink/client/version.properties
echo "version ${NEXT_VERSION}" > integration/flink/flink2/src/test/resources/io/openlineage/flink/client/version.properties
# (7) Prepare next development version commit
git commit --no-verify -sam "Prepare next development version ${NEXT_VERSION}" --signoff
# (8) Check for commits in log
COMMITS=false
MESSAGE_1=$(git log -1 --grep="Prepare for release ${RELEASE_VERSION}" --pretty=format:%s)
MESSAGE_2=$(git log -1 --grep="Prepare next development version ${NEXT_VERSION}" --pretty=format:%s)
if [[ $MESSAGE_1 ]] && [[ $MESSAGE_2 ]]; then
COMMITS=true
else
echo "one or both commits failed; exiting..."
exit 0
fi
# (9) Push commits and tag
if [[ $COMMITS = "true" ]] && [[ ! ${PUSH} = "false" ]]; then
git push origin main && git push origin "${RELEASE_VERSION}" && git push origin "client/go/v${RELEASE_VERSION}"
else
echo "...skipping push; to push manually, use 'git push origin main && git push origin \"${RELEASE_VERSION}\"'"
fi
echo "DONE!"