ti-pote/.gitea/workflows/build-sd-image.yml
ordinarthur aa1fa581ca fix: clean up leftover container before pi-gen build
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 22:11:53 +02:00

140 lines
4.6 KiB
YAML

name: Build Ti-Pote SD Image
on:
workflow_dispatch:
push:
tags:
- 'v*'
jobs:
build-image:
name: Build Raspberry Pi SD Image
runs-on: ubuntu-latest
timeout-minutes: 180
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 22
- name: Install pnpm
run: npm install -g pnpm@latest
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Build robot-client
run: pnpm --filter @ti-pote/robot-client build
- name: Prepare pi-gen stage files
run: |
STAGE_FILES="tools/pi-gen-tipote/stage-tipote/01-install-tipote/files"
rm -rf "$STAGE_FILES"
mkdir -p "$STAGE_FILES"
cp -r apps/robot-client/dist "$STAGE_FILES/dist"
cp apps/robot-client/package.json "$STAGE_FILES/package.json"
cp apps/robot-client/deploy/tipote.service "$STAGE_FILES/tipote.service"
cp apps/robot-client/deploy/journald-tipote.conf "$STAGE_FILES/journald-tipote.conf"
- name: Register QEMU for ARM emulation
run: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
- name: Build pi-gen Docker image
run: docker build -t tipote-builder tools/pi-gen-tipote/
- name: Build SD image in Docker
run: |
# Clean up any leftover container from a previous failed build
docker rm -f tipote-build 2>/dev/null || true
# Run pi-gen build inside a privileged container
# Use docker cp (not volume mounts) because of DooD path mapping
docker run --privileged --name tipote-build tipote-builder
# Extract the output image
mkdir -p output
docker cp tipote-build:/output/. output/ 2>/dev/null || true
# Fallback: check pi-gen deploy dir directly
if [ -z "$(ls output/*.img* 2>/dev/null)" ]; then
docker cp tipote-build:/build/pi-gen/deploy/. output/ 2>/dev/null || true
fi
docker rm tipote-build
echo "=== Build output ==="
ls -lh output/ || echo "No output found"
- name: Determine version
id: version
run: |
if [[ "$GITHUB_REF" == refs/tags/v* ]]; then
VERSION="${GITHUB_REF#refs/tags/v}"
else
VERSION="dev-$(echo $GITHUB_SHA | cut -c1-7)"
fi
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
- name: Prepare final image
run: |
VERSION="${{ steps.version.outputs.version }}"
IMG_FILE=$(find output -name "*.img.xz" -o -name "*.img" 2>/dev/null | head -1)
if [ -z "$IMG_FILE" ]; then
echo "ERROR: No image found in output/"
ls -laR output/ || true
exit 1
fi
BASENAME="tipote-${VERSION}.img"
if [[ "$IMG_FILE" == *.img.xz ]]; then
mv "$IMG_FILE" "output/${BASENAME}.xz"
else
mv "$IMG_FILE" "output/$BASENAME"
xz -T0 -6 "output/$BASENAME"
fi
ls -lh output/
echo "IMAGE_FILE=${BASENAME}.xz" >> "$GITHUB_ENV"
- name: Upload to Gitea release
if: startsWith(github.ref, 'refs/tags/v')
run: |
VERSION="${{ steps.version.outputs.version }}"
GITEA_URL="${{ github.server_url }}"
REPO="${{ github.repository }}"
# Create release
curl -sf -X POST "${GITEA_URL}/api/v1/repos/${REPO}/releases" \
-H "Authorization: token ${{ secrets.REGISTRY_PASSWORD }}" \
-H "Content-Type: application/json" \
-d "{\"tag_name\": \"v${VERSION}\", \"name\": \"Ti-Pote v${VERSION}\", \"body\": \"SD image for Raspberry Pi Zero 2W\"}" \
-o /tmp/release.json
RELEASE_ID=$(jq -r '.id' /tmp/release.json)
echo "Release ID: $RELEASE_ID"
# Upload image as attachment
curl -sf -X POST "${GITEA_URL}/api/v1/repos/${REPO}/releases/${RELEASE_ID}/assets?name=${IMAGE_FILE}" \
-H "Authorization: token ${{ secrets.REGISTRY_PASSWORD }}" \
-F "attachment=@output/${IMAGE_FILE}" \
-o /tmp/asset.json
echo "Download URL: $(jq -r '.browser_download_url' /tmp/asset.json)"
- name: Summary (dev builds)
if: ${{ !startsWith(github.ref, 'refs/tags/v') }}
run: |
echo "=== SD Image built successfully ==="
echo "File: output/${IMAGE_FILE}"
ls -lh output/
echo ""
echo "To create a release, push a tag: git tag v0.1.0 && git push origin v0.1.0"