Custom Github Action for Firebase App Distribution

  • Scope:
  • Mobile Development

…because sooner or later you’ll hve to migrate from Fabric.io

In this episode of “Cool Tooploox blogposts” I’ll focus on integrating two new services, both in beta at the time of writing this post: Github Actions and Firebase App Distribution.

Action type

Before starting to write Action, you have to decide which approach you will take. On Github you can use either Docker or Javascript. Docker action runs in its container and executes actions in it while JavaScript runs directly in the Github-hosted environment. 

For Firebase App Distribution Action we’ll choose Docker, to gain independence from the main container. What do I mean by this?

Let’s imagine having a few different scripts running during your workflow, each one needing a different version of Node.js. You would have to:

  • manually change version just before running script using tools like n or nvm 
  • maintain the correct version of Node.js if the plugin decides to use a different one in its next version
  • keep in mind that by adding Action directly to the main container we modify the build environment and allow it to have access to repository files (which might be security breach). We should maintain our CI/CD as isolated and as safe as possible.

I believe that a better approach is to make all plugins completely independent and self-sufficient.

action.yml as a manifesto

  • inputs are definitions of values that can be passed to the Action. They can be marked as required or not. In the second case, we can specify an optional value with default:
  • runs defines what kind of Action it is. As we’ve already decided, we’ll use DockerDocker needs Docker image, used to run its instance. We can get readymade one from DockerHub, but in this article, we’ll create our own. The configuration file, named Dockerfile, will be stored directly in Action’s repository.

Docker image

Having our manifesto defined, we’ll create Dockerfile which will configure our container with needed dependencies. To send our .apk or .ipa files to Firebase Console, we’ll use Firebase Command Line Interface, therefore we have to first fulfill the requirement of having Node.js v8.0.0 or later. 

To create our Docker image we’ll use parent image with preinstalled Alpine Linux and Node v12.10.0. I strongly recommend using Alpine Linux. This lightweight distribution (5MB only) will save you precious build times. We do this using FROM instruction.

Following best practices for writing Dockerfiles we’ll create WORKDIR and copy all files from the repository to it. Then we’ll install firebase-tool setup permissions and we’re good to go with our entrypoint.sh script!

entrypoint.sh as a 🙂

entrypoint.sh script is executed just after Docker container initialization. Inputs, defined in action.yml, are passed to entrypoint.sh script as variables in a format $INPUT_<name>. The logic here for MESSAGE is to include the last commit’s hash and message when a consumer of this Action won’t provide any message. Lastly, we’ll execute firebase appdistibution:distribute with parameters, accordingly to documentation.

Test

Having in mind that “if it is not tested, it doesn’t work” we’ll introduce a test for our plugin before integrating this into target workflow. What we’ll do is create Github Action Workflow directly in plugins directory: .github/workflows/main.yml:

To save space on our repository (so users of action won’t have to download unnecessary files) we won’t include any Android/iOS project but we’ll download ready .apk from the appium repository. Sensitive data, such as Firebase App Id or Firebase Token will be stored as secrets. To learn more about keeping environmental variables in secrets on Github Actions, read this documentation.

Thanks for reading this. You can check out the repository that contains all the files described in this article. I hope this was helpful for you and good luck with creating your own actions! ✊ 

We would be happy to read your thoughts about Github Actions, Firebase App Distribution, and their integration down below.