Repository navigation
release: 0.0.39 — Windows runs the Linux build in WSL, no installer to sign #59
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
ade7916
441fd45
23e852c
5441712
4eaf92d
67d082e
a5ac548
b384434
b2bd3ae
a68130c
b52a73d
2838d47
34e5f7f
f36b15d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
The site has been deployed by hand: git archive a commit into /opt/1helm-site/releases/<sha>, repoint current, restart the unit. That is fragile for something that gates a release - install.ps1 and install.sh are served from here, and install.sh resolves /api/releases/linux/latest to find the Linux archive, so publishing a release without deploying the site leaves Windows with no installer and Linux unable to resolve a version. Refuses any commit that is not an ancestor of origin/main, so the live surface always traces back to reviewed source. Verifies the archive actually contains install.sh, install.ps1 and the keepalive payload before going live, and rolls back to the previous release if the new one fails to answer its health endpoint. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,85 @@ | ||||||||||||||
| #!/usr/bin/env bash | ||||||||||||||
| # Deploy 1helm.com from an exact Git commit. | ||||||||||||||
| # | ||||||||||||||
| # The site is a release-directory deployment on this host: each release is an | ||||||||||||||
| # immutable `git archive` of one commit under /opt/1helm-site/releases/<sha>, | ||||||||||||||
| # `current` points at the live one, and 1helm-site.service runs | ||||||||||||||
| # `node site/server.mjs` from there behind 1helm-site-cloudflared.service. | ||||||||||||||
| # | ||||||||||||||
| # This exists because the site gates a release. install.ps1 and install.sh are | ||||||||||||||
| # served from here, and install.sh resolves /api/releases/linux/latest to find | ||||||||||||||
| # the archive - so a release published without deploying the site leaves Windows | ||||||||||||||
| # with no installer and Linux unable to resolve a version. | ||||||||||||||
| # | ||||||||||||||
| # scripts/deploy-site.sh <commit-ish> | ||||||||||||||
| # | ||||||||||||||
| # Rolls back to the previous release automatically if the new one fails to | ||||||||||||||
| # answer, so a bad deploy cannot leave 1helm.com down. | ||||||||||||||
| set -euo pipefail | ||||||||||||||
|
|
||||||||||||||
| SITE_ROOT=/opt/1helm-site | ||||||||||||||
| RELEASES="$SITE_ROOT/releases" | ||||||||||||||
| CURRENT="$SITE_ROOT/current" | ||||||||||||||
| UNIT=1helm-site.service | ||||||||||||||
| PORT=8130 | ||||||||||||||
|
|
||||||||||||||
| [[ "${EUID}" -eq 0 ]] || { echo "Run with sudo." >&2; exit 1; } | ||||||||||||||
| COMMITISH="${1:-}" | ||||||||||||||
| [[ -n "$COMMITISH" ]] || { echo "usage: $0 <commit-ish>" >&2; exit 1; } | ||||||||||||||
|
|
||||||||||||||
| REPO="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)" | ||||||||||||||
| cd "$REPO" | ||||||||||||||
|
|
||||||||||||||
| SHA="$(git rev-parse --verify "$COMMITISH^{commit}")" | ||||||||||||||
| # A deployed site must be reproducible from a pushed commit, otherwise the live | ||||||||||||||
| # surface cannot be traced back to reviewed source. | ||||||||||||||
| git merge-base --is-ancestor "$SHA" origin/main 2>/dev/null \ | ||||||||||||||
| || { echo "Refusing to deploy $SHA: it is not an ancestor of origin/main." >&2; exit 1; } | ||||||||||||||
|
|
||||||||||||||
| TARGET="$RELEASES/$SHA" | ||||||||||||||
| PREVIOUS="$(readlink -f "$CURRENT" 2>/dev/null || true)" | ||||||||||||||
|
|
||||||||||||||
| echo "repo : $REPO" | ||||||||||||||
| echo "commit : $SHA" | ||||||||||||||
| echo "previous : ${PREVIOUS:-<none>}" | ||||||||||||||
|
|
||||||||||||||
| if [[ -d "$TARGET" ]]; then | ||||||||||||||
| echo "release directory already exists; reusing it" | ||||||||||||||
| else | ||||||||||||||
| install -d -m 0755 "$TARGET" | ||||||||||||||
| git archive --format=tar "$SHA" | tar -x -C "$TARGET" | ||||||||||||||
| # The site serves the product's own public assets from ../public, so a bare | ||||||||||||||
| # archive of site/ alone would 404 icons and schemas. | ||||||||||||||
| [[ -d "$TARGET/site" && -f "$TARGET/site/server.mjs" ]] \ | ||||||||||||||
| || { echo "archive is missing site/server.mjs" >&2; rm -rf -- "$TARGET"; exit 1; } | ||||||||||||||
| for required in site/public/install.sh site/public/install.ps1 site/public/keepalive/keepalive-install.ps1; do | ||||||||||||||
| [[ -e "$TARGET/$required" ]] || { echo "archive is missing $required" >&2; rm -rf -- "$TARGET"; exit 1; } | ||||||||||||||
| done | ||||||||||||||
| fi | ||||||||||||||
|
|
||||||||||||||
| ln -sfn "$TARGET" "$SITE_ROOT/.current-next" | ||||||||||||||
| mv -Tf "$SITE_ROOT/.current-next" "$CURRENT" | ||||||||||||||
| systemctl restart "$UNIT" | ||||||||||||||
|
|
||||||||||||||
| healthy=0 | ||||||||||||||
| for _ in $(seq 1 60); do | ||||||||||||||
| if curl -fsS "http://127.0.0.1:$PORT/health" >/dev/null 2>&1; then healthy=1; break; fi | ||||||||||||||
| sleep 0.5 | ||||||||||||||
| done | ||||||||||||||
|
|
||||||||||||||
| if [[ "$healthy" -ne 1 ]]; then | ||||||||||||||
| echo "New release did not answer on :$PORT - rolling back." >&2 | ||||||||||||||
| if [[ -n "$PREVIOUS" && -d "$PREVIOUS" ]]; then | ||||||||||||||
| ln -sfn "$PREVIOUS" "$SITE_ROOT/.current-next" | ||||||||||||||
| mv -Tf "$SITE_ROOT/.current-next" "$CURRENT" | ||||||||||||||
| systemctl restart "$UNIT" | ||||||||||||||
| echo "Rolled back to $PREVIOUS." >&2 | ||||||||||||||
| fi | ||||||||||||||
| systemctl status "$UNIT" --no-pager -l >&2 || true | ||||||||||||||
| exit 1 | ||||||||||||||
| fi | ||||||||||||||
|
|
||||||||||||||
| echo "deployed : $SHA" | ||||||||||||||
| for path in /health /install.sh /install.ps1 /keepalive/keepalive-install.ps1 /api/releases/linux/latest; do | ||||||||||||||
| printf ' %-38s %s\n' "$path" "$(curl -s -o /dev/null -w '%{http_code}' "http://127.0.0.1:$PORT$path")" | ||||||||||||||
| done | ||||||||||||||
|
Comment on lines
+83
to
+85
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win Add
🔎 Proposed fix-for path in /health /install.sh /install.ps1 /keepalive/keepalive-install.ps1 /api/releases/linux/latest; do
+for path in /health /install.sh /install.ps1 /uninstall.ps1 /keepalive/keepalive-install.ps1 /api/releases/linux/latest; do📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
Validate a reused release directory before promoting it.
The required-asset checks at lines 53-57 only run in the
elsebranch. If an earlier run was interrupted duringgit archive | tar -x,$TARGETexists but is incomplete. Line 47 then reuses it, and line 61 promotes that partial tree tocurrent. The installers in this same PR guard against exactly this case (install.shline 306-309,update-host.shline 282-285).Move the validation out of the conditional so both the fresh and the reused path are proven.
🐛 Proposed fix: validate on both paths
📝 Committable suggestion
🤖 Prompt for AI Agents