Skip to content

Prerelease Open PR Builds #34

Prerelease Open PR Builds

Prerelease Open PR Builds #34

name: Prerelease Open PR Builds
on:
workflow_dispatch:
workflow_run:
workflows:
- "Build OpenEarable v2 Firmware"
types:
- completed
permissions:
contents: write
actions: read
pull-requests: read
env:
TAG: pr-builds
BUILD_WORKFLOW_NAME: "Build OpenEarable v2 Firmware"
jobs:
prerelease:
if: |
github.event_name == 'workflow_dispatch' ||
(
github.event_name == 'workflow_run' &&
github.event.workflow_run.conclusion == 'success' &&
github.event.workflow_run.event == 'pull_request'
)
runs-on: ubuntu-latest
steps:
- name: Ensure prerelease exists
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh release view "$TAG" --repo "${{ github.repository }}" >/dev/null 2>&1 || \
gh release create "$TAG" \
--repo "${{ github.repository }}" \
--prerelease \
--title "Open PR builds" \
--notes "Rolling prerelease containing build outputs from all open PRs."
- name: List open PRs
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh pr list --repo "${{ github.repository }}" --state open --json number,headRefOid,title --limit 200 > prs.json
- name: Download artifacts from each PR's latest successful build
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -euo pipefail
rm -rf collected && mkdir -p collected
jq -c '.[]' prs.json | while read -r pr; do
num=$(echo "$pr" | jq -r .number)
sha=$(echo "$pr" | jq -r .headRefOid)
title=$(echo "$pr" | jq -r .title)
safe_title=$(echo "$title" | sed 's/[^a-zA-Z0-9_-]/_/g' | cut -c1-50)
run_id=$(gh run list \
--repo "${{ github.repository }}" \
--workflow "$BUILD_WORKFLOW_NAME" \
--commit "$sha" \
--status success \
--limit 1 \
--json databaseId \
--jq '.[0].databaseId')
if [ -z "$run_id" ] || [ "$run_id" = "null" ]; then
echo "PR #$num: no successful run found"
continue
fi
out="collected/pr-$num"
rm -rf "$out" && mkdir -p "$out"
if ! gh run download "$run_id" --repo "${{ github.repository }}" -n "openearable_v2_firmware.elf" -D "$out/elf" 2>&1; then
echo "PR #$num: failed to download firmware.elf artifact (may be expired)"
rm -rf "$out"
continue
fi
if ! gh run download "$run_id" --repo "${{ github.repository }}" -n "openearable_v2_fota.zip" -D "$out/fota" 2>&1; then
echo "PR #$num: failed to download fota.zip artifact (may be expired)"
rm -rf "$out"
continue
fi
(cd "$out/fota" && zip -r "../openearable_v2_fota.zip" .)
mv "$out/elf/openearable_v2_firmware.elf" "$out/openearable_v2_firmware.elf"
rm -rf "$out/elf" "$out/fota"
echo "$safe_title" > "$out/title.txt"
echo "PR #$num ($title): artifacts downloaded and prepared successfully"
done
- name: Upload all PR assets to prerelease (overwrite)
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -euo pipefail
mkdir -p collected/upload
find collected -type f \( -name "*.elf" -o -name "*.zip" \) | while read -r f; do
pr=$(echo "$f" | sed -n 's#.*/pr-\([0-9]\+\)/.*#\1#p')
base=$(basename "$f")
title_file="collected/pr-$pr/title.txt"
if [ -f "$title_file" ]; then
safe_title=$(cat "$title_file")
asset="pr-${pr}-${safe_title}-${base}"
else
asset="pr-${pr}-${base}"
fi
cp "$f" "collected/upload/$asset"
gh release upload "$TAG" "collected/upload/$asset" --repo "${{ github.repository }}" --clobber
done
# delete assets of closed PRs
open_prs="$(jq -r '.[].number' prs.json || true)"
gh release view "$TAG" --repo "${{ github.repository }}" --json assets -q '.assets[].name' | while read -r asset; do
pr="$(echo "$asset" | sed -n 's/^pr-\([0-9]\+\)-.*$/\1/p')"
[ -n "$pr" ] || continue
if ! echo "$open_prs" | grep -qx "$pr"; then
echo "Deleting asset $asset (PR #$pr is closed/merged)"
gh release delete-asset "$TAG" "$asset" --repo "${{ github.repository }}" --yes
fi
done