@dream-encode/secret-santa-hat-build-tools 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/LICENSE +21 -0
- package/README.md +117 -0
- package/bin/config/release.conf.example +8 -0
- package/bin/lib/general-functions.sh +284 -0
- package/bin/lib/git-functions.sh +97 -0
- package/bin/lib/platform-utils.sh +43 -0
- package/bin/lib/release-functions.sh +198 -0
- package/bin/lib/tool-checker.sh +86 -0
- package/bin/release.sh +174 -0
- package/bin/setup.js +16 -0
- package/bin/ssh-release.js +52 -0
- package/package.json +45 -0
- package/scripts/postinstall.js +93 -0
- package/scripts/setup-project.js +214 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [NEXT_VERSION] - [UNRELEASED]
|
|
4
|
+
* BUG: Example fix description.
|
|
5
|
+
|
|
6
|
+
## [0.1.0] - 2026-07-16
|
|
7
|
+
* FEA: Initial release. Ships the `ssh-release` command, a JavaScript-tailored port of the `gcrq` (`git_create_release_quiet`) bash flow: branch and changelog guards, version bump across `package.json` and `public/manifest.json`, `[NEXT_VERSION]` placeholder replacement, changelog finalize and re-seed, release branch and tag, GitHub release with a compare link, merge to the default branch, and a service-worker version reset. Includes a postinstall that offers to wire a `release` script into the consuming project.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 David Baumwald
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# Secret Santa Hat Build Tools
|
|
2
|
+
|
|
3
|
+
Release tooling for the Secret Santa Hat JavaScript repositories. Ships the
|
|
4
|
+
`ssh-release` command, a JS-tailored port of the `gcrq`
|
|
5
|
+
(`git_create_release_quiet`) bash flow, so every repo releases the same way
|
|
6
|
+
without depending on a personal shell profile.
|
|
7
|
+
|
|
8
|
+
## What it does
|
|
9
|
+
|
|
10
|
+
Running `ssh-release` from a repo on the `development` (or `hotfix`) branch:
|
|
11
|
+
|
|
12
|
+
1. Verifies the branch and that `CHANGELOG.md` has a
|
|
13
|
+
`## [NEXT_VERSION] - [UNRELEASED]` section at the top.
|
|
14
|
+
2. Bumps the version (interactive menu, or `patch`/`minor`/`major`/`hotfix`):
|
|
15
|
+
- `package.json`
|
|
16
|
+
- `public/manifest.json` (if present)
|
|
17
|
+
- any file containing the `[NEXT_VERSION]` placeholder
|
|
18
|
+
3. Commits the bump, then rewrites the changelog `NEXT_VERSION` header to the
|
|
19
|
+
new version and date and commits that.
|
|
20
|
+
4. Pushes, creates a `release/<version>` branch, and tags `v<version>`.
|
|
21
|
+
5. Creates a GitHub release from the changelog notes and appends a
|
|
22
|
+
**Full Changelog** compare link.
|
|
23
|
+
6. Merges the release branch into the default branch (`main`/`master`) and
|
|
24
|
+
pushes it.
|
|
25
|
+
7. Re-seeds a fresh `NEXT_VERSION` changelog section and resets
|
|
26
|
+
`public/sw.js` `APP_VERSION` back to `[NEXT_VERSION]`, then returns to the
|
|
27
|
+
working branch.
|
|
28
|
+
|
|
29
|
+
JSON edits are done with `node` (always present in a Node project), so `jq` is
|
|
30
|
+
not required.
|
|
31
|
+
|
|
32
|
+
## Requirements
|
|
33
|
+
|
|
34
|
+
- **git**
|
|
35
|
+
- **gh** (GitHub CLI), authenticated: `gh auth login`
|
|
36
|
+
- **bash** — Git Bash on Windows; already present on macOS/Linux
|
|
37
|
+
- **node** — provided by the project itself
|
|
38
|
+
|
|
39
|
+
Check everything with:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
ssh-release --check-tools
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Install
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
# yarn (classic)
|
|
49
|
+
yarn add --dev @dream-encode/secret-santa-hat-build-tools
|
|
50
|
+
|
|
51
|
+
# npm
|
|
52
|
+
npm install --save-dev @dream-encode/secret-santa-hat-build-tools
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
After install, wire the `release` script into the project:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
npx @dream-encode/secret-santa-hat-build-tools setup # interactive
|
|
59
|
+
npx @dream-encode/secret-santa-hat-build-tools setup --force # no prompts
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
This sets `"release": "ssh-release"`. Any existing custom release script is
|
|
63
|
+
backed up as `release-backup`. An existing `prerelease` script is left alone.
|
|
64
|
+
|
|
65
|
+
## `yarn release` = prerelease + release
|
|
66
|
+
|
|
67
|
+
yarn (classic) and npm run a `prerelease` script automatically before
|
|
68
|
+
`release`. Keep each repo's pre-flight checks in its own `prerelease` script,
|
|
69
|
+
and `yarn release` runs them and then the release flow:
|
|
70
|
+
|
|
71
|
+
```jsonc
|
|
72
|
+
{
|
|
73
|
+
"scripts": {
|
|
74
|
+
// repo-specific pre-flight (tests, lint, build, browserslist refresh, ...)
|
|
75
|
+
"prerelease": "yarn maintenance && yarn test:unit",
|
|
76
|
+
// the shared release flow
|
|
77
|
+
"release": "ssh-release"
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
yarn release # prerelease, then interactive release
|
|
84
|
+
yarn release --dry-run
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Usage
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
ssh-release # interactive version selection
|
|
91
|
+
ssh-release patch # 1.0.0 -> 1.0.1
|
|
92
|
+
ssh-release minor # 1.0.0 -> 1.1.0
|
|
93
|
+
ssh-release major # 1.0.0 -> 2.0.0
|
|
94
|
+
ssh-release hotfix # 1.0.0 -> 1.0.0.1
|
|
95
|
+
ssh-release --dry-run minor # preview without making changes
|
|
96
|
+
ssh-release --check-tools # verify git + gh
|
|
97
|
+
ssh-release --help
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Because `release` passes arguments through, `yarn release patch` and
|
|
101
|
+
`yarn release --dry-run` work too.
|
|
102
|
+
|
|
103
|
+
## Configuration
|
|
104
|
+
|
|
105
|
+
Optional. Copy `bin/config/release.conf.example` to `bin/config/release.conf`
|
|
106
|
+
inside the installed package to override defaults:
|
|
107
|
+
|
|
108
|
+
- `SSH_RELEASE_MAIN_BRANCH` — the branch releases merge into (auto-detected as
|
|
109
|
+
`main`, then `master`, when unset).
|
|
110
|
+
|
|
111
|
+
## Notes
|
|
112
|
+
|
|
113
|
+
- Releases are allowed only from `development` or `hotfix`.
|
|
114
|
+
- The version bump commit runs `git add .`, so the working tree should hold
|
|
115
|
+
only what you intend to ship.
|
|
116
|
+
- The re-seeded `NEXT_VERSION` changelog section and the `sw.js` reset are left
|
|
117
|
+
uncommitted on the working branch, ready for the next cycle.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# secret-santa-hat-build-tools release configuration (optional).
|
|
2
|
+
#
|
|
3
|
+
# Copy this file to release.conf in the same directory to override defaults.
|
|
4
|
+
# It is sourced by release.sh before the release runs.
|
|
5
|
+
|
|
6
|
+
# Branch that releases are merged into. Auto-detected (main, then master) when
|
|
7
|
+
# unset.
|
|
8
|
+
# SSH_RELEASE_MAIN_BRANCH="main"
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# General helpers for secret-santa-hat-build-tools.
|
|
4
|
+
#
|
|
5
|
+
# JSON reads/writes go through node rather than jq: node is guaranteed present
|
|
6
|
+
# in a Node project and preserves the 2-space formatting these repos use.
|
|
7
|
+
|
|
8
|
+
# Detect the package manager for the current project.
|
|
9
|
+
function get_package_manager_for_project() {
|
|
10
|
+
if [ -f yarn.lock ]; then
|
|
11
|
+
echo "yarn"
|
|
12
|
+
else
|
|
13
|
+
echo "npm"
|
|
14
|
+
fi
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
# Read a version field from a JSON file. Usage: get_json_version <file>
|
|
18
|
+
function get_json_version() {
|
|
19
|
+
local file="$1"
|
|
20
|
+
|
|
21
|
+
node -e "process.stdout.write(String(JSON.parse(require('fs').readFileSync(process.argv[1],'utf8')).version || ''))" "$file" 2>/dev/null
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
# Read the project version from package.json.
|
|
25
|
+
function get_package_json_version() {
|
|
26
|
+
get_json_version "package.json"
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
# Write a version field to a JSON file, preserving 2-space formatting and a
|
|
30
|
+
# trailing newline. Usage: set_json_version <file> <version>
|
|
31
|
+
function set_json_version() {
|
|
32
|
+
local file="$1"
|
|
33
|
+
local version="$2"
|
|
34
|
+
|
|
35
|
+
node -e "const fs=require('fs');const f=process.argv[1];const v=process.argv[2];const j=JSON.parse(fs.readFileSync(f,'utf8'));j.version=v;fs.writeFileSync(f, JSON.stringify(j,null,2)+'\n');" "$file" "$version"
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
# Calculate a new version from a bump type. Supports X.X.X and X.X.X.X.
|
|
39
|
+
function calculate_new_version() {
|
|
40
|
+
local current_version="$1"
|
|
41
|
+
local bump_type="$2"
|
|
42
|
+
|
|
43
|
+
IFS='.' read -ra VERSION_PARTS <<< "$current_version"
|
|
44
|
+
|
|
45
|
+
local major=${VERSION_PARTS[0]}
|
|
46
|
+
local minor=${VERSION_PARTS[1]}
|
|
47
|
+
local patch=${VERSION_PARTS[2]}
|
|
48
|
+
local hotfix=${VERSION_PARTS[3]:-}
|
|
49
|
+
|
|
50
|
+
case $bump_type in
|
|
51
|
+
"patch")
|
|
52
|
+
patch=$((patch + 1))
|
|
53
|
+
hotfix=""
|
|
54
|
+
;;
|
|
55
|
+
"minor")
|
|
56
|
+
minor=$((minor + 1))
|
|
57
|
+
patch=0
|
|
58
|
+
hotfix=""
|
|
59
|
+
;;
|
|
60
|
+
"major")
|
|
61
|
+
major=$((major + 1))
|
|
62
|
+
minor=0
|
|
63
|
+
patch=0
|
|
64
|
+
hotfix=""
|
|
65
|
+
;;
|
|
66
|
+
"hotfix")
|
|
67
|
+
if [ -z "$hotfix" ]; then
|
|
68
|
+
hotfix=1
|
|
69
|
+
else
|
|
70
|
+
hotfix=$((hotfix + 1))
|
|
71
|
+
fi
|
|
72
|
+
;;
|
|
73
|
+
*)
|
|
74
|
+
echo "Invalid bump type: $bump_type. Use patch, minor, major, or hotfix." >&2
|
|
75
|
+
|
|
76
|
+
return 1
|
|
77
|
+
;;
|
|
78
|
+
esac
|
|
79
|
+
|
|
80
|
+
if [ -n "$hotfix" ]; then
|
|
81
|
+
echo "$major.$minor.$patch.$hotfix"
|
|
82
|
+
else
|
|
83
|
+
echo "$major.$minor.$patch"
|
|
84
|
+
fi
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
# Interactive menu selection with fzf/whiptail/numbered fallbacks.
|
|
88
|
+
function interactive_menu_select() {
|
|
89
|
+
local prompt="$1"
|
|
90
|
+
shift
|
|
91
|
+
local options=("$@")
|
|
92
|
+
|
|
93
|
+
if command -v fzf >/dev/null 2>&1; then
|
|
94
|
+
local result
|
|
95
|
+
result=$(printf '%s\n' "${options[@]}" | fzf --height=12 --layout=reverse --border --prompt="Select: " --header="$prompt")
|
|
96
|
+
|
|
97
|
+
if [ $? -eq 0 ] && [ -n "$result" ]; then
|
|
98
|
+
echo "$result"
|
|
99
|
+
|
|
100
|
+
return 0
|
|
101
|
+
fi
|
|
102
|
+
|
|
103
|
+
return 1
|
|
104
|
+
fi
|
|
105
|
+
|
|
106
|
+
if command -v whiptail >/dev/null 2>&1; then
|
|
107
|
+
local menu_items=()
|
|
108
|
+
local i
|
|
109
|
+
for i in "${!options[@]}"; do
|
|
110
|
+
menu_items+=("$((i+1))" "${options[i]}")
|
|
111
|
+
done
|
|
112
|
+
|
|
113
|
+
local choice
|
|
114
|
+
choice=$(whiptail --title "Version Bump" --menu "$prompt" 18 90 8 "${menu_items[@]}" 3>&1 1>&2 2>&3)
|
|
115
|
+
|
|
116
|
+
if [ $? -eq 0 ] && [ -n "$choice" ]; then
|
|
117
|
+
echo "${options[$((choice-1))]}"
|
|
118
|
+
|
|
119
|
+
return 0
|
|
120
|
+
fi
|
|
121
|
+
|
|
122
|
+
return 1
|
|
123
|
+
fi
|
|
124
|
+
|
|
125
|
+
echo "$prompt" >&2
|
|
126
|
+
echo "" >&2
|
|
127
|
+
|
|
128
|
+
local i
|
|
129
|
+
for i in "${!options[@]}"; do
|
|
130
|
+
echo " $((i+1))) ${options[i]}" >&2
|
|
131
|
+
done
|
|
132
|
+
echo "" >&2
|
|
133
|
+
|
|
134
|
+
while true; do
|
|
135
|
+
read -r -p "Enter your choice (1-${#options[@]}): " choice
|
|
136
|
+
if [[ "$choice" =~ ^[0-9]+$ ]] && [ "$choice" -ge 1 ] && [ "$choice" -le "${#options[@]}" ]; then
|
|
137
|
+
echo "${options[$((choice-1))]}"
|
|
138
|
+
|
|
139
|
+
return 0
|
|
140
|
+
fi
|
|
141
|
+
|
|
142
|
+
echo "Invalid choice. Please enter a number between 1 and ${#options[@]}." >&2
|
|
143
|
+
done
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
# Changelog helpers.
|
|
147
|
+
function changelog_exists() {
|
|
148
|
+
[ -f "CHANGELOG.md" ]
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
# True when CHANGELOG.md has a NEXT_VERSION / UNRELEASED section at the top.
|
|
152
|
+
function changelog_check_next_version() {
|
|
153
|
+
if changelog_exists && grep -q "## \[NEXT_VERSION\] - \[UNRELEASED\]" CHANGELOG.md; then
|
|
154
|
+
return 0
|
|
155
|
+
fi
|
|
156
|
+
|
|
157
|
+
return 1
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
# Extract the bullet notes for a version from CHANGELOG.md, as GitHub release
|
|
161
|
+
# body. Supports X.X.X and X.X.X.X.
|
|
162
|
+
function extract_version_updates_from_changelog() {
|
|
163
|
+
local RELEASE_VERSION="$1"
|
|
164
|
+
local CHANGELOG_FILE="CHANGELOG.md"
|
|
165
|
+
|
|
166
|
+
if [ ! -f "$CHANGELOG_FILE" ]; then
|
|
167
|
+
return 1
|
|
168
|
+
fi
|
|
169
|
+
|
|
170
|
+
awk -v ver="$RELEASE_VERSION" '
|
|
171
|
+
$0 ~ "^## \\[" ver "\\]" { print "## Changelog"; version_found=1; next }
|
|
172
|
+
/^## \[/ && version_found { exit }
|
|
173
|
+
version_found && /^\*/' "$CHANGELOG_FILE"
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
# Replace the NEXT_VERSION section header with the released version and date,
|
|
177
|
+
# then commit that changelog change.
|
|
178
|
+
function changelog_update_current_version() {
|
|
179
|
+
local CURRENT_VERSION="${1:-$(get_package_json_version)}"
|
|
180
|
+
|
|
181
|
+
if changelog_exists && grep -q "## \[NEXT_VERSION\]" CHANGELOG.md; then
|
|
182
|
+
local CURRENT_DATE
|
|
183
|
+
CURRENT_DATE=$(date +%Y-%m-%d)
|
|
184
|
+
|
|
185
|
+
sed_inplace "s/^## \[NEXT_VERSION\] - \[UNRELEASED\]$/## [$CURRENT_VERSION] - $CURRENT_DATE/" CHANGELOG.md
|
|
186
|
+
|
|
187
|
+
git add CHANGELOG.md >/dev/null 2>&1
|
|
188
|
+
git commit -m "Update changelog for v$CURRENT_VERSION" >/dev/null 2>&1
|
|
189
|
+
fi
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
# Re-seed a fresh NEXT_VERSION section above the just-released version.
|
|
193
|
+
function changelog_add_next_version_template() {
|
|
194
|
+
local CURRENT_VERSION=""
|
|
195
|
+
local QUIET_MODE="false"
|
|
196
|
+
|
|
197
|
+
while [[ $# -gt 0 ]]; do
|
|
198
|
+
case $1 in
|
|
199
|
+
--quiet)
|
|
200
|
+
QUIET_MODE="true"
|
|
201
|
+
shift
|
|
202
|
+
;;
|
|
203
|
+
--version)
|
|
204
|
+
CURRENT_VERSION="$2"
|
|
205
|
+
shift 2
|
|
206
|
+
;;
|
|
207
|
+
*)
|
|
208
|
+
echo "❌ Error: unknown argument '$1' for changelog_add_next_version_template" >&2
|
|
209
|
+
|
|
210
|
+
return 1
|
|
211
|
+
;;
|
|
212
|
+
esac
|
|
213
|
+
done
|
|
214
|
+
|
|
215
|
+
if [ -z "$CURRENT_VERSION" ]; then
|
|
216
|
+
CURRENT_VERSION=$(get_package_json_version)
|
|
217
|
+
fi
|
|
218
|
+
|
|
219
|
+
if changelog_exists; then
|
|
220
|
+
sed_inplace "s/^## \[$CURRENT_VERSION\]/## [NEXT_VERSION] - [UNRELEASED]\n* BUG: Example fix description.\n\n## [$CURRENT_VERSION]/" CHANGELOG.md
|
|
221
|
+
|
|
222
|
+
if [ "$QUIET_MODE" != "true" ]; then
|
|
223
|
+
echo "✅ Template changelog entry added to CHANGELOG.md"
|
|
224
|
+
fi
|
|
225
|
+
fi
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
# Replace [NEXT_VERSION] placeholders across project files (skipping the
|
|
229
|
+
# changelog, shell scripts, binaries, and dependency directories).
|
|
230
|
+
function replace_next_version_placeholders() {
|
|
231
|
+
local new_version="$1"
|
|
232
|
+
|
|
233
|
+
if ! command -v grep >/dev/null 2>&1; then
|
|
234
|
+
return 0
|
|
235
|
+
fi
|
|
236
|
+
|
|
237
|
+
local files
|
|
238
|
+
files=$(grep -r -l "\[NEXT_VERSION\]" . \
|
|
239
|
+
--exclude-dir=node_modules \
|
|
240
|
+
--exclude-dir=vendor \
|
|
241
|
+
--exclude-dir=.git \
|
|
242
|
+
--exclude-dir=dist \
|
|
243
|
+
--exclude-dir=build \
|
|
244
|
+
--exclude="*.zip" \
|
|
245
|
+
--exclude="*.tar.gz" \
|
|
246
|
+
--exclude="*.jpg" \
|
|
247
|
+
--exclude="*.jpeg" \
|
|
248
|
+
--exclude="*.png" \
|
|
249
|
+
--exclude="*.gif" \
|
|
250
|
+
--exclude="*.ico" \
|
|
251
|
+
--exclude="*.svg" \
|
|
252
|
+
--exclude="*.webp" \
|
|
253
|
+
--exclude="*.pdf" \
|
|
254
|
+
--exclude="*.woff" \
|
|
255
|
+
--exclude="*.woff2" \
|
|
256
|
+
--exclude="*.ttf" \
|
|
257
|
+
--exclude="*.eot" \
|
|
258
|
+
--exclude="*.mp4" \
|
|
259
|
+
--exclude="*.mp3" \
|
|
260
|
+
--exclude="*.wav" \
|
|
261
|
+
--exclude="*.lock" \
|
|
262
|
+
--exclude="*.sh" \
|
|
263
|
+
--exclude="CHANGELOG.md" \
|
|
264
|
+
2>/dev/null || true)
|
|
265
|
+
|
|
266
|
+
if [ -n "$files" ]; then
|
|
267
|
+
echo "$files" | while IFS= read -r file; do
|
|
268
|
+
if [ -f "$file" ]; then
|
|
269
|
+
sed_inplace "s/\[NEXT_VERSION\]/$new_version/g" "$file"
|
|
270
|
+
fi
|
|
271
|
+
done
|
|
272
|
+
|
|
273
|
+
echo " - Replaced [NEXT_VERSION] with $new_version in files."
|
|
274
|
+
fi
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
# Reset the service worker APP_VERSION back to the [NEXT_VERSION] template.
|
|
278
|
+
function update_service_worker_next_version_template() {
|
|
279
|
+
if [ -f "public/sw.js" ]; then
|
|
280
|
+
sed_inplace "s/const APP_VERSION *= *'[^']*'/const APP_VERSION = '[NEXT_VERSION]'/g" public/sw.js
|
|
281
|
+
|
|
282
|
+
echo " - Updated service worker version template."
|
|
283
|
+
fi
|
|
284
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Git and GitHub helpers for secret-santa-hat-build-tools.
|
|
4
|
+
|
|
5
|
+
# True when the current directory is inside a git repository.
|
|
6
|
+
function is_git_repo() {
|
|
7
|
+
git rev-parse --is-inside-work-tree >/dev/null 2>&1
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
# Print the current branch name.
|
|
11
|
+
function get_current_branch() {
|
|
12
|
+
git branch --show-current
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
# Determine the default branch to merge releases into. Honours an override from
|
|
16
|
+
# release.conf (SSH_RELEASE_MAIN_BRANCH), otherwise prefers main, then master.
|
|
17
|
+
function get_default_branch() {
|
|
18
|
+
if [ -n "${SSH_RELEASE_MAIN_BRANCH:-}" ]; then
|
|
19
|
+
echo "$SSH_RELEASE_MAIN_BRANCH"
|
|
20
|
+
|
|
21
|
+
return 0
|
|
22
|
+
fi
|
|
23
|
+
|
|
24
|
+
if git show-ref --verify --quiet refs/heads/main; then
|
|
25
|
+
echo "main"
|
|
26
|
+
elif git show-ref --verify --quiet refs/heads/master; then
|
|
27
|
+
echo "master"
|
|
28
|
+
else
|
|
29
|
+
echo "main"
|
|
30
|
+
fi
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
# Print owner/name for the current repo via the GitHub CLI.
|
|
34
|
+
function get_github_repo_info() {
|
|
35
|
+
gh repo view --json nameWithOwner -q '.nameWithOwner' 2>/dev/null
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
# Create a GitHub release for the given version, using changelog notes.
|
|
39
|
+
function github_create_release() {
|
|
40
|
+
local VERSION="$1"
|
|
41
|
+
|
|
42
|
+
if changelog_exists; then
|
|
43
|
+
local RELEASE_NOTES
|
|
44
|
+
RELEASE_NOTES=$(extract_version_updates_from_changelog "$VERSION")
|
|
45
|
+
|
|
46
|
+
if ! gh release create "v$VERSION" -n "$RELEASE_NOTES" -t "v$VERSION"; then
|
|
47
|
+
echo "Error: failed to create GitHub release v$VERSION" >&2
|
|
48
|
+
|
|
49
|
+
return 1
|
|
50
|
+
fi
|
|
51
|
+
else
|
|
52
|
+
if ! gh release create "v$VERSION" -t "v$VERSION" --generate-notes; then
|
|
53
|
+
echo "Error: failed to create GitHub release v$VERSION" >&2
|
|
54
|
+
|
|
55
|
+
return 1
|
|
56
|
+
fi
|
|
57
|
+
fi
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
# Generate a GitHub compare URL between two tags.
|
|
61
|
+
function github_generate_tags_compare_link() {
|
|
62
|
+
local prev_tag="$1"
|
|
63
|
+
local current_tag="$2"
|
|
64
|
+
local repo
|
|
65
|
+
repo=$(get_github_repo_info)
|
|
66
|
+
|
|
67
|
+
echo "https://github.com/${repo}/compare/${prev_tag}...${current_tag}"
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
# Append a "Full Changelog" compare link to an existing GitHub release.
|
|
71
|
+
function github_release_add_compare_link() {
|
|
72
|
+
local current_version="$1"
|
|
73
|
+
local current_tag="v${current_version}"
|
|
74
|
+
local prev_tag
|
|
75
|
+
prev_tag=$(git tag -l --sort=-version:refname "v*" | sed -n '2p')
|
|
76
|
+
|
|
77
|
+
if [ -z "$prev_tag" ]; then
|
|
78
|
+
return 0
|
|
79
|
+
fi
|
|
80
|
+
|
|
81
|
+
local compare_url
|
|
82
|
+
compare_url=$(github_generate_tags_compare_link "$prev_tag" "$current_tag")
|
|
83
|
+
|
|
84
|
+
local display="${prev_tag}...${current_tag}"
|
|
85
|
+
local compare_line="**Full Changelog:** [\`${display}\`](${compare_url})"
|
|
86
|
+
|
|
87
|
+
local existing_notes
|
|
88
|
+
existing_notes=$(gh release view "$current_tag" --json body -q '.body' 2>/dev/null)
|
|
89
|
+
|
|
90
|
+
local updated_notes="${existing_notes}"$'\n\n'"${compare_line}"
|
|
91
|
+
|
|
92
|
+
if ! gh release edit "$current_tag" --notes "$updated_notes"; then
|
|
93
|
+
echo "Warning: failed to add compare link to release $current_tag" >&2
|
|
94
|
+
|
|
95
|
+
return 1
|
|
96
|
+
fi
|
|
97
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Cross-platform helpers for secret-santa-hat-build-tools.
|
|
4
|
+
|
|
5
|
+
# Detect the current platform.
|
|
6
|
+
function get_platform() {
|
|
7
|
+
case "$OSTYPE" in
|
|
8
|
+
msys*|cygwin*|mingw*)
|
|
9
|
+
echo "windows"
|
|
10
|
+
;;
|
|
11
|
+
darwin*)
|
|
12
|
+
echo "macos"
|
|
13
|
+
;;
|
|
14
|
+
linux*)
|
|
15
|
+
echo "linux"
|
|
16
|
+
;;
|
|
17
|
+
*)
|
|
18
|
+
echo "unknown"
|
|
19
|
+
;;
|
|
20
|
+
esac
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
# File existence check.
|
|
24
|
+
function file_exists() {
|
|
25
|
+
[ -f "$1" ]
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
# Command existence check.
|
|
29
|
+
function command_exists() {
|
|
30
|
+
command -v "$1" >/dev/null 2>&1
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
# Cross-platform sed in-place editing.
|
|
34
|
+
function sed_inplace() {
|
|
35
|
+
local pattern="$1"
|
|
36
|
+
local file="$2"
|
|
37
|
+
|
|
38
|
+
if [[ "$(get_platform)" == "macos" ]]; then
|
|
39
|
+
sed -i '' "$pattern" "$file"
|
|
40
|
+
else
|
|
41
|
+
sed -i "$pattern" "$file"
|
|
42
|
+
fi
|
|
43
|
+
}
|