-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathcreate-pr-release
More file actions
executable file
·145 lines (120 loc) · 4.67 KB
/
create-pr-release
File metadata and controls
executable file
·145 lines (120 loc) · 4.67 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
#!/usr/bin/env bash
set -euo pipefail
VERSION="${1:-}"
# Ensure we're in a directory with a package.json
if [[ ! -f package.json ]]; then
echo "Error: no package.json in current directory" >&2
exit 1
fi
if [[ -n "$(git status --porcelain 2>/dev/null)" ]]; then
printf '\033[33mWarning: git working tree is dirty.\033[0m\n' >&2
fi
# ---------------------------------------------------------------------------
# Resolve VERSION
# ---------------------------------------------------------------------------
if [[ -z "$VERSION" ]]; then
# No version argument — check for an open PR and suggest one
if ! command -v gh &>/dev/null; then
echo "Error: 'gh' CLI is required when no version argument is provided." >&2
exit 1
fi
PR_NUMBER="$(gh pr view --json number -q .number 2>/dev/null || true)"
if [[ -z "$PR_NUMBER" ]]; then
echo "Usage: ext-release-create <version>" >&2
echo " version: x.y.z | x.y.z-prNNN | x.y.z-prNNN-shorthash" >&2
echo "" >&2
echo "No open PR detected for the current branch, so cannot auto-suggest a version." >&2
exit 1
fi
BASE_VERSION="$(jq -r .version package.json)"
SHORT_HASH="$(git rev-parse --short HEAD)"
VERSION="${BASE_VERSION}-pr${PR_NUMBER}-${SHORT_HASH}"
echo "Open PR #${PR_NUMBER} detected."
echo "Generated version: $VERSION"
echo "Releasing in 5s, ctrl-c to cancel..."
sleep 5
fi
# ---------------------------------------------------------------------------
# Validate VERSION — allowed forms:
# x.y.z
# x.y.z-pr123
# x.y.z-pr123-shorthash
# Explicitly forbid x.y.z.prNNN (dot before pr)
# ---------------------------------------------------------------------------
if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[0-9a-zA-Z][-0-9a-zA-Z]*)*$ ]]; then
echo "Error: version must match x.y.z, x.y.z-prNNN, or x.y.z-prNNN-shorthash" >&2
echo " (dot-separated pre-release like x.y.z.prNNN is NOT allowed)" >&2
exit 1
fi
# Resolve PR_NUMBER if not already set (i.e. version was supplied directly)
if [[ -z "${PR_NUMBER:-}" ]]; then
PR_NUMBER="$(gh pr view --json number -q .number 2>/dev/null || true)"
fi
NAME="$(jq -r .name package.json)"
ORIGINAL_VERSION="$(jq -r .version package.json)"
VSIX_FILE="${NAME}-${VERSION}.vsix"
PACKAGE_JSON_BACKUP="$(mktemp "${TMPDIR:-/tmp}/package.json.backup.XXXXXX")"
cp -p package.json "$PACKAGE_JSON_BACKUP"
NOTES_FILE="$(mktemp "${TMPDIR:-/tmp}/release-notes.XXXXXX.md")"
cleanup() {
if [[ -f "$PACKAGE_JSON_BACKUP" ]]; then
echo "Restoring package.json from backup"
cp -p "$PACKAGE_JSON_BACKUP" package.json
fi
rm -f "$PACKAGE_JSON_BACKUP"
rm -f "$NOTES_FILE"
}
trap cleanup EXIT
echo "==> Bumping version: $ORIGINAL_VERSION -> $VERSION"
jq --arg v "$VERSION" '.version = $v' package.json > package.json.tmp && mv package.json.tmp package.json
echo "==> Installing dependencies"
pnpm install
# Conditionally build webviews if the script exists
if jq -e '.scripts["build:webviews"]' package.json &>/dev/null; then
echo "==> Installing webview dependencies"
(cd webviews/codex-webviews && pnpm install)
echo "==> Building webviews"
pnpm run build:webviews
fi
echo "==> Building extension (production)"
pnpm run package
echo "==> Packaging VSIX"
# No dependencies results in errors like can't find codicon.css. We should probably bundle depens explicitly.
pnpm dlx @vscode/vsce package --no-dependencies
#pnpm dlx @vscode/vsce package
echo "==> Restoring version before release"
cleanup
trap - EXIT
# We need to ensure head is on remote so it's there to attach the release to.
# Skip verify as we just built and tested successfully.
git push --no-verify
REPO_URL="$(gh repo view --json url -q .url)"
REPO_SLUG="${REPO_URL#https://github.com/}"
RELEASE_URL="${REPO_URL}/releases/tag/${VERSION}"
# Build release notes with PR header
GENERATED_NOTES="$(gh api "repos/${REPO_SLUG}/releases/generate-notes" \
--method POST \
--field tag_name="$VERSION" \
--field target_commitish="$(git rev-parse HEAD)" \
-q .body)"
if [[ -n "${PR_NUMBER:-}" ]]; then
PR_URL="${REPO_URL}/pull/${PR_NUMBER}"
PR_TITLE="$(gh pr view "$PR_NUMBER" --json title -q .title)"
printf 'For PR #%s: [%s](%s)\n\n%s\n' \
"$PR_NUMBER" "$PR_TITLE" "$PR_URL" "$GENERATED_NOTES" > "$NOTES_FILE"
else
printf '%s\n' "$GENERATED_NOTES" > "$NOTES_FILE"
fi
echo "==> Creating GitHub prerelease: $VERSION"
gh release create "$VERSION" \
--target "$(git rev-parse HEAD)" \
--prerelease \
--title "$VERSION" \
--notes-file "$NOTES_FILE" \
"./$VSIX_FILE"
echo "Done! Prerelease $VERSION created with $VSIX_FILE"
if [[ -n "${PR_NUMBER:-}" ]]; then
gh pr comment "$PR_NUMBER" --body "Pre-release: ${VERSION} ${RELEASE_URL}"
echo "Commented PR #${PR_NUMBER} ${PR_URL}"
fi
open "$REPO_URL/releases"