Weekly Auto Build FAP for Release and Dev Channels #6
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Weekly Auto Build FAP for Release and Dev Channels | |
on: | |
schedule: | |
# Run every Sunday at 12:00 UTC | |
- cron: '0 12 * * 0' | |
workflow_dispatch: | |
inputs: | |
force_build: | |
description: 'Force build for release and dev channels' | |
required: false | |
default: false | |
type: boolean | |
jobs: | |
build: | |
runs-on: ubuntu-latest | |
strategy: | |
fail-fast: false # Prevents one failing job from canceling others | |
matrix: | |
channel: | |
- release | |
- dev | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@v4 | |
- name: Set up Python | |
uses: actions/setup-python@v4 | |
with: | |
python-version: '3.11' | |
- name: Install ufbt | |
run: | | |
python -m pip install --upgrade pip | |
pip install ufbt | |
ufbt --version | |
- name: Setup ufbt | |
run: | | |
echo "Setting up ufbt for ${{ matrix.channel }} channel..." | |
ufbt update --channel ${{ matrix.channel }} || { | |
echo "::error::ufbt update failed for ${{ matrix.channel }} channel" | |
exit 1 | |
} | |
echo "ufbt status:" | |
ufbt status | |
- name: Get app name from source | |
id: app-info | |
run: | | |
# Try to extract app name from common patterns | |
if [ -f "application.fam" ]; then | |
APP_NAME=$(grep -E "name\s*=" application.fam | sed 's/.*name\s*=\s*"\([^"]*\)".*/\1/' | head -1) | |
elif ls *.c 2>/dev/null; then | |
# Look for app name in C files | |
APP_NAME=$(grep -r "\.name.*=" *.c | sed 's/.*\.name.*=.*"\([^"]*\)".*/\1/' | head -1) | |
fi | |
# Fallback to directory name | |
if [ -z "$APP_NAME" ]; then | |
APP_NAME=$(basename "$(pwd)") | |
fi | |
# Clean up name for filename | |
APP_NAME_CLEAN=$(echo "$APP_NAME" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/_/g') | |
echo "name=$APP_NAME" >> $GITHUB_OUTPUT | |
echo "clean_name=$APP_NAME_CLEAN" >> $GITHUB_OUTPUT | |
- name: Build FAP | |
run: | | |
echo "Building FAP for ${{ matrix.channel }} channel..." | |
ufbt build || { | |
echo "::error::Build failed for ${{ matrix.channel }} channel" | |
ufbt status | |
ls -la | |
cat application.fam 2>/dev/null || echo "No application.fam found" | |
exit 1 | |
} | |
- name: Get current timestamp | |
id: timestamp | |
run: | | |
TIMESTAMP=$(date -u +%Y%m%d_%H%M%S) | |
echo "timestamp=$TIMESTAMP" >> $GITHUB_OUTPUT | |
- name: Find and rename FAP | |
id: fap-info | |
run: | | |
FAP_FILE=$(find . -name "*.fap" -path "*/dist/*" | head -1) | |
if [ -z "$FAP_FILE" ]; then | |
echo "::error::No FAP file found for ${{ matrix.channel }} channel" | |
exit 1 | |
fi | |
NEW_NAME="${{ steps.app-info.outputs.clean_name }}-${{ matrix.channel }}-${{ steps.timestamp.outputs.timestamp }}.fap" | |
cp "$FAP_FILE" "$NEW_NAME" | |
echo "filename=$NEW_NAME" >> $GITHUB_OUTPUT | |
- name: Upload artifact | |
uses: actions/upload-artifact@v4 | |
with: | |
name: ${{ matrix.channel }}-${{ steps.timestamp.outputs.timestamp }} | |
path: ${{ steps.fap-info.outputs.filename }} | |
create-releases: | |
needs: build | |
runs-on: ubuntu-latest | |
strategy: | |
fail-fast: false | |
matrix: | |
channel: | |
- release | |
- dev | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@v4 | |
- name: Get current timestamp | |
id: timestamp | |
run: | | |
TIMESTAMP=$(date -u +%Y%m%d_%H%M%S) | |
echo "timestamp=$TIMESTAMP" >> $GITHUB_OUTPUT | |
- name: Download artifact | |
uses: actions/download-artifact@v4 | |
with: | |
name: ${{ matrix.channel }}-${{ steps.timestamp.outputs.timestamp }} | |
path: ./release-files | |
- name: Get app info | |
id: app-info | |
run: | | |
if [ -f "application.fam" ]; then | |
APP_NAME=$(grep -E "name\s*=" application.fam | sed 's/.*name\s*=\s*"\([^"]*\)".*/\1/' | head -1) | |
else | |
APP_NAME=$(basename "$(pwd)") | |
fi | |
echo "name=$APP_NAME" >> $GITHUB_OUTPUT | |
- name: Create Release | |
uses: softprops/action-gh-release@v1 | |
with: | |
tag_name: ${{ matrix.channel }}-${{ steps.timestamp.outputs.timestamp }} | |
name: ${{ steps.app-info.outputs.name }} for ${{ matrix.channel }} (${{ steps.timestamp.outputs.timestamp }}) | |
files: ./release-files/*.fap | |
body: | | |
## ${{ steps.app-info.outputs.name }} | |
**Built for:** ${{ matrix.channel }} channel (compatible with official, momentum, unleashed firmwares) | |
This FAP was automatically built on ${{ steps.timestamp.outputs.timestamp }}. | |
**Installation:** | |
1. Download the .fap file | |
2. Copy to your Flipper Zero's `apps` folder | |
3. The app will appear in your applications menu | |
**Firmware Compatibility:** | |
- ✅ Official, Momentum, Unleashed firmwares (${{ matrix.channel }} channel, latest at build time) | |
- ❌ Other channels (use the appropriate release) | |
**Channel Info:** | |
- **Release**: Stable, tested firmware | |
- **Dev**: Latest features, may be unstable | |
draft: false | |
prerelease: ${{ matrix.channel == 'dev' }} | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
cleanup-old-releases: | |
needs: [build, create-releases] | |
runs-on: ubuntu-latest | |
steps: | |
- name: Cleanup releases older than 10 weeks | |
run: | | |
# Calculate the cutoff date (70 days ago) | |
CUTOFF_DATE=$(date -u -d "70 days ago" +%s) | |
echo "Cutoff timestamp: $CUTOFF_DATE" | |
# Fetch all releases | |
RELEASES=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ | |
https://api.github.com/repos/${{ github.repository }}/releases) | |
# Filter releases older than 70 days | |
OLD_RELEASES=$(echo "$RELEASES" | jq -r --argjson cutoff "$CUTOFF_DATE" \ | |
'.[] | select((.created_at | sub("\\.[0-9]+Z$"; "Z") | fromdateiso8601) < $cutoff) | .id') | |
for release_id in $OLD_RELEASES; do | |
echo "Deleting old release: $release_id" | |
curl -X DELETE -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ | |
"https://api.github.com/repos/${{ github.repository }}/releases/$release_id" | |
done |