Skip to content

Commit 25eeb7f

Browse files
author
Factory Bot
committed
ci: add R2 publish workflow for CLI releases
1 parent 899664a commit 25eeb7f

1 file changed

Lines changed: 261 additions & 0 deletions

File tree

.github/workflows/publish-r2.yml

Lines changed: 261 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,261 @@
1+
name: Publish CLI Release to R2
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
version:
7+
description: "Version to publish (e.g., 0.2.0)"
8+
required: true
9+
type: string
10+
release_run_id:
11+
description: "Release workflow run ID to download artifacts from"
12+
required: true
13+
type: string
14+
channel:
15+
description: "Release channel"
16+
required: true
17+
type: choice
18+
options:
19+
- stable
20+
- beta
21+
- nightly
22+
default: stable
23+
release_notes:
24+
description: "Brief release notes (optional)"
25+
required: false
26+
type: string
27+
28+
env:
29+
BINARY_NAME: Cortex
30+
31+
permissions:
32+
contents: read
33+
actions: read
34+
35+
jobs:
36+
# ==========================================================================
37+
# Download artifacts from Release workflow and publish to R2
38+
# ==========================================================================
39+
publish:
40+
name: Publish to R2
41+
runs-on: ubuntu-latest
42+
43+
steps:
44+
- uses: actions/checkout@v4
45+
46+
- name: Download artifacts from Release run
47+
env:
48+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
49+
run: |
50+
mkdir -p artifacts
51+
echo "Downloading artifacts from run ${{ inputs.release_run_id }}..."
52+
53+
# Download all artifacts from the release run
54+
gh run download ${{ inputs.release_run_id }} --dir artifacts
55+
56+
echo "Downloaded artifacts:"
57+
ls -la artifacts/
58+
59+
- name: Verify artifacts exist
60+
run: |
61+
EXPECTED_ARTIFACTS=(
62+
"cortex-cli-linux-x64"
63+
"cortex-cli-linux-arm64"
64+
"cortex-cli-macos-x64"
65+
"cortex-cli-macos-arm64"
66+
"cortex-cli-windows-x64"
67+
"cortex-cli-windows-arm64"
68+
)
69+
70+
for artifact in "${EXPECTED_ARTIFACTS[@]}"; do
71+
if [ ! -d "artifacts/$artifact" ]; then
72+
echo "ERROR: Missing artifact: $artifact"
73+
exit 1
74+
fi
75+
echo "Found: $artifact"
76+
done
77+
78+
- name: Prepare archives and calculate checksums
79+
id: checksums
80+
run: |
81+
mkdir -p dist
82+
83+
# Unix platforms - artifacts are already .tar.gz
84+
for mapping in linux-x86_64:cortex-cli-linux-x64 linux-aarch64:cortex-cli-linux-arm64 darwin-x86_64:cortex-cli-macos-x64 darwin-aarch64:cortex-cli-macos-arm64; do
85+
IFS=':' read -r platform artifact <<< "$mapping"
86+
87+
# Find the archive file
88+
ARCHIVE=$(find "artifacts/$artifact" -name "*.tar.gz" | head -1)
89+
if [ -z "$ARCHIVE" ]; then
90+
echo "ERROR: No .tar.gz found in artifacts/$artifact"
91+
ls -la "artifacts/$artifact/"
92+
exit 1
93+
fi
94+
95+
mkdir -p "dist/$platform"
96+
cp "$ARCHIVE" "dist/$platform/cortex.tar.gz"
97+
98+
SHA=$(sha256sum "dist/$platform/cortex.tar.gz" | awk '{print $1}')
99+
echo "${platform}=$SHA" >> $GITHUB_OUTPUT
100+
echo "$platform: $SHA"
101+
done
102+
103+
# Windows platforms - artifacts are already .zip
104+
for mapping in windows-x86_64:cortex-cli-windows-x64 windows-aarch64:cortex-cli-windows-arm64; do
105+
IFS=':' read -r platform artifact <<< "$mapping"
106+
107+
ARCHIVE=$(find "artifacts/$artifact" -name "*.zip" | head -1)
108+
if [ -z "$ARCHIVE" ]; then
109+
echo "ERROR: No .zip found in artifacts/$artifact"
110+
ls -la "artifacts/$artifact/"
111+
exit 1
112+
fi
113+
114+
mkdir -p "dist/$platform"
115+
cp "$ARCHIVE" "dist/$platform/cortex.zip"
116+
117+
SHA=$(sha256sum "dist/$platform/cortex.zip" | awk '{print $1}')
118+
echo "${platform}=$SHA" >> $GITHUB_OUTPUT
119+
echo "$platform: $SHA"
120+
done
121+
122+
echo "Prepared archives:"
123+
find dist -type f
124+
125+
- name: Setup rclone
126+
run: |
127+
curl https://rclone.org/install.sh | sudo bash
128+
mkdir -p ~/.config/rclone
129+
cat > ~/.config/rclone/rclone.conf << EOF
130+
[r2]
131+
type = s3
132+
provider = Cloudflare
133+
access_key_id = ${{ secrets.R2_ACCESS_KEY_ID }}
134+
secret_access_key = ${{ secrets.R2_SECRET_ACCESS_KEY }}
135+
endpoint = https://${{ secrets.CLOUDFLARE_ACCOUNT_ID }}.r2.cloudflarestorage.com
136+
acl = private
137+
no_check_bucket = true
138+
EOF
139+
140+
- name: Create checksum files
141+
run: |
142+
for platform in linux-x86_64 linux-aarch64 darwin-x86_64 darwin-aarch64; do
143+
sha256sum "dist/$platform/cortex.tar.gz" | awk '{print $1 " cortex.tar.gz"}' > "dist/$platform/cortex.tar.gz.sha256"
144+
echo "$platform: $(cat dist/$platform/cortex.tar.gz.sha256)"
145+
done
146+
147+
for platform in windows-x86_64 windows-aarch64; do
148+
sha256sum "dist/$platform/cortex.zip" | awk '{print $1 " cortex.zip"}' > "dist/$platform/cortex.zip.sha256"
149+
echo "$platform: $(cat dist/$platform/cortex.zip.sha256)"
150+
done
151+
152+
- name: Upload assets to R2
153+
run: |
154+
VERSION="${{ inputs.version }}"
155+
156+
for platform in linux-x86_64 linux-aarch64 darwin-x86_64 darwin-aarch64; do
157+
echo "Uploading $platform..."
158+
rclone copy "dist/$platform/cortex.tar.gz" "r2:cortex-software/assets/$platform/$VERSION/" --progress
159+
rclone copy "dist/$platform/cortex.tar.gz.sha256" "r2:cortex-software/assets/$platform/$VERSION/" --progress
160+
done
161+
162+
for platform in windows-x86_64 windows-aarch64; do
163+
echo "Uploading $platform..."
164+
rclone copy "dist/$platform/cortex.zip" "r2:cortex-software/assets/$platform/$VERSION/" --progress
165+
rclone copy "dist/$platform/cortex.zip.sha256" "r2:cortex-software/assets/$platform/$VERSION/" --progress
166+
done
167+
168+
- name: Install jq
169+
run: sudo apt-get update && sudo apt-get install -y jq
170+
171+
- name: Generate release manifest
172+
run: |
173+
VERSION="${{ inputs.version }}"
174+
CHANNEL="${{ inputs.channel }}"
175+
RELEASE_NOTES="${{ inputs.release_notes }}"
176+
RELEASED_AT=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
177+
BASE_URL="https://software.cortex.foundation/v1/assets"
178+
179+
cat > release.json << EOF
180+
{
181+
"version": "$VERSION",
182+
"channel": "$CHANNEL",
183+
"released_at": "$RELEASED_AT",
184+
"changelog_url": "https://github.com/${{ github.repository }}/blob/main/CHANGELOG.md",
185+
"release_notes": "$RELEASE_NOTES",
186+
"assets": {
187+
"linux-x86_64": {
188+
"url": "$BASE_URL/linux-x86_64/$VERSION/cortex.tar.gz",
189+
"sha256": "${{ steps.checksums.outputs.linux-x86_64 }}",
190+
"size": $(stat -c%s dist/linux-x86_64/cortex.tar.gz 2>/dev/null || echo 0)
191+
},
192+
"linux-aarch64": {
193+
"url": "$BASE_URL/linux-aarch64/$VERSION/cortex.tar.gz",
194+
"sha256": "${{ steps.checksums.outputs.linux-aarch64 }}",
195+
"size": $(stat -c%s dist/linux-aarch64/cortex.tar.gz 2>/dev/null || echo 0)
196+
},
197+
"darwin-x86_64": {
198+
"url": "$BASE_URL/darwin-x86_64/$VERSION/cortex.tar.gz",
199+
"sha256": "${{ steps.checksums.outputs.darwin-x86_64 }}",
200+
"size": $(stat -c%s dist/darwin-x86_64/cortex.tar.gz 2>/dev/null || echo 0)
201+
},
202+
"darwin-aarch64": {
203+
"url": "$BASE_URL/darwin-aarch64/$VERSION/cortex.tar.gz",
204+
"sha256": "${{ steps.checksums.outputs.darwin-aarch64 }}",
205+
"size": $(stat -c%s dist/darwin-aarch64/cortex.tar.gz 2>/dev/null || echo 0)
206+
},
207+
"windows-x86_64": {
208+
"url": "$BASE_URL/windows-x86_64/$VERSION/cortex.zip",
209+
"sha256": "${{ steps.checksums.outputs.windows-x86_64 }}",
210+
"size": $(stat -c%s dist/windows-x86_64/cortex.zip 2>/dev/null || echo 0)
211+
},
212+
"windows-aarch64": {
213+
"url": "$BASE_URL/windows-aarch64/$VERSION/cortex.zip",
214+
"sha256": "${{ steps.checksums.outputs.windows-aarch64 }}",
215+
"size": $(stat -c%s dist/windows-aarch64/cortex.zip 2>/dev/null || echo 0)
216+
}
217+
}
218+
}
219+
EOF
220+
221+
cat release.json
222+
223+
- name: Upload release manifest to R2
224+
run: |
225+
VERSION="${{ inputs.version }}"
226+
CHANNEL="${{ inputs.channel }}"
227+
228+
rclone copyto release.json "r2:cortex-software/releases/$VERSION.json" --progress
229+
230+
# Try to download existing manifest, create empty one if not found
231+
rclone copy "r2:cortex-software/releases/manifest.json" . 2>/dev/null || true
232+
if [ ! -f manifest.json ]; then
233+
echo '{"stable":null,"beta":null,"nightly":null,"all_versions":[]}' > manifest.json
234+
fi
235+
236+
RELEASE_JSON=$(cat release.json)
237+
jq --argjson release "$RELEASE_JSON" --arg channel "$CHANNEL" --arg version "$VERSION" '
238+
.[$channel] = $release |
239+
.all_versions = ([$version] + (.all_versions // []) | unique | reverse)
240+
' manifest.json > manifest_new.json
241+
mv manifest_new.json manifest.json
242+
243+
rclone copyto manifest.json "r2:cortex-software/releases/manifest.json" --progress
244+
245+
echo "Updated manifest:"
246+
cat manifest.json
247+
248+
- name: Summary
249+
run: |
250+
echo "## CLI Release Published" >> $GITHUB_STEP_SUMMARY
251+
echo "" >> $GITHUB_STEP_SUMMARY
252+
echo "| Property | Value |" >> $GITHUB_STEP_SUMMARY
253+
echo "|----------|-------|" >> $GITHUB_STEP_SUMMARY
254+
echo "| Version | ${{ inputs.version }} |" >> $GITHUB_STEP_SUMMARY
255+
echo "| Channel | ${{ inputs.channel }} |" >> $GITHUB_STEP_SUMMARY
256+
echo "| Source Run | [${{ inputs.release_run_id }}](https://github.com/${{ github.repository }}/actions/runs/${{ inputs.release_run_id }}) |" >> $GITHUB_STEP_SUMMARY
257+
echo "" >> $GITHUB_STEP_SUMMARY
258+
echo "### Download URLs" >> $GITHUB_STEP_SUMMARY
259+
echo "- Linux x64: https://software.cortex.foundation/v1/assets/linux-x86_64/${{ inputs.version }}/cortex.tar.gz" >> $GITHUB_STEP_SUMMARY
260+
echo "- macOS ARM64: https://software.cortex.foundation/v1/assets/darwin-aarch64/${{ inputs.version }}/cortex.tar.gz" >> $GITHUB_STEP_SUMMARY
261+
echo "- Windows x64: https://software.cortex.foundation/v1/assets/windows-x86_64/${{ inputs.version }}/cortex.zip" >> $GITHUB_STEP_SUMMARY

0 commit comments

Comments
 (0)