Skip to content

Commit 5056e13

Browse files
AbanoubGhadbanclaude
authored andcommitted
Add script to publish built JS packages to dist repo (#2767)
## Summary - Adds `scripts/publish-to-builds-repo.sh` that builds all JS packages and pushes the compiled output to [shakacode/react-on-rails-builds](https://github.com/shakacode/react-on-rails-builds) - The builds repo contains pre-built `package.json` + `lib/` for each package, ready for consumption as pnpm git dependencies — no TypeScript compilation needed during install - The script defaults to pushing to a branch matching the current react_on_rails branch name (overridable with `--branch`) ### What the script does 1. Runs `pnpm build` for all packages 2. Copies `package.json` + `lib/` to the builds repo 3. Replaces `workspace:*` references with the actual version 4. Strips `devDependencies` and build-related scripts 5. Commits, pushes, and tags (e.g., `v16.4.0`) ### Usage ```bash ./scripts/publish-to-builds-repo.sh # build + push + tag ./scripts/publish-to-builds-repo.sh --dry-run # preview without pushing ./scripts/publish-to-builds-repo.sh --tag v1.2.3 # custom tag ./scripts/publish-to-builds-repo.sh --branch main # override branch ``` ### Consumer usage (pnpm) ```json { "react-on-rails": "github:shakacode/react-on-rails-builds#v16.4.0&path:react-on-rails", "react-on-rails-pro": "github:shakacode/react-on-rails-builds#v16.4.0&path:react-on-rails-pro", "react-on-rails-pro-node-renderer": "github:shakacode/react-on-rails-builds#v16.4.0&path:react-on-rails-pro-node-renderer" } ``` ## Test plan - [x] Dry run completes successfully - [x] Real run pushes to `shakacode/react-on-rails-builds` with correct structure - [x] Verified `workspace:*` replaced with actual version in dist `package.json` - [x] Verified `devDependencies` and build scripts stripped - [x] Verified consumer `pnpm install` resolves correct packages in ~30s 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 6b415cb commit 5056e13

1 file changed

Lines changed: 254 additions & 0 deletions

File tree

scripts/publish-to-builds-repo.sh

Lines changed: 254 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,254 @@
1+
#!/usr/bin/env bash
2+
#
3+
# Build all JS packages and push the built output to the react-on-rails-builds repo.
4+
#
5+
# Usage:
6+
# ./scripts/publish-to-builds-repo.sh [--dist-repo <git-url>] [--branch <branch>] [--tag <tag>] [--dry-run]
7+
#
8+
# Options:
9+
# --dist-repo Git URL of the builds repo (default: git@github.com:shakacode/react-on-rails-builds.git)
10+
# --branch Branch to push to in the builds repo (default: current git branch name)
11+
# --tag Tag to create (default: v<version> from react-on-rails package.json)
12+
# --dry-run Build and prepare but don't push
13+
#
14+
# The builds repo will have this structure:
15+
# react-on-rails/
16+
# package.json
17+
# lib/
18+
# react-on-rails-pro/
19+
# package.json
20+
# lib/
21+
# react-on-rails-pro-node-renderer/
22+
# package.json
23+
# lib/
24+
25+
set -euo pipefail
26+
27+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
28+
MONOREPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
29+
30+
DIST_REPO="git@github.com:shakacode/react-on-rails-builds.git"
31+
DIST_BRANCH=""
32+
DIST_TAG=""
33+
DRY_RUN=false
34+
35+
while [[ $# -gt 0 ]]; do
36+
case "$1" in
37+
--dist-repo) DIST_REPO="$2"; shift 2 ;;
38+
--branch) DIST_BRANCH="$2"; shift 2 ;;
39+
--tag) DIST_TAG="$2"; shift 2 ;;
40+
--dry-run) DRY_RUN=true; shift ;;
41+
*) echo "Unknown option: $1" >&2; exit 1 ;;
42+
esac
43+
done
44+
45+
PACKAGES=(
46+
"react-on-rails"
47+
"react-on-rails-pro"
48+
"react-on-rails-pro-node-renderer"
49+
)
50+
51+
# Read version from react-on-rails package.json
52+
VERSION=$(node -e "console.log(require('./packages/react-on-rails/package.json').version)" 2>/dev/null)
53+
if [[ -z "$VERSION" ]]; then
54+
echo "Error: Could not read version from packages/react-on-rails/package.json" >&2
55+
exit 1
56+
fi
57+
58+
# Default branch to the current git branch name
59+
if [[ -z "$DIST_BRANCH" ]]; then
60+
DIST_BRANCH=$(cd "$MONOREPO_ROOT" && git rev-parse --abbrev-ref HEAD)
61+
fi
62+
63+
if [[ -z "$DIST_TAG" ]]; then
64+
DIST_TAG="v${VERSION}"
65+
fi
66+
67+
echo "==> Monorepo root: $MONOREPO_ROOT"
68+
echo "==> Version: $VERSION"
69+
echo "==> Dist repo: $DIST_REPO"
70+
echo "==> Dist branch: $DIST_BRANCH"
71+
echo "==> Dist tag: $DIST_TAG"
72+
echo "==> Dry run: $DRY_RUN"
73+
echo ""
74+
75+
# -------------------------------------------------------------------
76+
# 1. Build all packages
77+
# -------------------------------------------------------------------
78+
echo "==> Building all packages..."
79+
cd "$MONOREPO_ROOT"
80+
pnpm build
81+
echo "==> Build complete."
82+
echo ""
83+
84+
# -------------------------------------------------------------------
85+
# 2. Clone or update the builds repo
86+
# -------------------------------------------------------------------
87+
DIST_DIR=$(mktemp -d)
88+
trap 'rm -rf "$DIST_DIR"' EXIT
89+
90+
echo "==> Cloning builds repo into $DIST_DIR..."
91+
if git ls-remote "$DIST_REPO" "refs/heads/$DIST_BRANCH" &>/dev/null; then
92+
git clone --branch "$DIST_BRANCH" --depth 1 "$DIST_REPO" "$DIST_DIR/repo" 2>/dev/null || \
93+
git clone "$DIST_REPO" "$DIST_DIR/repo" 2>/dev/null || {
94+
# Fresh repo with no commits yet
95+
git init "$DIST_DIR/repo"
96+
cd "$DIST_DIR/repo"
97+
git remote add origin "$DIST_REPO"
98+
}
99+
else
100+
# Branch doesn't exist or repo is empty
101+
git clone "$DIST_REPO" "$DIST_DIR/repo" 2>/dev/null || {
102+
git init "$DIST_DIR/repo"
103+
cd "$DIST_DIR/repo"
104+
git remote add origin "$DIST_REPO"
105+
}
106+
fi
107+
108+
cd "$DIST_DIR/repo"
109+
110+
# Ensure we're on the right branch
111+
git checkout "$DIST_BRANCH" 2>/dev/null || git checkout -b "$DIST_BRANCH"
112+
113+
echo ""
114+
115+
# -------------------------------------------------------------------
116+
# 3. Copy built packages
117+
# -------------------------------------------------------------------
118+
echo "==> Copying built packages..."
119+
120+
for pkg in "${PACKAGES[@]}"; do
121+
PKG_SRC="$MONOREPO_ROOT/packages/$pkg"
122+
PKG_DEST="$DIST_DIR/repo/$pkg"
123+
124+
echo " $pkg"
125+
126+
# Clean the destination
127+
rm -rf "$PKG_DEST"
128+
mkdir -p "$PKG_DEST"
129+
130+
# Copy package.json
131+
cp "$PKG_SRC/package.json" "$PKG_DEST/package.json"
132+
133+
# Copy lib/ directory
134+
if [[ -d "$PKG_SRC/lib" ]]; then
135+
cp -r "$PKG_SRC/lib" "$PKG_DEST/lib"
136+
else
137+
echo " WARNING: $PKG_SRC/lib does not exist! Was the build successful?" >&2
138+
fi
139+
140+
# Copy README if it exists
141+
if [[ -f "$PKG_SRC/README.md" ]]; then
142+
cp "$PKG_SRC/README.md" "$PKG_DEST/README.md"
143+
fi
144+
done
145+
146+
# -------------------------------------------------------------------
147+
# 4. Fix workspace:* references in package.json files
148+
# -------------------------------------------------------------------
149+
echo "==> Replacing workspace:* references with version $VERSION..."
150+
151+
for pkg in "${PACKAGES[@]}"; do
152+
PKG_JSON="$DIST_DIR/repo/$pkg/package.json"
153+
if grep -q '"workspace:\*"' "$PKG_JSON" 2>/dev/null; then
154+
sed -i "s/\"workspace:\*\"/\"$VERSION\"/g" "$PKG_JSON"
155+
echo " Fixed $pkg/package.json"
156+
fi
157+
done
158+
159+
# -------------------------------------------------------------------
160+
# 5. Remove prepare/prepublishOnly scripts (not needed in dist)
161+
# -------------------------------------------------------------------
162+
echo "==> Removing build-related scripts from package.json files..."
163+
164+
for pkg in "${PACKAGES[@]}"; do
165+
PKG_JSON="$DIST_DIR/repo/$pkg/package.json"
166+
node -e "
167+
const fs = require('fs');
168+
const pkg = JSON.parse(fs.readFileSync('$PKG_JSON', 'utf8'));
169+
if (pkg.scripts) {
170+
delete pkg.scripts.build;
171+
delete pkg.scripts['build-watch'];
172+
delete pkg.scripts.clean;
173+
delete pkg.scripts.prepare;
174+
delete pkg.scripts.prepublishOnly;
175+
delete pkg.scripts['type-check'];
176+
if (Object.keys(pkg.scripts).length === 0) delete pkg.scripts;
177+
}
178+
delete pkg.devDependencies;
179+
fs.writeFileSync('$PKG_JSON', JSON.stringify(pkg, null, 2) + '\n');
180+
"
181+
echo " Cleaned $pkg/package.json"
182+
done
183+
184+
# -------------------------------------------------------------------
185+
# 6. Write a top-level README
186+
# -------------------------------------------------------------------
187+
cat > "$DIST_DIR/repo/README.md" << 'READMEEOF'
188+
# react-on-rails-builds
189+
190+
Pre-built JavaScript packages from the [react_on_rails](https://github.com/shakacode/react_on_rails) monorepo.
191+
192+
This repo contains compiled output ready for consumption as git dependencies.
193+
Do not edit files here directly — they are generated by `scripts/publish-to-builds-repo.sh`
194+
in the source monorepo.
195+
196+
## Usage (pnpm)
197+
198+
```json
199+
{
200+
"dependencies": {
201+
"react-on-rails": "github:shakacode/react-on-rails-builds#TAG&path:react-on-rails",
202+
"react-on-rails-pro": "github:shakacode/react-on-rails-builds#TAG&path:react-on-rails-pro",
203+
"react-on-rails-pro-node-renderer": "github:shakacode/react-on-rails-builds#TAG&path:react-on-rails-pro-node-renderer"
204+
},
205+
"pnpm": {
206+
"overrides": {
207+
"react-on-rails": "github:shakacode/react-on-rails-builds#TAG&path:react-on-rails"
208+
}
209+
}
210+
}
211+
```
212+
213+
Replace `TAG` with the version tag (e.g., `v16.4.0-rc.5`).
214+
READMEEOF
215+
216+
# -------------------------------------------------------------------
217+
# 7. Commit and push
218+
# -------------------------------------------------------------------
219+
echo ""
220+
cd "$DIST_DIR/repo"
221+
git add -A
222+
223+
SOURCE_SHA=$(cd "$MONOREPO_ROOT" && git rev-parse --short HEAD)
224+
SOURCE_BRANCH=$(cd "$MONOREPO_ROOT" && git rev-parse --abbrev-ref HEAD)
225+
226+
if git diff --cached --quiet; then
227+
echo "==> No file changes to commit."
228+
else
229+
git commit -m "Build packages $VERSION from $SOURCE_BRANCH ($SOURCE_SHA)"
230+
fi
231+
232+
if [[ "$DRY_RUN" == "true" ]]; then
233+
echo "==> [DRY RUN] Would push to $DIST_REPO branch $DIST_BRANCH"
234+
echo "==> [DRY RUN] Would create tag $DIST_TAG"
235+
echo ""
236+
echo "==> Contents of dist repo:"
237+
find . -not -path './.git/*' -not -path './.git' | sort
238+
else
239+
echo "==> Pushing to $DIST_REPO branch $DIST_BRANCH..."
240+
git push -u origin "$DIST_BRANCH"
241+
242+
# Create and push tag
243+
if git rev-parse "$DIST_TAG" &>/dev/null; then
244+
echo "==> Tag $DIST_TAG already exists, skipping tag creation."
245+
else
246+
git tag "$DIST_TAG"
247+
git push origin "$DIST_TAG"
248+
echo "==> Tag $DIST_TAG pushed."
249+
fi
250+
fi
251+
252+
echo ""
253+
echo "==> Done! Packages published to $DIST_REPO"
254+
echo "==> Tag: $DIST_TAG"

0 commit comments

Comments
 (0)