@wipcomputer/deploy-public 1.9.7 → 1.9.8
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/deploy-public.sh +125 -27
- package/package.json +1 -1
package/deploy-public.sh
CHANGED
|
@@ -32,6 +32,23 @@ if [[ ! -d "$PRIVATE_REPO/.git" ]]; then
|
|
|
32
32
|
exit 1
|
|
33
33
|
fi
|
|
34
34
|
|
|
35
|
+
# ── Safety: never deploy back to the source repo ──
|
|
36
|
+
# Extract the private repo's GitHub org/name from its remote URL
|
|
37
|
+
PRIVATE_REMOTE=$(cd "$PRIVATE_REPO" && git remote get-url origin 2>/dev/null | sed 's/.*github.com[:/]\(.*\)\.git/\1/' || echo "")
|
|
38
|
+
|
|
39
|
+
if [[ -n "$PRIVATE_REMOTE" && "$PRIVATE_REMOTE" == "$PUBLIC_REPO" ]]; then
|
|
40
|
+
echo "ERROR: PUBLIC_REPO ($PUBLIC_REPO) is the same as the private repo's origin ($PRIVATE_REMOTE)."
|
|
41
|
+
echo "This would deploy sanitized code (no ai/) back to the source repo and destroy files."
|
|
42
|
+
echo "Did you mean to target the public counterpart instead?"
|
|
43
|
+
exit 1
|
|
44
|
+
fi
|
|
45
|
+
|
|
46
|
+
if [[ "$PUBLIC_REPO" == *"-private"* ]]; then
|
|
47
|
+
echo "ERROR: PUBLIC_REPO ($PUBLIC_REPO) contains '-private'."
|
|
48
|
+
echo "deploy-public.sh should only target public repos. Private repos have ai/ folders that would be destroyed."
|
|
49
|
+
exit 1
|
|
50
|
+
fi
|
|
51
|
+
|
|
35
52
|
# Get the latest commit message from private repo
|
|
36
53
|
COMMIT_MSG=$(cd "$PRIVATE_REPO" && git log -1 --pretty=format:"%s")
|
|
37
54
|
COMMIT_HASH=$(cd "$PRIVATE_REPO" && git log -1 --pretty=format:"%h")
|
|
@@ -39,14 +56,35 @@ COMMIT_HASH=$(cd "$PRIVATE_REPO" && git log -1 --pretty=format:"%h")
|
|
|
39
56
|
TMPDIR=$(mktemp -d)
|
|
40
57
|
trap 'rm -rf "$TMPDIR"' EXIT
|
|
41
58
|
|
|
59
|
+
# ── Auto-create public repo if it doesn't exist ──
|
|
60
|
+
REPO_EXISTS=$(gh repo view "$PUBLIC_REPO" --json name -q '.name' 2>/dev/null || echo "")
|
|
61
|
+
if [[ -z "$REPO_EXISTS" ]]; then
|
|
62
|
+
echo "Public repo $PUBLIC_REPO does not exist. Creating..."
|
|
63
|
+
DESCRIPTION=$(cd "$PRIVATE_REPO" && node -p "require('./package.json').description" 2>/dev/null || echo "")
|
|
64
|
+
gh repo create "$PUBLIC_REPO" --public --description "${DESCRIPTION:-Synced from private repo}" 2>/dev/null
|
|
65
|
+
echo " + Created $PUBLIC_REPO"
|
|
66
|
+
EMPTY_REPO=true
|
|
67
|
+
else
|
|
68
|
+
EMPTY_REPO=false
|
|
69
|
+
# Verify the resolved repo is actually the one we asked for (catch GitHub redirects)
|
|
70
|
+
RESOLVED_NAME=$(gh repo view "$PUBLIC_REPO" --json nameWithOwner -q '.nameWithOwner' 2>/dev/null || echo "")
|
|
71
|
+
if [[ -n "$RESOLVED_NAME" && "$RESOLVED_NAME" != "$PUBLIC_REPO" ]]; then
|
|
72
|
+
echo "ERROR: GitHub redirected $PUBLIC_REPO to $RESOLVED_NAME."
|
|
73
|
+
echo "The public repo doesn't actually exist. A repo with a similar name is redirecting."
|
|
74
|
+
echo "Create the public repo first: gh repo create $PUBLIC_REPO --public"
|
|
75
|
+
exit 1
|
|
76
|
+
fi
|
|
77
|
+
fi
|
|
78
|
+
|
|
42
79
|
echo "Cloning public repo $PUBLIC_REPO..."
|
|
43
80
|
gh repo clone "$PUBLIC_REPO" "$TMPDIR/public" -- --depth 1 2>/dev/null || {
|
|
44
|
-
echo "Public repo is empty
|
|
81
|
+
echo "Public repo is empty. Initializing..."
|
|
45
82
|
mkdir -p "$TMPDIR/public"
|
|
46
83
|
cd "$TMPDIR/public"
|
|
47
84
|
git init
|
|
48
85
|
git remote add origin "git@github.com:${PUBLIC_REPO}.git"
|
|
49
86
|
cd - > /dev/null
|
|
87
|
+
EMPTY_REPO=true
|
|
50
88
|
}
|
|
51
89
|
|
|
52
90
|
echo "Syncing files from private repo (excluding ai/, .git/)..."
|
|
@@ -84,37 +122,48 @@ if [[ -z "${HARNESS_ID:-}" ]]; then
|
|
|
84
122
|
fi
|
|
85
123
|
BRANCH="$HARNESS_ID/deploy-$(date +%Y%m%d-%H%M%S)"
|
|
86
124
|
|
|
87
|
-
git checkout -b "$BRANCH"
|
|
88
125
|
git add -A
|
|
89
126
|
git commit -m "$COMMIT_MSG (from $COMMIT_HASH)"
|
|
90
127
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
echo "Merging PR..."
|
|
101
|
-
PR_NUMBER=$(echo "$PR_URL" | grep -o '[0-9]*$')
|
|
102
|
-
gh pr merge "$PR_NUMBER" -R "$PUBLIC_REPO" --merge --delete-branch
|
|
103
|
-
|
|
104
|
-
# Clean up any other non-main branches on public repo
|
|
105
|
-
echo "Checking for stale branches on public repo..."
|
|
106
|
-
STALE_BRANCHES=$(gh api "repos/$PUBLIC_REPO/branches" --paginate --jq '.[].name' 2>/dev/null | grep -v '^main$' || true)
|
|
107
|
-
if [[ -n "$STALE_BRANCHES" ]]; then
|
|
108
|
-
STALE_COUNT=$(echo "$STALE_BRANCHES" | wc -l | tr -d ' ')
|
|
109
|
-
echo " Found $STALE_COUNT stale branch(es). Deleting..."
|
|
110
|
-
echo "$STALE_BRANCHES" | while read -r stale; do
|
|
111
|
-
gh api -X DELETE "repos/$PUBLIC_REPO/git/refs/heads/$stale" 2>/dev/null && echo " ✓ Deleted $stale" || echo " ! Could not delete $stale"
|
|
112
|
-
done
|
|
128
|
+
if [[ "$EMPTY_REPO" == "true" ]]; then
|
|
129
|
+
# Empty repo: push directly to main (no base branch to PR against)
|
|
130
|
+
echo "Pushing initial commit to main on $PUBLIC_REPO..."
|
|
131
|
+
git branch -M main
|
|
132
|
+
git push -u origin main
|
|
133
|
+
gh repo edit "$PUBLIC_REPO" --default-branch main 2>/dev/null || true
|
|
134
|
+
PR_URL="(initial push, no PR)"
|
|
135
|
+
echo " + Initial commit pushed to main"
|
|
113
136
|
else
|
|
114
|
-
|
|
115
|
-
fi
|
|
137
|
+
git checkout -b "$BRANCH"
|
|
116
138
|
|
|
117
|
-
echo "
|
|
139
|
+
echo "Pushing branch $BRANCH to $PUBLIC_REPO..."
|
|
140
|
+
git push -u origin "$BRANCH"
|
|
141
|
+
|
|
142
|
+
echo "Creating PR..."
|
|
143
|
+
PR_URL=$(gh pr create -R "$PUBLIC_REPO" \
|
|
144
|
+
--head "$BRANCH" \
|
|
145
|
+
--title "$COMMIT_MSG" \
|
|
146
|
+
--body "Synced from private repo (commit $COMMIT_HASH).")
|
|
147
|
+
|
|
148
|
+
echo "Merging PR..."
|
|
149
|
+
PR_NUMBER=$(echo "$PR_URL" | grep -o '[0-9]*$')
|
|
150
|
+
gh pr merge "$PR_NUMBER" -R "$PUBLIC_REPO" --merge --delete-branch
|
|
151
|
+
|
|
152
|
+
# Clean up any other non-main branches on public repo
|
|
153
|
+
echo "Checking for stale branches on public repo..."
|
|
154
|
+
STALE_BRANCHES=$(gh api "repos/$PUBLIC_REPO/branches" --paginate --jq '.[].name' 2>/dev/null | grep -v '^main$' || true)
|
|
155
|
+
if [[ -n "$STALE_BRANCHES" ]]; then
|
|
156
|
+
STALE_COUNT=$(echo "$STALE_BRANCHES" | wc -l | tr -d ' ')
|
|
157
|
+
echo " Found $STALE_COUNT stale branch(es). Deleting..."
|
|
158
|
+
echo "$STALE_BRANCHES" | while read -r stale; do
|
|
159
|
+
gh api -X DELETE "repos/$PUBLIC_REPO/git/refs/heads/$stale" 2>/dev/null && echo " ✓ Deleted $stale" || echo " ! Could not delete $stale"
|
|
160
|
+
done
|
|
161
|
+
else
|
|
162
|
+
echo " ✓ No stale branches"
|
|
163
|
+
fi
|
|
164
|
+
|
|
165
|
+
echo "Code synced via PR: $PR_URL"
|
|
166
|
+
fi
|
|
118
167
|
|
|
119
168
|
# ── Sync release to public repo ──
|
|
120
169
|
# If the private repo has a version tag, create a matching release on the public repo.
|
|
@@ -160,6 +209,55 @@ if [[ -n "$VERSION" ]]; then
|
|
|
160
209
|
fi
|
|
161
210
|
fi
|
|
162
211
|
|
|
212
|
+
# ── npm publish from public repo (#100) ──
|
|
213
|
+
# After syncing code and release, publish to npm from the public clone.
|
|
214
|
+
# Only if package.json exists and private !== true.
|
|
215
|
+
|
|
216
|
+
if [[ -n "${VERSION:-}" ]]; then
|
|
217
|
+
# Re-clone public for npm publish (the previous tmpdir might be gone)
|
|
218
|
+
NPM_TMPDIR=$(mktemp -d)
|
|
219
|
+
gh repo clone "$PUBLIC_REPO" "$NPM_TMPDIR/public" -- --depth 1 2>/dev/null
|
|
220
|
+
|
|
221
|
+
if [[ -f "$NPM_TMPDIR/public/package.json" ]]; then
|
|
222
|
+
IS_PRIVATE=$(cd "$NPM_TMPDIR/public" && node -p "require('./package.json').private || false" 2>/dev/null)
|
|
223
|
+
echo "Publishing to npm from public repo..."
|
|
224
|
+
NPM_TOKEN=$(OP_SERVICE_ACCOUNT_TOKEN=$(cat ~/.openclaw/secrets/op-sa-token) \
|
|
225
|
+
op item get "npm Token" --vault "Agent Secrets" --fields label=password --reveal 2>/dev/null || echo "")
|
|
226
|
+
if [[ -n "$NPM_TOKEN" ]]; then
|
|
227
|
+
cd "$NPM_TMPDIR/public"
|
|
228
|
+
|
|
229
|
+
# Publish root package (if not private)
|
|
230
|
+
if [[ "$IS_PRIVATE" != "true" ]]; then
|
|
231
|
+
echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > .npmrc
|
|
232
|
+
npm publish --access public 2>/dev/null && echo " ✓ Published root package to npm" || echo " ✗ Root npm publish failed (non-fatal)"
|
|
233
|
+
rm -f .npmrc
|
|
234
|
+
else
|
|
235
|
+
echo " - Root package is private. Skipping root npm publish."
|
|
236
|
+
fi
|
|
237
|
+
|
|
238
|
+
# For toolbox repos: publish each sub-tool regardless of root private status
|
|
239
|
+
if [[ -d "tools" ]]; then
|
|
240
|
+
for TOOL_DIR in tools/*/; do
|
|
241
|
+
if [[ -f "${TOOL_DIR}package.json" ]]; then
|
|
242
|
+
TOOL_PRIVATE=$(node -p "require('./${TOOL_DIR}package.json').private || false" 2>/dev/null)
|
|
243
|
+
if [[ "$TOOL_PRIVATE" != "true" ]]; then
|
|
244
|
+
TOOL_NAME=$(node -p "require('./${TOOL_DIR}package.json').name" 2>/dev/null)
|
|
245
|
+
echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > "${TOOL_DIR}.npmrc"
|
|
246
|
+
(cd "$TOOL_DIR" && npm publish --access public 2>/dev/null) && echo " ✓ Published $TOOL_NAME to npm" || echo " ✗ npm publish failed for $TOOL_NAME (non-fatal)"
|
|
247
|
+
rm -f "${TOOL_DIR}.npmrc"
|
|
248
|
+
fi
|
|
249
|
+
fi
|
|
250
|
+
done
|
|
251
|
+
fi
|
|
252
|
+
|
|
253
|
+
cd - > /dev/null
|
|
254
|
+
else
|
|
255
|
+
echo " ! npm Token not found in 1Password. Skipping npm publish."
|
|
256
|
+
fi
|
|
257
|
+
fi
|
|
258
|
+
rm -rf "$NPM_TMPDIR"
|
|
259
|
+
fi
|
|
260
|
+
|
|
163
261
|
echo "Done. Public repo updated."
|
|
164
262
|
echo " PR: $PR_URL"
|
|
165
263
|
echo " Commit: $COMMIT_MSG (from $COMMIT_HASH)"
|
package/package.json
CHANGED