Fix web flasher versioned releases failing with CORS error

GitHub release download URLs redirect to release-assets.githubusercontent.com
which doesn't return Access-Control-Allow-Origin headers. The browser blocks
cross-origin fetches from the GitHub Pages flasher, causing "Failed to fetch"
for any versioned release while the latest dev build (same-origin) works fine.

Fix: Deploy versioned firmware binaries to GitHub Pages alongside the dev
build at firmware/releases/{tag}/, so all versions are fetched same-origin.
The CI workflow now downloads existing release assets and deploys them to
Pages with keep_files: true to preserve across deploys.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
torlando-tech
2026-03-03 20:57:38 -05:00
parent 609a3bc62b
commit ee87edef7a
2 changed files with 41 additions and 2 deletions
+39
View File
@@ -51,6 +51,44 @@ jobs:
BOOT_APP0=$(find ~/.platformio -name "boot_app0.bin" | head -1)
cp "$BOOT_APP0" docs/flasher/firmware/
# For tagged releases, also deploy to a versioned path on GitHub Pages
# so the flasher can fetch them same-origin (GitHub release downloads lack CORS)
if [[ "$GITHUB_REF" == refs/tags/v* ]]; then
TAG="${GITHUB_REF#refs/tags/}"
mkdir -p "docs/flasher/firmware/releases/${TAG}"
cp .pio/build/tdeck/bootloader.bin "docs/flasher/firmware/releases/${TAG}/"
cp .pio/build/tdeck/partitions.bin "docs/flasher/firmware/releases/${TAG}/"
cp .pio/build/tdeck/firmware.bin "docs/flasher/firmware/releases/${TAG}/"
cp "$BOOT_APP0" "docs/flasher/firmware/releases/${TAG}/"
fi
- name: Download existing release assets for GitHub Pages
run: |
# Fetch all published releases and download their firmware assets
# so versioned firmware is available same-origin on GitHub Pages.
# With keep_files: true, each release only needs to be downloaded once.
for tag in $(gh api repos/${{ github.repository }}/releases --jq '.[].tag_name'); do
dir="docs/flasher/firmware/releases/${tag}"
# Skip if we already have this version's firmware (e.g., current tagged build)
if [ -f "${dir}/firmware.bin" ]; then
echo "Skipping ${tag} — already present"
continue
fi
mkdir -p "${dir}"
echo "Downloading assets for ${tag}..."
for asset in bootloader.bin partitions.bin boot_app0.bin firmware.bin; do
url="https://github.com/${{ github.repository }}/releases/download/${tag}/${asset}"
if curl -sL -o "${dir}/${asset}" -w '%{http_code}' "${url}" | grep -q 200; then
echo " ${asset} OK"
else
rm -f "${dir}/${asset}"
echo " ${asset} not found"
fi
done
done
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Generate manifest files
run: |
VERSION="${{ steps.version.outputs.VERSION }}"
@@ -94,6 +132,7 @@ jobs:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./docs/flasher
destination_dir: flasher
keep_files: true
- name: Create GitHub Release
if: startsWith(github.ref, 'refs/tags/v')
+2 -2
View File
@@ -386,7 +386,7 @@
const hasAll = REQUIRED_FULL_ASSETS.every(f => assetNames.includes(f));
option.value = release.tag_name;
option.textContent = release.tag_name + (release.name && release.name !== release.tag_name ? `${release.name}` : '');
option.dataset.downloadUrl = `https://github.com/torlando-tech/pyxis/releases/download/${release.tag_name}/`;
option.dataset.downloadUrl = `firmware/releases/${release.tag_name}/`;
option.dataset.hasFullAssets = hasAll ? 'true' : 'false';
versionSelect.appendChild(option);
}
@@ -458,7 +458,7 @@
for (const file of files) {
log(`Loading ${file.name}...`);
const response = await fetch(file.path);
if (!response.ok) throw new Error(`Failed to load ${file.name}`);
if (!response.ok) throw new Error(`Failed to fetch ${file.name} (HTTP ${response.status}). This version may not be available yet — try "Latest" instead.`);
const arrayBuffer = await response.arrayBuffer();
const bytes = new Uint8Array(arrayBuffer);
let binaryString = '';