Publishing to F-Droid with Fastlane and Flavors
How I did it... How you can, too!
One of the first questions I received when I announced that I had published a new open-source app on the Google Play Store was "How do I know that your code in GitHub is the same code that created this app in Google Play?".
At first, I thought this question was somewhat ridiculous. Would someone publish code that is different than the code in their repository? Unfortunately, some bad actors engage in this behavior quite regularly. This is where F-Droid is especially helpful.
F-Droid is an installable catalogue of FOSS (Free and Open Source Software) applications for the Android platform.
F-Droid is a truly remarkable tool for several reasons beyond the catalog of apps:
A trusted CI build process that builds your application directly from the source.
Advanced scanning of apps for any libraries or plugins that are not FOSS.
Simple setup for automated version updates
Detailed application permissions, history of build versions (easy rollback to different versions), issue tracker, license details, and more.
The first step in publishing to F-Droid is preparing your repository. There are a few different ways to go about this, but I used the recommended process using a tool called Fastlane.
To configure your repository for Fastlane, follow the directions outlined in this snippet.
For a real-world example, see the repository for my app here.
Evaluate your dependencies (optional)
When I first attempted to publish to F-Droid, I experienced several pipeline issues. After reading through the pipeline logs in GitLab, I realized that my application's database (ObjectBox) was not entirely FOSS compliant and was causing build failures. The following day was spent migrating my app to Room.
This is a cautionary step to help save you some headaches and disappointment. Ensuring all application dependencies comply with FOSS standards is worth the time investment.
Build Flavors (optional)
This step is optional; however, I found it beneficial to create a specific flavor of my application for F-Droid. Being a solo developer and having limited time and testing capabilities, Firebase Crashlytics has been an invaluable tool in helping me recognize and diagnose issues my application is having in the wild. However, using Firebase in an F-Droid application is (obviously) not permitted.
So I didn't have to remove Firebase from my application, I created two different build variants. One for F-Droid, which excluded my Firebase dependencies, and the other for my general releases that included these dependencies. How I configured these flavors can be seen in my repository in the project build.gradle.kts and app/build.gradle.kts files. I don't want to belabor this point too much (as it perhaps deserves a dedicated blog post), but I thought it was worth mentioning.
Creating your metadata file
To submit your app to F-Droid, you must complete a merge request to their repository in GitLab that includes the metadata for your application.
Here are the steps:
Create an account or sign in to GitLab here.
Fork this repository.
Create a new branch on your fork.
Navigate to the /metadata directory.
Create a new file here called <your-applicationId>.yml as found in your app build.gradle file (you can add this file via GitLab's GUI or locally).
See F-Droid's contributing doc for more details. Templates for the contents of this file can be found here. Additional details on each metadata field's meaning and use can be found on their metadata reference page here. Here is what my metadata file looked like:
Things to note about my metadata file:
At the time of writing, I believe F-Droid's build image only had JDK 8 installed. If your app uses a higher version of Java like mine, you will need the "sudo" field to install a version of Java that matches your project.
The "prebuild" field and the "gradle" are necessary if you take the flavor approach. It is not enough to F-Droid that your build won't include the non-FOSS dependencies. All traces of these dependencies need to be removed from your Gradle files. This can be accomplished with the "prebuild" script. Additionally, for the "gradle" field, you specify the name of your flavor ("fdroid" in my case), or if you are not using flavors, you just set "yes" as the flavor.
The "commit" field would be your latest commit and the version codes to match throughout the file.
There are several ways you can configure auto-updating of your app (GitLab will check your repository for new versions automatically); I chose to do auto-update by GitHub release tags. Whenever I push a new build, I create a new release and tag it appropriately. You can ignore the regex after the word "Tags" in my "UpdateCheckMode" field.
Validate the CI pipeline
Pushing the committed metadata file to your branch will cause the CI pipeline to run automatically. You will then navigate to your forked repository in GitLab and select the "CI/CD Configuration" button. From here, you will switch to your branch and see the pipeline running for your recent commit.
Validate that all of the jobs pass before submitting your merge request. If jobs are failing, look through the logs to find the problem. Hopefully, you were able to avoid some of the issues I ran into and come away with all of the jobs completed successfully.
Once everything is green, use the "Create merge request" button on your forked repository to submit your merge request.
Complete the merge request
Once you elect to merge your changes, you will be directed to a merge request page where you will select the "app inclusion" template for your merge. Fill out each field with an "X" that applies and submit the request.
Validate the CI merge pipeline
Once you submit the merge request, another pipeline will run for the merge request. This pipeline is slightly different than the previous one. Therefore, new issues could arise. You will want to navigate to the "Merge requests" tab on the primary F-Droid repository here and find your merge request. Fix any issues that arise with the pipeline. If you get stuck, someone from the F-Droid team will engage with you in the merge request and help you resolve the issue (that was my experience). Eventually, your request should be merged.
Relax and wait
Once the merge is complete, it is just a waiting game so sit back, relax, and grab another coffee. It took roughly one week after I merged my request for the app to be live in the F-Droid catalog, but this all depends on where your merge lands in the build cycle. You can monitor the action here. The particular pipelines that you will want to watch are the f-droid build and the f-droid deploy (sequentially). You should first see your app in the f-droid build pipeline under "Successful builds" and then once the f-droid deploy pipeline runs you should be live! Congrats!