Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 117 additions & 0 deletions .github/workflows/prerelease_open_pr_builds.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
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_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