Skip to content

Instantly share code, notes, and snippets.

@Th3Un1q3
Last active October 10, 2024 01:20
Show Gist options
  • Save Th3Un1q3/233fa6900d13caa95c6383e53a92bed1 to your computer and use it in GitHub Desktop.
Save Th3Un1q3/233fa6900d13caa95c6383e53a92bed1 to your computer and use it in GitHub Desktop.
The Hitchhiker's Guide to the Flipper Releasing

The Hitchhiker's Guide to the Flipper Releasing 📕

The purpose of this document is to simplify development for Flipper Zero platform.

It's my cure from oh, great, now I have to rebuild my app. Again...

DON'T PANIC!

As by the time of this document is published all the Flipper applications should be built for the specific API so that API version provided by the firmware is matching one used during the application building. It is promised that this limitation may be gone along with official firmware 1.0.0 is released. Until it happened, best option for developers is to have a framework that automates dependency tracking and releasing routines.

Track Firmware Updates

Define Dependencies

As build of the application should take place within firmware environment, it makes sense to explicitly define firmwares as application dependencies.

Start form making firmwares you need to be your Git Submodules.

# Add official firmware as a submodule to your app.
# Check out submodules documentation if you need to configure branch other than default(https://git-scm.com/book/en/v2/Git-Tools-Submodules)
git submodule add https://github.com/flipperdevices/flipperzero-firmware.git .standard-firmware

# ... Add all other firmwares here

# Update or re-init submodules(after clonning)
# Will take latest commit from tracked branch
git submodule update --init --recursive

Configure Tracking

And now when all dependencies are defined it's time to utilise tracking system. I suggest dependabot. Create a file .github/dependabot.yml. There goes my sample config:

version: 2
updates:
  - package-ecosystem: "gitsubmodule" # Track official and unleashed firmware as a submodule
    directory: "/"
    schedule:
      interval: "daily"

Once this config is pushed to the main branch it will catch up all submodules defined in .gitmodules and initiate a PR once update happened on either of dependencies. Tune dependabot.yml up to your needs. Additionally you may configure your repo to notify you on dependabot opens a PR.

Build for Multiple Target Firmwares

There are several popular firmwares for flipper. There is no gurantee that app build for one will work for another, even if API version matches. That's why I decided to design build procedure the way my project is as much firmware agnostic as possible.

Let's go through build sequence I offer to create and execute following build script build.sh:

#!/bin/bash

# Define your application name, application sources should be placed in the directory with the same name, and manifest file should also declare the same name.
application_name="flipp_pomodoro"

# Set default build mode(should match target firmware submodule prefix)
build_mode="standard"

# Create artifacts destination directory
mkdir dist

# Fetch all firmwares(dependencies) submodules
git submodule update --init --recursive

# Mount into firmware root directory as it's required for fbt utility to work correctly
cd .$build_mode-firmware

# Extract API version
api_version=$(awk -F',' 'NR == 2 {print $3}' firmware/targets/f7/api_symbols.csv);

# Define suffix to easly find artifact
app_suffix="${build_mode}_${api_version}"

# Make fbt ignore git sync while running, because sync happened above
export FBT_NO_SYNC=1

# Clean up source and destination directories so that builds don't impact one another
rm -rf applications_user/$application_name
rm -rf build/f7-firmware-D/.extapps

# Copy sources of the app into the firmware environment
cp -r ../$application_name/. applications_user/$application_name

# Build the application
./fbt "fap_${application_name}"

# Move resulting application artifact to the dist directory
cp "build/f7-firmware-D/.extapps/${application_name}.fap" "../dist/${application_name}_${app_suffix}.fap"

By changing application_name variable and build mode you may adjust your build prefferences.

Automate Publishing

Now when build procedure is defined we can move towards publishing.

Create .github/workflows/release.yml that will implement automated releasing.

Following code assumes that you have your build as a bash script with parameters:

name: Release
on:
  push:
    branches:
      - master

jobs:
  build:
    name: Bump and Release
    runs-on: ubuntu-latest
    steps:
      - name: Cancel Previous Runs
        uses: styfle/cancel-workflow-action@0.11.0
        with:
          access_token: ${{ github.token }}

      - uses: actions/checkout@v3

      - name: Build Application
        run: |
          bash tools/build.sh -f unleashed
          bash tools/build.sh

      - name: Bump Version and Push Tag
        id: tag_version
        uses: mathieudutour/github-tag-action@v6.1
        with:
          release_branches: master
          github_token: ${{ secrets.GITHUB_TOKEN }}


      - name: Create a GitHub Release
        uses: ncipollo/release-action@v1
        with:
          tag: ${{ steps.tag_version.outputs.new_tag }}
          name: ${{ steps.tag_version.outputs.new_tag }}
          body: ${{ steps.tag_version.outputs.changelog }} # Generated changelog
          artifacts: "dist/**" # directory with build artifacts

This automation will produce new version release for you every time you master branch is updated.

Release Content Sample image

Check out this project to see all of the above in action.

Find it useful? Share!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment