Skip to content

Merge branch 'release/20260101-1' #31

Merge branch 'release/20260101-1'

Merge branch 'release/20260101-1' #31

Workflow file for this run

name: Build and Release Cores

Check failure on line 1 in .github/workflows/build-release.yml

View workflow run for this annotation

GitHub Actions / .github/workflows/build-release.yml

Invalid workflow file

(Line: 21, Col: 14): Unrecognized function: 'hashFiles'. Located at position 1 within expression: hashFiles('Dockerfile')
on:
push:
tags:
- "[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]-[0-9]*" # Match YYYYMMDD-N format (e.g., 20251115-0)
concurrency:
group: release-${{ github.ref }}
cancel-in-progress: false # Don't cancel releases mid-build
permissions:
contents: write
packages: write
jobs:
docker-build:
runs-on: sprinters:aws:ubuntu-24.04-arm:c7gd.xlarge:temp=32
timeout-minutes: 30
concurrency:
group: docker-build-${{ hashFiles('Dockerfile') }}
cancel-in-progress: false
steps:
- name: Checkout code
uses: actions/checkout@v5
with:
submodules: recursive
fetch-depth: 0
- name: Calculate Dockerfile hash
id: dockerfile-hash
run: |
HASH=$(sha256sum Dockerfile | awk '{print $1}')
echo "hash=$HASH" >> $GITHUB_OUTPUT
echo "Dockerfile hash: $HASH"
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Check if image exists in GHCR
id: check-image
run: |
IMAGE="ghcr.io/${{ github.repository_owner }}/lessui-cores-builder:${{ steps.dockerfile-hash.outputs.hash }}"
if docker pull "$IMAGE" 2>/dev/null; then
echo "✓ Image found in GHCR (skipped 28 min build!)"
echo "exists=true" >> $GITHUB_OUTPUT
else
echo "Image not found, will build"
echo "exists=false" >> $GITHUB_OUTPUT
fi
- name: Set up Docker Buildx
if: steps.check-image.outputs.exists == 'false'
uses: docker/setup-buildx-action@v3
- name: Build and push Docker image
if: steps.check-image.outputs.exists == 'false'
uses: docker/build-push-action@v6
with:
context: .
push: true
tags: |
ghcr.io/${{ github.repository_owner }}/lessui-cores-builder:${{ steps.dockerfile-hash.outputs.hash }}
ghcr.io/${{ github.repository_owner }}/lessui-cores-builder:latest
cache-from: type=gha
cache-to: type=gha,mode=max
build:
needs: docker-build
runs-on: sprinters:aws:ubuntu-24.04-arm:c7gd.xlarge:temp=32
timeout-minutes: 120 # 2 hours max per architecture
strategy:
matrix:
cpu: [arm32, arm64]
fail-fast: false # Continue other builds even if one fails
steps:
- name: Checkout code
uses: actions/checkout@v5
with:
submodules: recursive
fetch-depth: 0
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Pull Docker image from GHCR
run: |
docker pull ghcr.io/${{ github.repository_owner }}/lessui-cores-builder:latest
docker tag ghcr.io/${{ github.repository_owner }}/lessui-cores-builder:latest lessui-cores-builder:latest
- name: Clean previous builds
run: make clean
- name: Build ${{ matrix.cpu }}
env:
JOBS: 4
SKIP_DOCKER_BUILD: 1
run: |
echo "Starting build for ${{ matrix.cpu }} at $(date)"
make build-${{ matrix.cpu }}
echo "Build completed at $(date)"
- name: Verify build
run: |
count=$(ls output/${{ matrix.cpu }}/*.so 2>/dev/null | wc -l)
echo "${{ matrix.cpu }}: $count cores built"
if [ "$count" -eq 0 ]; then
echo "ERROR: No cores built for ${{ matrix.cpu }}"
exit 1
fi
- name: Package build
run: make package-${{ matrix.cpu }}
- name: Verify package
run: |
if [ -f "output/dist/linux-${{ matrix.cpu }}.zip" ]; then
size=$(du -h "output/dist/linux-${{ matrix.cpu }}.zip" | cut -f1)
echo "linux-${{ matrix.cpu }}.zip: $size"
else
echo "ERROR: output/dist/linux-${{ matrix.cpu }}.zip not found"
exit 1
fi
- name: Upload package artifact
uses: actions/upload-artifact@v4
with:
name: linux-${{ matrix.cpu }}
path: output/dist/linux-${{ matrix.cpu }}.zip
retention-days: 7
- name: Save build info
run: |
count=$(ls output/${{ matrix.cpu }}/*.so 2>/dev/null | wc -l)
echo "$count" > core-count-${{ matrix.cpu }}.txt
- name: Upload build info artifact
uses: actions/upload-artifact@v4
with:
name: build-info-${{ matrix.cpu }}
path: core-count-${{ matrix.cpu }}.txt
retention-days: 7
release:
needs: build
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout code
uses: actions/checkout@v5
with:
fetch-depth: 1 # Only need current commit for release
- name: Download build artifacts
uses: actions/download-artifact@v4
with:
pattern: linux-*
path: artifacts
- name: Download build info artifacts
uses: actions/download-artifact@v4
with:
pattern: build-info-*
path: artifacts
- name: Verify downloads
run: |
echo "Checking downloaded artifacts..."
ls -lR artifacts/
# Verify packages exist
if [ ! -f "artifacts/linux-arm32/linux-arm32.zip" ]; then
echo "ERROR: linux-arm32.zip not found"
exit 1
fi
if [ ! -f "artifacts/linux-arm64/linux-arm64.zip" ]; then
echo "ERROR: linux-arm64.zip not found"
exit 1
fi
# Verify build info exists
if [ ! -f "artifacts/build-info-arm32/core-count-arm32.txt" ]; then
echo "ERROR: core-count-arm32.txt not found"
exit 1
fi
if [ ! -f "artifacts/build-info-arm64/core-count-arm64.txt" ]; then
echo "ERROR: core-count-arm64.txt not found"
exit 1
fi
echo "✓ All required artifacts downloaded"
- name: Organize artifacts
run: |
mkdir -p release-packages
mv artifacts/linux-arm32/linux-arm32.zip release-packages/
mv artifacts/linux-arm64/linux-arm64.zip release-packages/
ls -lh release-packages/
- name: Generate release notes
id: release_notes
run: |
# Get core counts
arm32_count=$(cat artifacts/build-info-arm32/core-count-arm32.txt)
arm64_count=$(cat artifacts/build-info-arm64/core-count-arm64.txt)
cat << EOF > release_notes.md
# lessui-cores ${GITHUB_REF_NAME}
Libretro cores for ARM-based retro handhelds running MinUI.
| Package | Cores | Devices |
|---------|-------|---------|
| **linux-arm32.zip** | ${arm32_count} | Miyoo Mini, RG35XX, Trimui Smart |
| **linux-arm64.zip** | ${arm64_count} | RG28xx/40xx, CubeXX, Trimui |
Built $(date -u '+%Y-%m-%d') from commit ${GITHUB_SHA:0:8}
EOF
echo "notes_file=release_notes.md" >> $GITHUB_OUTPUT
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
files: release-packages/*.zip
body_path: release_notes.md
prerelease: false
make_latest: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Update 'latest' tag
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git tag -f latest
git push -f origin latest