๐Ÿšง Early alpha Under active construction. Everything here may change without notice โ€” except the appcast URL. That one's forever.

Aetower

Docs

Cloudflare Release Hosting

aetower.dev is served by two independent Cloudflare deploy units so a website edit can never take the release payload (and Sparkle auto-updates) down:

Public URLs are unchanged from the single-project era โ€” the Sparkle appcast baked into shipped apps keeps working at:


https://aetower.dev/releases/appcast.xml

URL contract

Header rules live next to what they govern: site/_headers (security block only) ships with the website; infra/releases-pages/_headers (content types + cache policy, using ! detachment so latest aliases do not inherit the immutable policy) ships with the payload.

Deploy the website (fast path, safe any time)


sh scripts/deploy-website.sh

Assembles dist/cloudflare-site from site/ (plus the brand icon), deploys it to aetower-dev, and runs a smoke check that ends with an appcast tripwire: the deploy fails loudly if /releases/appcast.xml is not being served by the release router.

Deploy the release payload (release pipeline)

Payload deploys are full snapshots, so they must contain the complete history (immutable archives, Sparkle deltas), not just the newest release. scripts/prepare-release-payload.sh therefore always syncs the live payload down first (via scripts/mirror-live-release-payload.sh, which verifies the cask sha256, appcast enclosure lengths, and live Content-Lengths), then overlays the new release's dist/ artifacts.

The release orchestrator does all of this:


sh scripts/release-public-preview.sh                      # full build
sh scripts/release-public-preview.sh --prepare-only       # reuse dist artifacts
sh scripts/release-public-preview.sh --prepare-only --publish-cloudflare

--publish-cloudflare deploys the payload to aetower-releases, runs scripts/verify-published-release.sh against the public URLs, then deploys the website. Payload-only deploys are also available directly:


sh scripts/prepare-release-payload.sh
sh scripts/deploy-release-payload.sh

Worker deploy

Only needed when infra/release-router/src/worker.js changes:


cd infra/release-router && npx wrangler@4 deploy

Configuration

All values have working defaults; override in .env.release.local if the project names or dirs ever change:


AETOWER_CLOUDFLARE_PROJECT=aetower-dev
AETOWER_CLOUDFLARE_SITE_DIR=dist/cloudflare-site
AETOWER_CLOUDFLARE_RELEASES_PROJECT=aetower-releases
AETOWER_CLOUDFLARE_RELEASES_DIR=dist/releases-payload
AETOWER_CLOUDFLARE_BRANCH=master
AETOWER_RELEASES_ORIGIN=https://aetower-releases.pages.dev

Rollback

After deploy


curl -I https://aetower.dev/
curl -I https://aetower.dev/third-party-notices.md
curl -I https://aetower.dev/releases/appcast.xml
curl -I https://aetower.dev/releases/Aetower.dmg
curl -I https://aetower.dev/releases/Aetower.zip
curl -I https://aetower.dev/releases/Aetower.pkg
curl -I https://aetower.dev/releases/Aetower-source.tar.gz
curl -I https://aetower.dev/homebrew/Casks/aetower.rb

Release payload responses carry x-aetower-release-router: 1; website responses must not. Then run the Sparkle N-1 -> N update verification before sharing the link.

Notes

Aetower is a free early-alpha download for macOS 14+ (Apple silicon).

Download for macOS