@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
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# The release orchestrator for secret-santa-hat-build-tools.
|
|
4
|
+
#
|
|
5
|
+
# Ported from git_create_release_quiet (gcrq). Given a JS project on the
|
|
6
|
+
# development or hotfix branch with a NEXT_VERSION changelog section, it bumps
|
|
7
|
+
# the version, finalizes and re-seeds the changelog, tags and pushes a release
|
|
8
|
+
# branch, publishes a GitHub release, merges into the default branch, and
|
|
9
|
+
# leaves the working branch ready for the next cycle.
|
|
10
|
+
#
|
|
11
|
+
# Honours DRY_RUN (set by the --dry-run flag): when true, it performs every
|
|
12
|
+
# read-only check and computes the target version but makes no changes.
|
|
13
|
+
|
|
14
|
+
# Clean, intentional abort. Clears the ERR trap first so a controlled failure
|
|
15
|
+
# does not print the "failed unexpectedly" backstop message, then exits.
|
|
16
|
+
function _release_abort() {
|
|
17
|
+
trap - ERR 2>/dev/null || true
|
|
18
|
+
|
|
19
|
+
exit 1
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function ssh_create_release() {
|
|
23
|
+
local version_bump="$1"
|
|
24
|
+
|
|
25
|
+
local PACKAGE_MANAGER CURRENT_VERSION CURRENT_BRANCH DEFAULT_BRANCH
|
|
26
|
+
PACKAGE_MANAGER=$(get_package_manager_for_project)
|
|
27
|
+
CURRENT_VERSION=$(get_package_json_version)
|
|
28
|
+
CURRENT_BRANCH=$(get_current_branch)
|
|
29
|
+
DEFAULT_BRANCH=$(get_default_branch)
|
|
30
|
+
|
|
31
|
+
# --- Guards -------------------------------------------------------------
|
|
32
|
+
if ! is_git_repo; then
|
|
33
|
+
echo "โ Error: not inside a git repository."
|
|
34
|
+
|
|
35
|
+
_release_abort
|
|
36
|
+
fi
|
|
37
|
+
|
|
38
|
+
if [ ! -f "package.json" ]; then
|
|
39
|
+
echo "โ Error: no package.json found in $(pwd)."
|
|
40
|
+
|
|
41
|
+
_release_abort
|
|
42
|
+
fi
|
|
43
|
+
|
|
44
|
+
if [ "$CURRENT_BRANCH" != "development" ] && [ "$CURRENT_BRANCH" != "hotfix" ]; then
|
|
45
|
+
echo "โ Error: releases can only be created from 'development' or 'hotfix'."
|
|
46
|
+
echo " Current branch: $CURRENT_BRANCH"
|
|
47
|
+
|
|
48
|
+
_release_abort
|
|
49
|
+
fi
|
|
50
|
+
|
|
51
|
+
if ! changelog_check_next_version; then
|
|
52
|
+
echo "โ Error: the top CHANGELOG.md entry is not '## [NEXT_VERSION] - [UNRELEASED]'."
|
|
53
|
+
echo " Update CHANGELOG.md before releasing."
|
|
54
|
+
|
|
55
|
+
_release_abort
|
|
56
|
+
fi
|
|
57
|
+
|
|
58
|
+
# --- Determine the target version --------------------------------------
|
|
59
|
+
local NEW_VERSION=""
|
|
60
|
+
local do_bump="true"
|
|
61
|
+
|
|
62
|
+
if [ -n "$version_bump" ]; then
|
|
63
|
+
NEW_VERSION=$(calculate_new_version "$CURRENT_VERSION" "$version_bump")
|
|
64
|
+
else
|
|
65
|
+
echo ""
|
|
66
|
+
printf " ๐ข Version selection required (current: %s)\n" "$CURRENT_VERSION"
|
|
67
|
+
|
|
68
|
+
local options=(
|
|
69
|
+
"patch - Bug fixes (${CURRENT_VERSION} -> $(calculate_new_version "$CURRENT_VERSION" "patch"))"
|
|
70
|
+
"minor - New features (${CURRENT_VERSION} -> $(calculate_new_version "$CURRENT_VERSION" "minor"))"
|
|
71
|
+
"major - Breaking changes (${CURRENT_VERSION} -> $(calculate_new_version "$CURRENT_VERSION" "major"))"
|
|
72
|
+
"hotfix - Critical fixes (${CURRENT_VERSION} -> $(calculate_new_version "$CURRENT_VERSION" "hotfix"))"
|
|
73
|
+
"custom - Enter a custom version"
|
|
74
|
+
"stay - Stay at current version (${CURRENT_VERSION})"
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
local selected
|
|
78
|
+
selected=$(interactive_menu_select "Choose the version for this release:" "${options[@]}")
|
|
79
|
+
|
|
80
|
+
if [ -z "$selected" ]; then
|
|
81
|
+
echo "โ Version selection cancelled. Aborting release."
|
|
82
|
+
|
|
83
|
+
_release_abort
|
|
84
|
+
fi
|
|
85
|
+
|
|
86
|
+
local action
|
|
87
|
+
action=$(echo "$selected" | cut -d' ' -f1)
|
|
88
|
+
printf " โ
Selected: %s\n" "$selected"
|
|
89
|
+
|
|
90
|
+
case "$action" in
|
|
91
|
+
stay)
|
|
92
|
+
do_bump="false"
|
|
93
|
+
NEW_VERSION="$CURRENT_VERSION"
|
|
94
|
+
;;
|
|
95
|
+
custom)
|
|
96
|
+
read -r -e -p "Enter custom version: " -i "$CURRENT_VERSION" NEW_VERSION
|
|
97
|
+
if [ -z "$NEW_VERSION" ]; then
|
|
98
|
+
echo "โ No version supplied. Aborting release."
|
|
99
|
+
|
|
100
|
+
_release_abort
|
|
101
|
+
fi
|
|
102
|
+
;;
|
|
103
|
+
*)
|
|
104
|
+
NEW_VERSION=$(calculate_new_version "$CURRENT_VERSION" "$action")
|
|
105
|
+
;;
|
|
106
|
+
esac
|
|
107
|
+
fi
|
|
108
|
+
|
|
109
|
+
# --- Dry run: report the plan and stop ---------------------------------
|
|
110
|
+
if [ "${DRY_RUN:-false}" = "true" ]; then
|
|
111
|
+
echo ""
|
|
112
|
+
echo "๐งช Dry run - no changes will be made."
|
|
113
|
+
echo " - Package manager: $PACKAGE_MANAGER"
|
|
114
|
+
echo " - Current branch: $CURRENT_BRANCH"
|
|
115
|
+
echo " - Default branch: $DEFAULT_BRANCH"
|
|
116
|
+
echo " - Current version: $CURRENT_VERSION"
|
|
117
|
+
|
|
118
|
+
if [ "$do_bump" = "true" ]; then
|
|
119
|
+
echo " - Target version: $NEW_VERSION"
|
|
120
|
+
else
|
|
121
|
+
echo " - Target version: $CURRENT_VERSION (staying)"
|
|
122
|
+
fi
|
|
123
|
+
|
|
124
|
+
echo ""
|
|
125
|
+
echo " Would then: bump versions, replace [NEXT_VERSION] placeholders, commit,"
|
|
126
|
+
echo " finalize the changelog, push, create release/$NEW_VERSION, tag v$NEW_VERSION,"
|
|
127
|
+
echo " publish a GitHub release, merge into $DEFAULT_BRANCH, and re-seed the changelog."
|
|
128
|
+
echo ""
|
|
129
|
+
echo " โ
Dry run complete."
|
|
130
|
+
|
|
131
|
+
return 0
|
|
132
|
+
fi
|
|
133
|
+
|
|
134
|
+
# --- Apply the version bump --------------------------------------------
|
|
135
|
+
if [ "$do_bump" = "true" ]; then
|
|
136
|
+
set_json_version "package.json" "$NEW_VERSION"
|
|
137
|
+
echo " - Updated package.json."
|
|
138
|
+
|
|
139
|
+
if [ -f "public/manifest.json" ]; then
|
|
140
|
+
set_json_version "public/manifest.json" "$NEW_VERSION"
|
|
141
|
+
echo " - Updated public/manifest.json."
|
|
142
|
+
fi
|
|
143
|
+
|
|
144
|
+
replace_next_version_placeholders "$NEW_VERSION"
|
|
145
|
+
|
|
146
|
+
git add . >/dev/null 2>&1
|
|
147
|
+
git commit -m "Version $NEW_VERSION bump." >/dev/null 2>&1
|
|
148
|
+
echo " - Committed version bump."
|
|
149
|
+
fi
|
|
150
|
+
|
|
151
|
+
# Refresh version in case it changed.
|
|
152
|
+
CURRENT_VERSION=$(get_package_json_version)
|
|
153
|
+
|
|
154
|
+
# --- Finalize the changelog for this version ---------------------------
|
|
155
|
+
changelog_update_current_version "$CURRENT_VERSION"
|
|
156
|
+
echo " - Finalized changelog for v$CURRENT_VERSION."
|
|
157
|
+
|
|
158
|
+
# --- Push, branch, tag -------------------------------------------------
|
|
159
|
+
git push -q >/dev/null 2>&1
|
|
160
|
+
|
|
161
|
+
git checkout -b "release/$CURRENT_VERSION" >/dev/null 2>&1
|
|
162
|
+
git push -q --set-upstream origin "release/$CURRENT_VERSION" >/dev/null 2>&1
|
|
163
|
+
echo " - Release branch created."
|
|
164
|
+
|
|
165
|
+
git tag -a "v$CURRENT_VERSION" -m "Version $CURRENT_VERSION" >/dev/null 2>&1
|
|
166
|
+
git push -q -u origin "v$CURRENT_VERSION" >/dev/null 2>&1
|
|
167
|
+
echo " - Tagged v$CURRENT_VERSION."
|
|
168
|
+
|
|
169
|
+
# --- GitHub release ----------------------------------------------------
|
|
170
|
+
if ! github_create_release "$CURRENT_VERSION"; then
|
|
171
|
+
echo "โ Error: GitHub release creation failed. Aborting." >&2
|
|
172
|
+
|
|
173
|
+
_release_abort
|
|
174
|
+
fi
|
|
175
|
+
|
|
176
|
+
if ! github_release_add_compare_link "$CURRENT_VERSION"; then
|
|
177
|
+
echo "โ ๏ธ Warning: failed to add compare link to the release." >&2
|
|
178
|
+
fi
|
|
179
|
+
|
|
180
|
+
echo " - GitHub release created."
|
|
181
|
+
|
|
182
|
+
# --- Merge into the default branch -------------------------------------
|
|
183
|
+
git checkout "$DEFAULT_BRANCH" >/dev/null 2>&1
|
|
184
|
+
git merge "release/$CURRENT_VERSION" --no-ff -m "Merge release/$CURRENT_VERSION into $DEFAULT_BRANCH" >/dev/null 2>&1
|
|
185
|
+
git push -q origin "$DEFAULT_BRANCH" >/dev/null 2>&1
|
|
186
|
+
echo " - Merged release/$CURRENT_VERSION into $DEFAULT_BRANCH."
|
|
187
|
+
|
|
188
|
+
# --- Re-seed for the next cycle ----------------------------------------
|
|
189
|
+
# These changes are left uncommitted and carried back to the working branch
|
|
190
|
+
# by the checkout below, matching the gcrq end state.
|
|
191
|
+
changelog_add_next_version_template --quiet
|
|
192
|
+
update_service_worker_next_version_template
|
|
193
|
+
|
|
194
|
+
git checkout "$CURRENT_BRANCH" >/dev/null 2>&1
|
|
195
|
+
|
|
196
|
+
echo ""
|
|
197
|
+
echo " โ
Release v$CURRENT_VERSION created."
|
|
198
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Tool availability checker for secret-santa-hat-build-tools.
|
|
4
|
+
#
|
|
5
|
+
# The JS repos only need git and an authenticated GitHub CLI. JSON edits are
|
|
6
|
+
# done with node, which is always present in a Node project, so jq is not
|
|
7
|
+
# required.
|
|
8
|
+
|
|
9
|
+
if ! command -v get_platform >/dev/null 2>&1; then
|
|
10
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
|
+
# shellcheck disable=SC1091
|
|
12
|
+
source "$SCRIPT_DIR/platform-utils.sh"
|
|
13
|
+
fi
|
|
14
|
+
|
|
15
|
+
# Check a single tool and print its version.
|
|
16
|
+
function check_tool() {
|
|
17
|
+
local tool="$1"
|
|
18
|
+
local description="$2"
|
|
19
|
+
|
|
20
|
+
if command_exists "$tool"; then
|
|
21
|
+
local version
|
|
22
|
+
version=$("$tool" --version 2>/dev/null | head -1 || echo "available")
|
|
23
|
+
echo "โ
$tool: $version"
|
|
24
|
+
|
|
25
|
+
return 0
|
|
26
|
+
fi
|
|
27
|
+
|
|
28
|
+
echo "โ $tool: not found - $description"
|
|
29
|
+
|
|
30
|
+
return 1
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
# Check that the GitHub CLI is authenticated.
|
|
34
|
+
function check_gh_auth() {
|
|
35
|
+
if ! command_exists "gh"; then
|
|
36
|
+
echo "โ gh: not installed - GitHub CLI (required for releases)"
|
|
37
|
+
|
|
38
|
+
return 1
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
if gh auth status >/dev/null 2>&1; then
|
|
42
|
+
echo "โ
gh: authenticated"
|
|
43
|
+
|
|
44
|
+
return 0
|
|
45
|
+
fi
|
|
46
|
+
|
|
47
|
+
echo "โ ๏ธ gh: not authenticated (run 'gh auth login')"
|
|
48
|
+
|
|
49
|
+
return 1
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
# Check all required tools. Pass "true" to suppress the per-tool output.
|
|
53
|
+
function check_all_tools() {
|
|
54
|
+
local quiet_mode="${1:-false}"
|
|
55
|
+
local failed=0
|
|
56
|
+
|
|
57
|
+
if ! check_tool "git" "Version control (required)"; then
|
|
58
|
+
failed=$((failed + 1))
|
|
59
|
+
fi
|
|
60
|
+
|
|
61
|
+
if ! check_tool "node" "Node.js runtime (required for JSON edits)"; then
|
|
62
|
+
failed=$((failed + 1))
|
|
63
|
+
fi
|
|
64
|
+
|
|
65
|
+
if ! check_gh_auth; then
|
|
66
|
+
failed=$((failed + 1))
|
|
67
|
+
fi
|
|
68
|
+
|
|
69
|
+
if [ "$quiet_mode" != "true" ]; then
|
|
70
|
+
echo ""
|
|
71
|
+
echo "๐ Platform: $(get_platform)"
|
|
72
|
+
fi
|
|
73
|
+
|
|
74
|
+
if [ "$failed" -gt 0 ]; then
|
|
75
|
+
return 1
|
|
76
|
+
fi
|
|
77
|
+
|
|
78
|
+
return 0
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
# Silent pass/fail check for use as a gate.
|
|
82
|
+
function quick_tool_check() {
|
|
83
|
+
check_all_tools "true" >/dev/null 2>&1
|
|
84
|
+
|
|
85
|
+
return $?
|
|
86
|
+
}
|
package/bin/release.sh
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Secret Santa Hat release script.
|
|
4
|
+
#
|
|
5
|
+
# A JavaScript-tailored port of the `git_create_release_quiet` (gcrq) bash
|
|
6
|
+
# function. Handles version bumping, changelog management, git tagging, GitHub
|
|
7
|
+
# releases, and the post-release merge/reseed cycle for the Secret Santa Hat
|
|
8
|
+
# JS repositories.
|
|
9
|
+
|
|
10
|
+
set -e
|
|
11
|
+
|
|
12
|
+
trap 'printf "\nโ Release failed unexpectedly on line %s (exit code: %s).\n" "$LINENO" "$?" >&2' ERR
|
|
13
|
+
|
|
14
|
+
export LANG="${LANG:-en_US.UTF-8}"
|
|
15
|
+
export LC_ALL="${LC_ALL:-en_US.UTF-8}"
|
|
16
|
+
export TERM="${TERM:-xterm-256color}"
|
|
17
|
+
|
|
18
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
19
|
+
USER_PROJECT_DIR="$(pwd)"
|
|
20
|
+
|
|
21
|
+
function show_help() {
|
|
22
|
+
cat << 'EOF'
|
|
23
|
+
NAME
|
|
24
|
+
ssh-release - Secret Santa Hat release tool
|
|
25
|
+
|
|
26
|
+
SYNOPSIS
|
|
27
|
+
ssh-release [OPTIONS] [VERSION_TYPE]
|
|
28
|
+
|
|
29
|
+
DESCRIPTION
|
|
30
|
+
Creates a release for a Secret Santa Hat JavaScript project: bumps the
|
|
31
|
+
version, finalizes the changelog, tags the release, publishes a GitHub
|
|
32
|
+
release, merges into the default branch, and re-seeds the next changelog
|
|
33
|
+
section. Ported from the gcrq (git_create_release_quiet) bash flow.
|
|
34
|
+
|
|
35
|
+
Releases can only be created from the 'development' or 'hotfix' branch, and
|
|
36
|
+
CHANGELOG.md must have a "## [NEXT_VERSION] - [UNRELEASED]" section at the
|
|
37
|
+
top.
|
|
38
|
+
|
|
39
|
+
OPTIONS
|
|
40
|
+
--check-tools Check that git and gh (authenticated) are available
|
|
41
|
+
--dry-run Walk through the release without pushing, tagging, or
|
|
42
|
+
publishing anything (still shows the computed version)
|
|
43
|
+
--help, -h Show this help message
|
|
44
|
+
--version, -v Show version information
|
|
45
|
+
|
|
46
|
+
VERSION_TYPE
|
|
47
|
+
patch Bug fixes (1.0.0 -> 1.0.1)
|
|
48
|
+
minor New features (1.0.0 -> 1.1.0)
|
|
49
|
+
major Breaking changes (1.0.0 -> 2.0.0)
|
|
50
|
+
hotfix Critical fixes (1.0.0 -> 1.0.0.1)
|
|
51
|
+
|
|
52
|
+
If no VERSION_TYPE is given, interactive mode prompts for the bump.
|
|
53
|
+
|
|
54
|
+
EXAMPLES
|
|
55
|
+
ssh-release # Interactive mode
|
|
56
|
+
ssh-release patch # Patch release
|
|
57
|
+
ssh-release --dry-run minor # Preview a minor release
|
|
58
|
+
ssh-release --check-tools # Verify required tools
|
|
59
|
+
|
|
60
|
+
REQUIREMENTS
|
|
61
|
+
- git Version control
|
|
62
|
+
- gh GitHub CLI, authenticated (gh auth login)
|
|
63
|
+
- node Used for package.json / manifest.json edits (always present in a
|
|
64
|
+
Node project)
|
|
65
|
+
|
|
66
|
+
FILES OPERATED ON
|
|
67
|
+
package.json Version source of truth
|
|
68
|
+
CHANGELOG.md Release notes, NEXT_VERSION section
|
|
69
|
+
public/manifest.json Version, if present
|
|
70
|
+
public/sw.js APP_VERSION reset to [NEXT_VERSION], if present
|
|
71
|
+
* Any file containing the [NEXT_VERSION] placeholder
|
|
72
|
+
EOF
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
# Parse arguments.
|
|
76
|
+
DRY_RUN=false
|
|
77
|
+
CHECK_TOOLS=false
|
|
78
|
+
VERSION_TYPE=""
|
|
79
|
+
|
|
80
|
+
while [[ $# -gt 0 ]]; do
|
|
81
|
+
case $1 in
|
|
82
|
+
--help|-h)
|
|
83
|
+
show_help
|
|
84
|
+
exit 0
|
|
85
|
+
;;
|
|
86
|
+
--version|-v)
|
|
87
|
+
echo "ssh-release (secret-santa-hat-build-tools)"
|
|
88
|
+
exit 0
|
|
89
|
+
;;
|
|
90
|
+
--check-tools)
|
|
91
|
+
CHECK_TOOLS=true
|
|
92
|
+
shift
|
|
93
|
+
;;
|
|
94
|
+
--dry-run)
|
|
95
|
+
DRY_RUN=true
|
|
96
|
+
shift
|
|
97
|
+
;;
|
|
98
|
+
--quiet)
|
|
99
|
+
# Accepted for gcrq parity; the flow is quiet by default.
|
|
100
|
+
shift
|
|
101
|
+
;;
|
|
102
|
+
patch|minor|major|hotfix)
|
|
103
|
+
if [ -n "$VERSION_TYPE" ]; then
|
|
104
|
+
echo "โ Error: multiple version types specified."
|
|
105
|
+
exit 1
|
|
106
|
+
fi
|
|
107
|
+
VERSION_TYPE="$1"
|
|
108
|
+
shift
|
|
109
|
+
;;
|
|
110
|
+
-*)
|
|
111
|
+
echo "โ Error: unknown option '$1'. See 'ssh-release --help'."
|
|
112
|
+
exit 1
|
|
113
|
+
;;
|
|
114
|
+
*)
|
|
115
|
+
echo "โ Error: unexpected argument '$1'. See 'ssh-release --help'."
|
|
116
|
+
exit 1
|
|
117
|
+
;;
|
|
118
|
+
esac
|
|
119
|
+
done
|
|
120
|
+
|
|
121
|
+
# Source configuration if present.
|
|
122
|
+
if [ -f "$SCRIPT_DIR/config/release.conf" ]; then
|
|
123
|
+
# shellcheck disable=SC1091
|
|
124
|
+
source "$SCRIPT_DIR/config/release.conf"
|
|
125
|
+
fi
|
|
126
|
+
|
|
127
|
+
# Source helper libraries.
|
|
128
|
+
# shellcheck disable=SC1091
|
|
129
|
+
source "$SCRIPT_DIR/lib/platform-utils.sh"
|
|
130
|
+
# shellcheck disable=SC1091
|
|
131
|
+
source "$SCRIPT_DIR/lib/tool-checker.sh"
|
|
132
|
+
# shellcheck disable=SC1091
|
|
133
|
+
source "$SCRIPT_DIR/lib/general-functions.sh"
|
|
134
|
+
# shellcheck disable=SC1091
|
|
135
|
+
source "$SCRIPT_DIR/lib/git-functions.sh"
|
|
136
|
+
# shellcheck disable=SC1091
|
|
137
|
+
source "$SCRIPT_DIR/lib/release-functions.sh"
|
|
138
|
+
|
|
139
|
+
# Operate in the user's project directory.
|
|
140
|
+
cd "$USER_PROJECT_DIR"
|
|
141
|
+
|
|
142
|
+
if [ "$CHECK_TOOLS" = true ]; then
|
|
143
|
+
echo "๐ง Checking required tools..."
|
|
144
|
+
echo ""
|
|
145
|
+
|
|
146
|
+
if check_all_tools; then
|
|
147
|
+
echo ""
|
|
148
|
+
echo "โ
All required tools are available. Ready to run ssh-release."
|
|
149
|
+
exit 0
|
|
150
|
+
else
|
|
151
|
+
echo ""
|
|
152
|
+
echo "โ Some required tools are missing or not configured."
|
|
153
|
+
echo " โข git: https://git-scm.com/downloads"
|
|
154
|
+
echo " โข gh: https://cli.github.com/ (then run: gh auth login)"
|
|
155
|
+
exit 1
|
|
156
|
+
fi
|
|
157
|
+
fi
|
|
158
|
+
|
|
159
|
+
# Normal release workflow: verify tools first.
|
|
160
|
+
if ! quick_tool_check; then
|
|
161
|
+
echo "๐ง Checking required tools..."
|
|
162
|
+
echo ""
|
|
163
|
+
check_all_tools || true
|
|
164
|
+
echo ""
|
|
165
|
+
echo "โ Missing required tools. Install them before running ssh-release."
|
|
166
|
+
echo " Run 'ssh-release --check-tools' for details."
|
|
167
|
+
exit 1
|
|
168
|
+
fi
|
|
169
|
+
|
|
170
|
+
if [ -n "$VERSION_TYPE" ]; then
|
|
171
|
+
ssh_create_release "$VERSION_TYPE"
|
|
172
|
+
else
|
|
173
|
+
ssh_create_release
|
|
174
|
+
fi
|
package/bin/setup.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* Entry point for `npx @dream-encode/secret-santa-hat-build-tools setup`.
|
|
5
|
+
* Delegates to the interactive project setup.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const path = require( 'path' )
|
|
9
|
+
|
|
10
|
+
const args = process.argv.slice( 2 )
|
|
11
|
+
|
|
12
|
+
if ( args[ 0 ] === 'setup' ) {
|
|
13
|
+
process.argv = [ process.argv[ 0 ], process.argv[ 1 ], ...args.slice( 1 ) ]
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
require( path.join( __dirname, '..', 'scripts', 'setup-project.js' ) )
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* Node wrapper for ssh-release.
|
|
5
|
+
*
|
|
6
|
+
* Spawns the bundled bash release script so the tool works identically whether
|
|
7
|
+
* it is invoked through `yarn release`, `npm run release`, or `npx ssh-release`.
|
|
8
|
+
* Forcing UTF-8 locale here fixes the emoji display issues yarn causes on Windows.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const { spawn } = require( 'child_process' )
|
|
12
|
+
const path = require( 'path' )
|
|
13
|
+
|
|
14
|
+
const scriptDir = __dirname
|
|
15
|
+
const releaseScript = path.join( scriptDir, 'release.sh' )
|
|
16
|
+
|
|
17
|
+
const isYarn = process.env.npm_config_user_agent && process.env.npm_config_user_agent.includes( 'yarn' )
|
|
18
|
+
const isWindows = process.platform === 'win32'
|
|
19
|
+
|
|
20
|
+
if ( isYarn && isWindows ) {
|
|
21
|
+
console.log( 'โ ๏ธ Note: running via yarn on Windows may garble emoji output. If it looks wrong, use: npm run release' )
|
|
22
|
+
console.log( '' )
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const child = spawn( 'bash', [ releaseScript, ...process.argv.slice( 2 ) ], {
|
|
26
|
+
stdio: 'inherit',
|
|
27
|
+
cwd: process.cwd(),
|
|
28
|
+
env: {
|
|
29
|
+
...process.env,
|
|
30
|
+
LANG: process.env.LANG || 'en_US.UTF-8',
|
|
31
|
+
LC_ALL: process.env.LC_ALL || 'en_US.UTF-8',
|
|
32
|
+
PYTHONIOENCODING: 'utf-8',
|
|
33
|
+
TERM: process.env.TERM || 'xterm-256color',
|
|
34
|
+
SSH_RELEASE_VIA_YARN: isYarn ? '1' : '0',
|
|
35
|
+
},
|
|
36
|
+
} )
|
|
37
|
+
|
|
38
|
+
child.on( 'error', ( err ) => {
|
|
39
|
+
console.error( 'โ Failed to launch the release script.' )
|
|
40
|
+
|
|
41
|
+
if ( err.code === 'ENOENT' ) {
|
|
42
|
+
console.error( ' `bash` was not found on your PATH. Install Git Bash (Windows) or bash (macOS/Linux).' )
|
|
43
|
+
} else {
|
|
44
|
+
console.error( ` ${ err.message }` )
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
process.exit( 1 )
|
|
48
|
+
} )
|
|
49
|
+
|
|
50
|
+
child.on( 'exit', ( code ) => {
|
|
51
|
+
process.exit( code === null ? 1 : code )
|
|
52
|
+
} )
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@dream-encode/secret-santa-hat-build-tools",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Release build tools for Secret Santa Hat JavaScript repositories. Provides the `ssh-release` command, a JS-tailored port of the gcrq (git_create_release_quiet) release flow.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "David Baumwald <david@dream-encode.com>",
|
|
7
|
+
"type": "commonjs",
|
|
8
|
+
"engines": {
|
|
9
|
+
"node": ">=18"
|
|
10
|
+
},
|
|
11
|
+
"bin": {
|
|
12
|
+
"ssh-release": "bin/ssh-release.js",
|
|
13
|
+
"secret-santa-hat-build-tools": "bin/setup.js"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"bin/",
|
|
17
|
+
"scripts/",
|
|
18
|
+
"README.md",
|
|
19
|
+
"LICENSE",
|
|
20
|
+
"CHANGELOG.md"
|
|
21
|
+
],
|
|
22
|
+
"scripts": {
|
|
23
|
+
"postinstall": "node scripts/postinstall.js"
|
|
24
|
+
},
|
|
25
|
+
"repository": {
|
|
26
|
+
"type": "git",
|
|
27
|
+
"url": "git+https://github.com/dream-encode/secret-santa-hat-build-tools.git"
|
|
28
|
+
},
|
|
29
|
+
"bugs": {
|
|
30
|
+
"url": "https://github.com/dream-encode/secret-santa-hat-build-tools/issues"
|
|
31
|
+
},
|
|
32
|
+
"homepage": "https://github.com/dream-encode/secret-santa-hat-build-tools#readme",
|
|
33
|
+
"keywords": [
|
|
34
|
+
"secret-santa-hat",
|
|
35
|
+
"release",
|
|
36
|
+
"build",
|
|
37
|
+
"changelog",
|
|
38
|
+
"versioning",
|
|
39
|
+
"git",
|
|
40
|
+
"github"
|
|
41
|
+
],
|
|
42
|
+
"publishConfig": {
|
|
43
|
+
"access": "public"
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* Postinstall for @dream-encode/secret-santa-hat-build-tools.
|
|
5
|
+
*
|
|
6
|
+
* After the package is installed into a project, notify that a "release"
|
|
7
|
+
* script can be wired in. It never edits package.json automatically here;
|
|
8
|
+
* wiring happens through the interactive `setup` command so installs stay
|
|
9
|
+
* side-effect free (and CI-safe).
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
const fs = require( 'fs' )
|
|
13
|
+
const path = require( 'path' )
|
|
14
|
+
const { analyzeCurrentSetup, findProjectRoot } = require( './setup-project' )
|
|
15
|
+
|
|
16
|
+
const PACKAGE_NAME = '@dream-encode/secret-santa-hat-build-tools'
|
|
17
|
+
|
|
18
|
+
const colors = {
|
|
19
|
+
green: '\x1b[32m',
|
|
20
|
+
yellow: '\x1b[33m',
|
|
21
|
+
blue: '\x1b[34m',
|
|
22
|
+
reset: '\x1b[0m',
|
|
23
|
+
bold: '\x1b[1m',
|
|
24
|
+
dim: '\x1b[2m',
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function log( message, color = 'reset' ) {
|
|
28
|
+
console.log( `${ colors[ color ] }${ message }${ colors.reset }` )
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function isInteractive() {
|
|
32
|
+
return process.stdout.isTTY && process.stdin.isTTY && ! process.env.CI
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function isSelfInstall() {
|
|
36
|
+
try {
|
|
37
|
+
const pkg = JSON.parse( fs.readFileSync( path.join( process.cwd(), 'package.json' ), 'utf8' ) )
|
|
38
|
+
|
|
39
|
+
return pkg.name === PACKAGE_NAME
|
|
40
|
+
} catch {
|
|
41
|
+
return false
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function shouldSkip() {
|
|
46
|
+
return !! ( process.env.CI || process.env.NO_SETUP || isSelfInstall() )
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function main() {
|
|
50
|
+
if ( shouldSkip() ) {
|
|
51
|
+
return
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
try {
|
|
55
|
+
const projectRoot = findProjectRoot()
|
|
56
|
+
|
|
57
|
+
if ( ! projectRoot ) {
|
|
58
|
+
return
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const pkg = JSON.parse( fs.readFileSync( path.join( projectRoot, 'package.json' ), 'utf8' ) )
|
|
62
|
+
const analysis = analyzeCurrentSetup( pkg )
|
|
63
|
+
|
|
64
|
+
if ( ! analysis.needsSetup ) {
|
|
65
|
+
return
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
log( '\n' + '='.repeat( 60 ), 'blue' )
|
|
69
|
+
log( '๐
secret-santa-hat-build-tools installed', 'bold' )
|
|
70
|
+
log( '='.repeat( 60 ), 'blue' )
|
|
71
|
+
|
|
72
|
+
if ( analysis.hasReleaseScript ) {
|
|
73
|
+
log( `\nโ ๏ธ Existing release script detected: "${ analysis.currentReleaseScript }"`, 'yellow' )
|
|
74
|
+
log( ' (setup will back it up as "release-backup")', 'dim' )
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
log( '\n๐ก Wire in the release script with:', 'bold' )
|
|
78
|
+
log( ` npx ${ PACKAGE_NAME } setup # interactive`, 'blue' )
|
|
79
|
+
log( ` npx ${ PACKAGE_NAME } setup --force # no prompts`, 'blue' )
|
|
80
|
+
log( '\n Then: yarn release (runs your prerelease script, then the release flow)', 'dim' )
|
|
81
|
+
log( '='.repeat( 60 ) + '\n', 'blue' )
|
|
82
|
+
|
|
83
|
+
if ( ! isInteractive() ) {
|
|
84
|
+
log( `Run: npx ${ PACKAGE_NAME } setup`, 'yellow' )
|
|
85
|
+
}
|
|
86
|
+
} catch ( error ) {
|
|
87
|
+
if ( process.env.DEBUG ) {
|
|
88
|
+
console.error( 'secret-santa-hat-build-tools postinstall error:', error )
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
main()
|