A weekly mobile release cadence, minus the busywork

Shipping a native mobile app every week is a lot of overhead for a small team: build and test the binary, upload it for beta testing, draft release notes, and create a tracking issue — every seven days. The GitHub Mobile team needed that process to be mostly hands-off so engineering time went into product work, not release mechanics. Their solution: a GitHub Actions workflow that automates all the repeatable steps, leaving humans only the tasks that genuinely need judgment.

A release candidate is considered ready when it meets a handful of criteria: a dedicated hot-fix branch exists, the build carries the correct version number and has been uploaded to TestFlight, all unit and snapshot tests pass, a release-tracking issue has been filed, and the release notes are drafted. The entire pipeline is orchestrated from a single YAML workflow file that kicks off four jobs in parallel. Most steps run automatically; the only manual work is writing user-facing release notes and merging the final changes.

Building and uploading the binary

The first job handles the core artifact. A new release branch is created for each version, so the team can later cherry-pick critical fixes without disturbing main. The jump-start comes from an open-source action, peterjgrainger/action-create-branch. After the branch exists, the workflow calls fastlane to run the test suite, archive the app, code-sign it, and push it to TestFlight.

Authentication and signing credentials live in GitHub Secrets, so the workflow can pass them to actions without ever exposing them in logs or to outside contributors.

One issue as an operating playbook

A second job creates a GitHub issue to track everything that must happen before the build reaches users. The issue body functions as a step-by-step release checklist: verify marketing copy, run pre-launch manual tests, post a status update to the team, and so on. Because the checklist is written down, a designated release captain doesn't need to have done it before, which makes onboarding new engineers into the release rotation much easier.

The team pulls the on-call release engineer from PagerDuty and assigns them to the issue. Shelling out to the GitHub CLI from the workflow is enough to create the issue — e.g., gh issue create -t {title} -b {body} -a {assignees} -l {labels} — and the action JamesIves/fetch-api-data-action is used to fetch the current PagerDuty on-call. An alternative to the CLI is the JasonEtco/create-an-issue action if you prefer templated issue bodies.

Release notes that read like a human wrote them

A third parallel job assembles the raw materials for release notes. Using fastlane, it pulls every commit and pull request merged since the previous release. That raw changelog is written to a text file in the repository, and the workflow opens a pull request for a human to rewrite it into something users would actually want to read. Being honest that machines can’t match human prose, the team reserves this for manual effort — but the material is already organized, so the writing takes minutes, not hours.

The release engineer is assigned to this PR, just like the tracking issue. Once a teammate reviews the composed notes, the PR is merged and the notes are stored for later reference. Pull-request creation uses the GitHub CLI — gh pr create -t {title} -b {body} -a {assignees}, -r {reviewers} -l {labels} — or the open-source peter-evans/create-pull-request action.

Keeping version numbers in lockstep

A fourth job increments the version number in main as soon as a release candidate is cut, so the next cycle starts fresh. Instead of committing straight to main, the workflow opens a pull request with version bumps made by small Bash and Ruby scripts. The PR is created using the same method as the release notes PR, which keeps main shielded from automatic but unreviewed changes.

The cadence: batch the work, ship weekly

All four jobs are described together in one workflow file. The workflow triggers every Saturday morning, which gives the release engineer a full Monday to complete the human steps: ticking off the issue checklist, sending the build to TestFlight, and submitting it for App Store review. During the beta week, the team monitors for crashes and regressions. If a critical issue surfaces, it gets fixed in main, cherry-picked into the release branch, and pushed — a separate workflow fires on each push to that branch and rebuilds/requeues the process.

If beta metrics look clean after a week, the build goes live on the App Store. That schedule is smooth enough in practice that the team has more time for feature development and less time waiting on Xcode builds.