-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Expand file tree
/
Copy pathlerna-publish.sh
More file actions
executable file
路131 lines (116 loc) 路 5 KB
/
Copy pathlerna-publish.sh
File metadata and controls
executable file
路131 lines (116 loc) 路 5 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
#!/bin/bash
set -e
usage() {
echo "Usage: $0 [bump] [-y|--yes]"
echo
echo " bump version bump to pass to lerna (default: patch)"
echo " -y, --yes skip lerna's confirmation prompt for the release step"
echo
echo "The release step asks for confirmation before it commits, tags, pushes and"
echo "creates the GitHub release. Pass --yes to run it unattended."
}
BUMP=patch
CONFIRM=()
while [ $# -gt 0 ]; do
case "$1" in
-y|--yes) CONFIRM=(--yes) ;;
-h|--help) usage; exit 0 ;;
-*) echo "Error: unknown option: $1"; echo; usage; exit 1 ;;
*) BUMP="$1" ;;
esac
shift
done
# Without --yes the release step prompts, and lerna's prompt cannot be answered
# where stdin is not a terminal - it fails there with a bare exit 1 that says
# nothing about why. Say it here instead.
if [ ${#CONFIRM[@]} -eq 0 ] && [ ! -t 0 ]; then
echo "Error: stdin is not a terminal, so the release step's confirmation prompt"
echo "cannot be answered. Re-run with --yes to release unattended."
exit 1
fi
# GH_TOKEN, for the release step's --create-release=github. Sourced after the
# argument checks so that --help works on a checkout that has no .gh-token yet
# - the file is gitignored, so a fresh clone never has one.
. .gh-token
# Cleanup below discards staged as well as unstaged changes to tracked files.
# Refuse to start if the tree already carries any, so that cleanup can only ever
# undo what this script itself did. This gate runs before the trap is installed,
# so a tree it rejects is never touched.
# Untracked files are deliberately not checked: `git restore` cannot touch them,
# and build output that no .gitignore covers must not block a release.
if [ -n "$(git status --porcelain --untracked-files=no)" ]; then
echo "Error: working tree has uncommitted changes to tracked files."
echo "Commit or stash them before releasing - cleanup would discard them."
echo "If this is leftover state from a failed release run, discard it with:"
echo " git restore --staged --worktree ."
GIT_PAGER=cat git status --short --untracked-files=no
exit 1
fi
# Step 4 undoes the bump on the happy path, but `set -e` aborts before reaching
# it if step 1 or step 2 fails, so the same restore also runs from a trap:
# otherwise a failed run leaves behind the bumped, partly staged tree that trips
# lerna's working tree validation on the next run.
# lerna also writes a CHANGELOG.md for any package that lacks one, and a newly
# created one is untracked, so `git restore` alone would leave it behind - the
# pathspecs match the workspace globs ("workspaces" in package.json) and
# nothing else in the tree.
# INT and TERM are named alongside EXIT so an interrupted run is covered without
# relying on the shell running an EXIT trap for an untrapped signal; the handler
# disarms itself first so its own `exit` cannot run the cleanup a second time,
# then re-raises the signal so an interrupted run does not exit 0.
restore_bump() {
git restore --staged --worktree . || true
git clean -fdq -- 'packages/*/CHANGELOG.md' 'rust/*/CHANGELOG.md' || true
}
cleanup_bump() {
status=$?
sig=$1
trap - EXIT INT TERM
echo "Cleaning up temporary version bump..."
restore_bump
if [ -n "$sig" ]; then
# Die from the signal now that it is untrapped, so the caller sees the run
# was interrupted. Exiting with $? instead would report the last completed
# command's status, which is 0 when the signal lands between commands.
kill -"$sig" $$
fi
exit $status
}
trap cleanup_bump EXIT
trap 'cleanup_bump INT' INT
trap 'cleanup_bump TERM' TERM
# Always unattended: this bump is thrown away by the cleanup above, so there is
# nothing for an operator to confirm. Only the release step below asks.
echo "Step 1: bumping versions (no commit/push)..."
yarn lerna version "$BUMP" \
--conventional-commits \
--force-publish \
--exact \
--no-git-tag-version \
--no-push \
--yes
echo "Step 2: doing yarn install check..."
CUBESTORE_SKIP_POST_INSTALL=true yarn install
echo "Step 3: checking git status..."
if git status --porcelain | grep -q '^ M yarn.lock'; then
echo "Error: yarn.lock is not clean after version bump and yarn install. Please review the changes and fix it or commit."
echo "If you see any new entries in yarn.lock with @cubejs-*/* packages - probably not all packages versions were updated."
GIT_PAGER=cat git diff yarn.lock
exit 1
fi
# Step 1's bump has to come back out before the real one: lerna reads the
# versions in the tree to compute the next ones, and refuses to commit over a
# dirty tree at all. This is the happy path, not error handling - the trap
# below only covers the runs that never get here.
echo "Step 4: cleaning up temporary version bump..."
restore_bump
# Restore first, then disarm, so an interrupt during the restore is still
# covered. From here the version commit, tag and release are meant to survive.
trap - EXIT INT TERM
echo "Step 5: commit, tag and push version..."
yarn lerna version "$BUMP" \
--conventional-commits \
--force-publish \
--exact \
--create-release=github \
"${CONFIRM[@]}"