Skip to content

Commit ffeeae7

Browse files
fix(init-wiki): robust, owner-parametrised, token-aware wiki seeding (#90)
## What Hardens `init-wiki.sh` — the estate work-around for GitHub having **no API to create/seed a wiki** (the `.wiki.git` repo is created lazily on first UI save; see the open feature request being filed at community discussions). ## Why The previous version had a `WIKI_DIR` quoting bug, was hardcoded to `hyperpolymath/`, and — critically — never enabled the wiki, so the lazy-init case silently printed "Failed to push" with no guidance. ## Changes - **Fix** `WIKI_DIR=""$HYPATIA_TMPDIR/...` quoting bug → `mktemp -d` + `trap` cleanup. - **Owner-parametrised**: accepts `<owner>/<repo>` (or `$WIKI_OWNER`), so it works for `metadatastician/*` etc., not just `hyperpolymath/*`. - **Enable wiki first** via `gh api -X PATCH repos/<slug> -F has_wiki=true` so the push target exists. - **Token-aware remote**: `GH_TOKEN`/`GITHUB_TOKEN` → HTTPS `x-access-token` (CI / GitHub App installation token); else SSH. - **Idempotent**: `write_page` only creates missing pages — never clobbers human-edited wiki content on re-run. - **Actionable failure**: on push error, prints the real message and the lazy-init fallback (create first page once via UI / browser-automation agent, then re-run). - `set -euo pipefail`. ## Verification - `bash -n init-wiki.sh` → syntax OK - `shellcheck -S warning init-wiki.sh` → no warnings - Smoke test: owner/repo parsing (`metadatastician/paint-type` + bare-repo default) and no-clobber idempotency confirmed. Part of the "route around GitHub API limits for AI tooling" work (Arm B2). Draft pending live run against a repo with no existing wiki. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 7dcd68f commit ffeeae7

1 file changed

Lines changed: 109 additions & 50 deletions

File tree

init-wiki.sh

Lines changed: 109 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,87 @@
11
#!/bin/bash
22
# SPDX-License-Identifier: MPL-2.0
3-
# Initialize wiki with standard structure for a repo
3+
# Initialize (seed) a repository wiki with a standard structure.
4+
#
5+
# GitHub has no REST/GraphQL API to create a wiki or its first page: the backing
6+
# `<repo>.wiki.git` repo is created lazily, only once a page is saved. This script
7+
# is the estate work-around — it enables the wiki, then seeds it over git.
8+
#
9+
# Usage:
10+
# init-wiki.sh <repo> # owner defaults to $WIKI_OWNER or "hyperpolymath"
11+
# init-wiki.sh <owner>/<repo> # explicit owner (e.g. metadatastician/paint-type)
12+
#
13+
# Auth:
14+
# - If GH_TOKEN or GITHUB_TOKEN is set (CI / GitHub App installation token), the
15+
# wiki remote uses HTTPS token auth. Otherwise it falls back to SSH.
16+
#
17+
# Idempotent: existing wiki pages are never overwritten — only missing pages are added.
18+
19+
set -euo pipefail
20+
21+
ARG="${1:-}"
22+
if [[ -z "$ARG" ]]; then
23+
echo "Usage: $0 <repo>|<owner>/<repo>" >&2
24+
exit 1
25+
fi
426

5-
REPO="${1:-}"
27+
# Parse owner/repo (owner optional).
28+
if [[ "$ARG" == */* ]]; then
29+
OWNER="${ARG%%/*}"
30+
REPO="${ARG##*/}"
31+
else
32+
OWNER="${WIKI_OWNER:-hyperpolymath}"
33+
REPO="$ARG"
34+
fi
35+
SLUG="$OWNER/$REPO"
636

7-
if [[ -z "$REPO" ]]; then
8-
echo "Usage: $0 <repo-name>"
9-
exit 1
37+
# Token-aware wiki remote (App/CI token → HTTPS; else SSH).
38+
TOKEN="${GH_TOKEN:-${GITHUB_TOKEN:-}}"
39+
if [[ -n "$TOKEN" ]]; then
40+
WIKI_REMOTE="https://x-access-token:${TOKEN}@github.com/${SLUG}.wiki.git"
41+
else
42+
WIKI_REMOTE="git@github.com:${SLUG}.wiki.git"
1043
fi
1144

12-
WIKI_DIR=""$HYPATIA_TMPDIR/wiki-init-"$$"
13-
mkdir -p "$WIKI_DIR"
14-
cd "$WIKI_DIR" || exit 1
45+
WIKI_DIR="$(mktemp -d "${TMPDIR:-/tmp}/wiki-init-XXXXXX")"
46+
cleanup() { rm -rf "$WIKI_DIR"; }
47+
trap cleanup EXIT
48+
49+
echo "Initializing wiki for ${SLUG}..."
50+
51+
# Step 1 — ensure the wiki feature is enabled (no-op if already on). Without this,
52+
# the .wiki.git remote may not exist server-side and the push below 404s.
53+
if ! gh api -X PATCH "repos/${SLUG}" -F has_wiki=true >/dev/null 2>&1; then
54+
echo "warning: could not confirm has_wiki=true via API (insufficient scope?); continuing" >&2
55+
fi
1556

16-
echo "Initializing wiki for hyperpolymath/$REPO..."
57+
cd "$WIKI_DIR"
1758

18-
# Clone wiki repo (creates if doesn't exist when you push)
19-
if ! git clone "git@github.com:hyperpolymath/$REPO.wiki.git" wiki 2>/dev/null; then
20-
# Wiki doesn't exist yet, create it
21-
mkdir wiki
59+
# Step 2 — clone the wiki repo; if it has never been initialized, start it locally.
60+
if git clone "$WIKI_REMOTE" wiki 2>/dev/null; then
2261
cd wiki
23-
git init
24-
git remote add origin "git@github.com:hyperpolymath/$REPO.wiki.git"
2562
else
26-
cd wiki
63+
echo "Wiki repo not yet initialized server-side; creating first commit locally."
64+
mkdir wiki && cd wiki
65+
git init -q
66+
git remote add origin "$WIKI_REMOTE"
2767
fi
2868

29-
# Get repo description for context
30-
DESCRIPTION=$(gh repo view "hyperpolymath/$REPO" --json description --jq '.description // "No description available"' 2>/dev/null)
69+
DESCRIPTION=$(gh repo view "$SLUG" --json description --jq '.description // "No description available"' 2>/dev/null || echo "No description available")
70+
71+
# write_page <filename> — reads heredoc from stdin; writes only if the page is
72+
# absent, so re-runs never clobber human-edited wiki pages.
73+
write_page() {
74+
local file="$1"
75+
if [[ -e "$file" ]]; then
76+
echo " skip (exists): $file"
77+
cat >/dev/null # drain heredoc
78+
return
79+
fi
80+
cat > "$file"
81+
echo " add: $file"
82+
}
3183

32-
# Create Home.md
33-
cat > Home.md << EOF
84+
write_page Home.md << EOF
3485
# $REPO
3586
3687
$DESCRIPTION
@@ -50,8 +101,7 @@ See the [Getting Started](Getting-Started) guide to begin using this project.
50101
See the [Contributing](Contributing) guide for developer information.
51102
EOF
52103

53-
# Create _Sidebar.md for navigation
54-
cat > _Sidebar.md << EOF
104+
write_page _Sidebar.md << EOF
55105
### $REPO Wiki
56106
57107
**For Users**
@@ -65,14 +115,12 @@ cat > _Sidebar.md << EOF
65115
- [API Reference](API-Reference)
66116
EOF
67117

68-
# Create _Footer.md
69-
cat > _Footer.md << EOF
118+
write_page _Footer.md << EOF
70119
---
71-
*[View on GitHub](https://github.com/hyperpolymath/$REPO) | [Report Issue](https://github.com/hyperpolymath/$REPO/issues/new) | [Discussions](https://github.com/hyperpolymath/$REPO/discussions)*
120+
*[View on GitHub](https://github.com/$SLUG) | [Report Issue](https://github.com/$SLUG/issues/new) | [Discussions](https://github.com/$SLUG/discussions)*
72121
EOF
73122

74-
# Create Getting-Started.md
75-
cat > Getting-Started.md << EOF
123+
write_page Getting-Started.md << EOF
76124
# Getting Started
77125
78126
## Prerequisites
@@ -95,8 +143,7 @@ See the main repository README for installation instructions.
95143
- Read the [Architecture](Architecture) for understanding the codebase
96144
EOF
97145

98-
# Create FAQ.md
99-
cat > FAQ.md << EOF
146+
write_page FAQ.md << EOF
100147
# Frequently Asked Questions
101148
102149
## General
@@ -107,16 +154,15 @@ $DESCRIPTION
107154
108155
### Where can I get help?
109156
110-
- [GitHub Discussions](https://github.com/hyperpolymath/$REPO/discussions) - Community help
111-
- [Issues](https://github.com/hyperpolymath/$REPO/issues) - Bug reports
157+
- [GitHub Discussions](https://github.com/$SLUG/discussions) - Community help
158+
- [Issues](https://github.com/$SLUG/issues) - Bug reports
112159
113160
## Troubleshooting
114161
115162
*Add common issues and solutions here.*
116163
EOF
117164

118-
# Create Architecture.md
119-
cat > Architecture.md << EOF
165+
write_page Architecture.md << EOF
120166
# Architecture
121167
122168
## Overview
@@ -136,8 +182,7 @@ See the repository for the current directory structure.
136182
See the project's META.scm or ADR files for architectural decisions.
137183
EOF
138184

139-
# Create Contributing.md
140-
cat > Contributing.md << EOF
185+
write_page Contributing.md << EOF
141186
# Contributing
142187
143188
Thank you for your interest in contributing to $REPO!
@@ -164,11 +209,10 @@ Thank you for your interest in contributing to $REPO!
164209
165210
## Getting Help
166211
167-
Use [GitHub Discussions](https://github.com/hyperpolymath/$REPO/discussions) for questions.
212+
Use [GitHub Discussions](https://github.com/$SLUG/discussions) for questions.
168213
EOF
169214

170-
# Create API-Reference.md
171-
cat > API-Reference.md << EOF
215+
write_page API-Reference.md << EOF
172216
# API Reference
173217
174218
*This page documents the public API of $REPO.*
@@ -186,19 +230,34 @@ See the project source code and inline documentation for detailed API informatio
186230
*Document configuration options here.*
187231
EOF
188232

189-
# Commit and push
233+
# Step 3 — commit and push. Wikis default to the `master` branch; detect the current one.
190234
git add -A
191235
if git diff --cached --quiet 2>/dev/null; then
192-
echo "No changes to commit"
193-
else
194-
git commit -m "Initialize wiki with standard structure"
195-
if git push -u origin master 2>/dev/null || git push -u origin main 2>/dev/null; then
196-
echo "Wiki initialized successfully for $REPO"
197-
else
198-
echo "Failed to push wiki for $REPO"
199-
fi
236+
echo "No changes to commit (wiki already seeded)."
237+
exit 0
238+
fi
239+
git commit -q -m "Initialize wiki with standard structure"
240+
241+
BRANCH="$(git symbolic-ref --short HEAD 2>/dev/null || echo master)"
242+
if PUSH_ERR="$(git push -u origin "$BRANCH" 2>&1)"; then
243+
echo "Wiki initialized successfully for ${SLUG}."
244+
exit 0
200245
fi
201246

202-
# Cleanup
203-
cd /
204-
rm -rf "$WIKI_DIR"
247+
# Push failed — surface the real reason and the lazy-init fallback.
248+
echo "Failed to push wiki for ${SLUG}." >&2
249+
echo "$PUSH_ERR" >&2
250+
if echo "$PUSH_ERR" | grep -qiE 'not found|does not exist'; then
251+
cat >&2 <<MSG
252+
253+
The wiki repo has never been initialized server-side, and pushing does not create
254+
it on this account/repo. GitHub only creates <repo>.wiki.git after the FIRST page
255+
is saved through the web UI — there is no API for it (see the open feature request).
256+
257+
Fallback: create the first page once, then re-run this script:
258+
1. Open https://github.com/${SLUG}/wiki and click "Create the first page" -> Save.
259+
2. Re-run: $0 ${SLUG}
260+
Or drive that single UI step with the estate browser-automation agent.
261+
MSG
262+
fi
263+
exit 1

0 commit comments

Comments
 (0)