---
title: '@expo/fingerprint 🤝 GitHub Actions'
authors: Kudo Chien
published: February 20, 2024
categories: Product
tags: fingerprint, SDK 50, github actions
---

In a previous blog post, [Fingerprint your native runtime with @expo/fingerprint](https://expo.dev/blog/fingerprint-your-native-runtime), we introduced `@expo/fingerprint`, explained why we built it, and gave a quick explanation of how to use it. 

In this post, we’ll introduce GitHub Actions that we built to make it easier for you to start integrating `@expo/fingerprint` into your workflows.  


> Note: there is nothing GitHub- or EAS-specific about `@expo/fingerprint`, and you can refer to the source to figure out how to implement them for a CI provider of your choice. Additionally, `@expo/fingerprint` works in any React Native project.

## Identify changes in native code with fingerprint

You can use `expo-github-action/fingerprint` to look at the fingerprint for each pull request and see what’s different from the fingerprint on the main branch. At Expo, we’re already using it to label pull requests automatically, which makes it easier for reviewers to see if there are any changes to native code without diving deep into the details.

![Before the fingerprint changed.](https://cdn.sanity.io/images/9r24npb8/production/ba9844e59bef0f3010ff60af0fe9314d3ef2aaea-1202x96.png)

![After the fingerprint changed. ](https://cdn.sanity.io/images/9r24npb8/production/78e5a182ee40d37e2486d7ff79a5d88e8671e6c3-1138x104.png)

You can go deeper on `expo-github-action/fingerprint` [in this github page.](https://github.com/expo/expo-github-action/tree/main/fingerprint)

## Create new builds when the fingerprint changes

There is a new (experimental) GitHub action called: `expo-github-action/preview-build` . It builds on the action fingerprint action and takes it further by **automatically starting a new build** via [EAS Build](https://expo.dev/eas#build) if the fingerprint in a pull request has changed. Then it automatically comments on the pull request with a link to the build(s) when it's complete.

![Before the fingerprint changed (no new build required). ](https://cdn.sanity.io/images/9r24npb8/production/208c3f25b6867a15e778b3a56c5f8401b1b63175-1816x394.png)

![After the fingerprint changed a new build is automatically started.](https://cdn.sanity.io/images/9r24npb8/production/d8f09ac02ee1d06503de884f7cd786d02dacd0f6-1832x1280.png)

[Here is a GitHub link](https://github.com/expo/expo-github-action/tree/main/preview-build) if you want to learn more about `expo-github-action/preview-build`.

## An Engineering Diary: GitHub Actions as a SQLite Storage

In this section, I’ll share my experience integrating `@expo/fingerprint` with GitHub Actions. To determine if the fingerprint has changed on a pull request, we need a place to keep track of fingerprints across different Git references. My first thought was to use GitHub Actions Caches with SQLite as a simple database. This seemed like a great idea… until I ran into some major issues.

First, [GitHub Actions Caches are immutable](https://github.com/actions/toolkit/issues/505), meaning you can't change them once they're made. This means we can't update the database directly. We found a way around this by deleting the cache with GitHub's API before making any updates. This also explains why we need the ['actions' permission](https://github.com/expo/expo-github-action/blob/57dcabe749340c8c995ee0334cd7c547c35770d0/fingerprint/README.md?plain=1#L118-L119) to delete caches. However, the process of deleting and creating caches isn't foolproof and atomic. If many workflows are trying to save their data at the same time, they might overwrite each other. That's why we have to use the [**`concurrency` setting**](https://github.com/expo/expo-github-action/blob/57dcabe749340c8c995ee0334cd7c547c35770d0/fingerprint/README.md?plain=1#L113-L114) to make sure only one workflow run is saving data at a time.

Second, [GitHub Actions Caches are scoped to individual branches](https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#restrictions-for-accessing-a-cache), meaning a cache entry created in a pull request is different from one created on the main branch, even if their keys are identical. We solved this by updating the database cache only when a pull request is merged back into the main branch, which is why the [`push main` branch event](https://github.com/expo/expo-github-action/blob/57dcabe749340c8c995ee0334cd7c547c35770d0/fingerprint/README.md?plain=1#L103-L106) is so important.

While there were several hurdles to using GitHub Actions Caches as a simple SQLite database storage, the good news is that **`@expo/fingerprint`** can be run on any GitHub Actions runner and on any project, without any external service dependencies.

## Give @expo/fingerprint a try and tell us what you think!

We’re excited about the potential of **`@expo/fingerprint`** to improve your workflows. We’re also eager to hear what you think about it. 

Your feedback will give us the confidence to bring **`@expo/fingerprint`** into more scenarios to help speed up the development process. Whether you [use the tool directly](https://expo.dev/blog/fingerprint-your-native-runtime) or via GitHub Actions, please share your thoughts. Let's make development faster together.