Upload Release to Cloudflare R2 #179
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Upload Release to Cloudflare R2 | |
| on: | |
| release: | |
| types: [published] | |
| workflow_dispatch: | |
| inputs: | |
| tag: | |
| description: 'Release tag to upload (e.g. v0.1.28)' | |
| required: true | |
| channel: | |
| description: 'Channel: stable or beta (default: auto-detect from prerelease flag)' | |
| required: false | |
| default: 'auto' | |
| jobs: | |
| upload: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Download release assets | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| TAG="${{ github.event.release.tag_name || inputs.tag }}" | |
| mkdir artifacts | |
| gh release download "$TAG" \ | |
| --repo ${{ github.repository }} \ | |
| --dir ./artifacts | |
| echo "Assets:" | |
| ls -lh ./artifacts/ | |
| - name: Upload to Cloudflare R2 | |
| env: | |
| AWS_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }} | |
| AWS_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }} | |
| AWS_DEFAULT_REGION: auto | |
| run: | | |
| TAG="${{ github.event.release.tag_name || inputs.tag }}" | |
| VERSION="${TAG#v}" | |
| ENDPOINT="https://a851dc5e529a04a83d87176e91cfad51.r2.cloudflarestorage.com" | |
| PUBLIC_BASE="https://pub-e99883270f2047d9a6151090f7da8a5c.r2.dev" | |
| # Determine channel: manual input → auto-detect from prerelease flag | |
| CHANNEL_INPUT="${{ inputs.channel }}" | |
| IS_PRERELEASE="${{ github.event.release.prerelease }}" | |
| if [ "$CHANNEL_INPUT" = "beta" ]; then | |
| IS_BETA=true | |
| elif [ "$CHANNEL_INPUT" = "stable" ]; then | |
| IS_BETA=false | |
| elif [ "$IS_PRERELEASE" = "true" ]; then | |
| IS_BETA=true | |
| else | |
| IS_BETA=false | |
| fi | |
| echo "Channel: $( [ "$IS_BETA" = "true" ] && echo beta || echo stable )" | |
| # Upload release zip | |
| for f in ./artifacts/*.zip; do | |
| [ -f "$f" ] || continue | |
| filename=$(basename "$f") | |
| echo "Uploading $filename..." | |
| aws s3 cp "$f" "s3://ai-resource-manager/$TAG/$filename" \ | |
| --endpoint-url "$ENDPOINT" \ | |
| --no-progress | |
| echo "URL: $PUBLIC_BASE/$TAG/$filename" | |
| # Generate manifest JSON | |
| size=$(stat -c%s "$f") | |
| published="${{ github.event.release.published_at }}" | |
| if [ -z "$published" ]; then published=$(date -u +"%Y-%m-%dT%H:%M:%SZ"); fi | |
| node -e " | |
| const fs = require('fs'); | |
| const manifest = JSON.stringify({ | |
| version: '$VERSION', | |
| tag: '$TAG', | |
| filename: '$filename', | |
| size: $size, | |
| publishedAt: '$published' | |
| }, null, 2); | |
| fs.writeFileSync('manifest.json', manifest); | |
| " | |
| done | |
| # Beta channel always gets latest-beta.json | |
| aws s3 cp manifest.json "s3://ai-resource-manager/latest-beta.json" \ | |
| --endpoint-url "$ENDPOINT" \ | |
| --content-type "application/json" \ | |
| --cache-control "no-store" \ | |
| --no-progress | |
| echo "latest-beta.json updated -> $PUBLIC_BASE/latest-beta.json" | |
| # Stable releases also update latest.json (beta releases never touch this) | |
| # This ensures old app versions (which only know about latest.json) never see beta builds. | |
| if [ "$IS_BETA" = "false" ]; then | |
| aws s3 cp manifest.json "s3://ai-resource-manager/latest.json" \ | |
| --endpoint-url "$ENDPOINT" \ | |
| --content-type "application/json" \ | |
| --cache-control "no-store" \ | |
| --no-progress | |
| echo "latest.json updated -> $PUBLIC_BASE/latest.json" | |
| else | |
| echo "Beta release: skipping latest.json update (stable users unaffected)" | |
| fi | |
| # Generate and upload changelog.json from GitHub releases API. | |
| # Hosted on R2 so clients in China can fetch it without VPN. | |
| GH_TOKEN="${{ github.token }}" gh api "repos/${{ github.repository }}/releases?per_page=15" \ | |
| --jq '[.[] | {tag: (.tag_name | ltrimstr("v")), name, body, publishedAt: .published_at}]' \ | |
| > changelog.json | |
| aws s3 cp changelog.json "s3://ai-resource-manager/changelog.json" \ | |
| --endpoint-url "$ENDPOINT" \ | |
| --content-type "application/json" \ | |
| --cache-control "no-store" \ | |
| --no-progress | |
| echo "changelog.json updated -> $PUBLIC_BASE/changelog.json" |