This documentation is available as Markdown for AI agents and LLMs. See the full Markdown index or append .md to any documentation URL.
Using Git tags to trigger production deployments
Edit page
Learn how to trigger production deployments from Git tags on EAS Workflows.
Pushing to a release branch runs the production workflow on every commit, even ones we never meant as a release.
Learning outcomes
- Switch the production workflow trigger from a
release/*branch to a Git tag matchingv*.*.* - Cut a release by pushing a tag from
mainand watch the workflow run on the EAS dashboard - Exclude pre-release tags like
v1.0.0-rc.1from production and run release candidates in a separate workflow
Tags as release events
EAS Workflows supports tag-based triggers through on.push with a tags list. The workflow runs only when a tag matching a glob pattern is pushed to the remote. A Git tag is a one-time event tied to a specific commit and version, unlike a branch that can be updated over time. That makes tags well-suited for marking releases.
A tag-based release workflow fits teams that:
- Want the version number in Git to match the version they ship to app users
- Release from
maindirectly rather than maintaining long-lived release branches - Want a clear audit trail of every release commit by version
Switch production.yml to a tag trigger
Open the .eas/workflows/production.yml workflow from the previous chapter and replace the on.push.branches trigger with on.push.tags. Everything else inside the workflow stays the same.
1
Change the trigger
Replace the branches trigger with a tags trigger. The tags glob matches tags like v1.0.0, v2.3.7, and v10.0.0-beta.1.
name: Deploy to production on: push: tags: ['v*.*.*'] jobs: fingerprint: name: Fingerprint type: fingerprint environment: production get_android_build: name: Check for existing Android build needs: [fingerprint] type: get-build params: fingerprint_hash: ${{ needs.fingerprint.outputs.android_fingerprint_hash }} profile: production get_ios_build: name: Check for existing iOS build needs: [fingerprint] type: get-build params: fingerprint_hash: ${{ needs.fingerprint.outputs.ios_fingerprint_hash }} profile: production build_android: name: Build Android needs: [get_android_build] if: ${{ !needs.get_android_build.outputs.build_id }} type: build params: platform: android profile: production build_ios: name: Build iOS needs: [get_ios_build] if: ${{ !needs.get_ios_build.outputs.build_id }} type: build params: platform: ios profile: production update_android: name: Publish Android update needs: [get_android_build] if: ${{ needs.get_android_build.outputs.build_id }} type: update params: branch: production platform: android update_ios: name: Publish iOS update needs: [get_ios_build] if: ${{ needs.get_ios_build.outputs.build_id }} type: update params: branch: production platform: ios
For tags to trigger the workflow, we need to pick a pattern that matches our team's flow. Common patterns include:
['v*']matches any tag that starts withv['v*.*.*']matches strict three-part semantic versions (recommended)
We don't need to change any other jobs. The fingerprint, get-build, build, and update jobs work identically because they operate on the commit.
2
Commit and push the workflow change
Commit the change to production.yml and push it to main. This doesn't trigger the workflow because we switched from a branch trigger to a tag trigger.
- git add .eas/workflows/production.yml- git commit -m "Switch production workflow to tag trigger"- git push origin main3
Create a tag to test the workflow
To run the workflow, we need to push a tag that matches the glob pattern defined in production.yml.
Make a TypeScript/JavaScript change in our example project, commit it, and push a new tag:
- git add .- git commit -m "Fix welcome copy"- git tag v0.1.0- git push origin main --tagsThe workflow triggers on the v0.1.0 tag. Open the EAS dashboard, and under Workflows, notice "Deploy to production" running with refs/tags/v0.1.0 as its branch:
Since this is the first production run with the fingerprint generated for a tag-based release, the build jobs run for both Android and iOS. Subsequent tags that point to TypeScript/JavaScript changes skip the build jobs and go straight to update jobs.
Pre-release tags for release candidates
The v*.*.* glob also matches pre-release tags like v1.0.0-rc.1, which would ship a release candidate to app users. To keep release candidates out of production, exclude them from the production workflow's trigger:
on: push: tags: ['v*.*.*', '!v*.*.*-rc.*']
To exercise a release candidate before the real release, create a separate workflow that matches only pre-release tags (tags: ['v*.*.*-rc.*']) and reuses the fingerprint, get-build, and build jobs without the update and submit jobs. The same pipeline runs, and nothing reaches app users.
Summary
Chapter 6: Tag-based releases
We switched the production workflow trigger from a release branch to a Git tag, tested the change by pushing a versioned tag from main, and learned how to gate release candidates with a pre-release tag glob.
In the next chapter, learn how to deploy web builds to EAS Hosting from a workflow.