Skip to content
This repository was archived by the owner on Feb 24, 2025. It is now read-only.

Commit

Permalink
iOS release flow automation (#3818)
Browse files Browse the repository at this point in the history
<!--
Note: This checklist is a reminder of our shared engineering
expectations. Feel free to change it, although assigning a GitHub
reviewer and the items in bold are required.

⚠️ If you're an external contributor, please file an issue first before
working on a PR, as we can't guarantee that we will accept your changes
if they haven't been discussed ahead of time. Thanks!
-->

Task/Issue URL:
https://app.asana.com/0/1205419239275955/1208056445209269/f
Tech Design URL:
CC:

**Description**:
Initial automation sharing for iOS release flow based on macOS release
flow.

- [x] Set schedule for release bump
- [x] Bump fastlane plugin
- [x] Align build number before merging. 

<!--
If at any point it isn't actively being worked on/ready for
review/otherwise moving forward strongly consider closing it (or not
opening it in the first place). If you decide not to close it, use Draft
PR while work is still in progress or use `DO NOT MERGE` label to
clarify the PRs state and comment with more information.
-->

**Steps to test this PR**:
1. Run a release flow
2. [Alpha build to test version and buildnumber
config](https://github.com/duckduckgo/iOS/actions/runs/12824908763)

<!--
Before submitting a PR, please ensure you have tested the combinations
you expect the reviewer to test, then delete configurations you *know*
do not need explicit testing.

Using a simulator where a physical device is unavailable is acceptable.
-->

**Definition of Done (Internal Only)**:

* [ ] Does this PR satisfy our [Definition of
Done](https://app.asana.com/0/1202500774821704/1207634633537039/f)?

**Copy Testing**:

* [ ] Use of correct apostrophes in new copy, ie `’` rather than `'`

**Orientation Testing**:

* [ ] Portrait
* [ ] Landscape

**Device Testing**:

* [ ] iPhone SE (1st Gen)
* [ ] iPhone 8
* [ ] iPhone X
* [ ] iPhone 14 Pro
* [ ] iPad

**OS Testing**:

* [ ] iOS 15
* [ ] iOS 16
* [ ] iOS 17

**Theme Testing**:

* [ ] Light theme
* [ ] Dark theme

---
###### Internal references:
[Software Engineering
Expectations](https://app.asana.com/0/59792373528535/199064865822552)
[Technical Design
Template](https://app.asana.com/0/59792373528535/184709971311943)

---------

Co-authored-by: Dominik Kapusta <[email protected]>
  • Loading branch information
kshann and ayoy authored Jan 20, 2025
1 parent 6bbc364 commit f356843
Show file tree
Hide file tree
Showing 16 changed files with 783 additions and 88 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ios-alpha.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,9 @@ jobs:
MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
run: |
app_version="$(cut -d ' ' -f 3 < Configuration/Version.xcconfig)"
build_version="$(cut -d ' ' -f 3 < Configuration/BuildNumber.xcconfig)"
bundle exec fastlane increment_build_number_for_version version:$app_version app_identifier:"com.duckduckgo.mobile.ios.alpha"
bundle exec fastlane release_alpha groups:["${{ env.destination }}"]
build_version="$(xcodebuild -configuration Alpha -showBuildSettings | grep CURRENT_PROJECT_VERSION | tr -d 'CURRENT_PROJECT_VERSION =')"
echo "dsyms_path=${{ github.workspace }}/DuckDuckGo-Alpha.app.dSYM.zip" >> $GITHUB_ENV
echo "app_version=${app_version}" >> $GITHUB_ENV
echo "build_version=${build_version}" >> $GITHUB_ENV
Expand Down
143 changes: 143 additions & 0 deletions .github/workflows/ios-bump-internal-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
name: iOS - Bump Internal Release

on:
schedule:
- cron: '0 5 * * 2-5' # Run at 05:00 UTC, Tuesday through Friday
workflow_dispatch:
inputs:
asana-task-url:
description: "Asana release task URL"
required: false
type: string
base-branch:
description: "Base branch (defaults to main, only override for testing)"
required: false
type: string

jobs:

validate_input_conditions:

name: Validate Input Conditions
runs-on: macos-15
timeout-minutes: 10

outputs:
skip-release: ${{ steps.prepare-release-bump.outputs.skip_release }}
asana-task-id: ${{ steps.prepare-release-bump.outputs.release_task_id }}
asana-task-url: ${{ steps.prepare-release-bump.outputs.release_task_url }}
release-branch: ${{ steps.prepare-release-bump.outputs.release_branch }}

steps:

- name: Assert release branch
run: |
case "${{ github.ref_name }}" in
*release/*) ;;
*main) ;;
*) echo "👎 Not a release or main branch"; exit 1 ;;
esac
- name: Check out the code
uses: actions/checkout@v4

- name: Set up fastlane
run: bundle install

- name: Prepare release bump
id: prepare-release-bump
env:
ASANA_ACCESS_TOKEN: ${{ secrets.ASANA_ACCESS_TOKEN }}
GITHUB_TOKEN: ${{ github.token }}
run: |
bundle exec fastlane run validate_internal_release_bump \
platform:"ios" \
is_scheduled_release:"${{ github.event_name == 'schedule' }}" \
release_task_url:"${{ inputs.asana-task-url }}"
run_tests:

name: Run Tests

needs: validate_input_conditions

if: needs.validate_input_conditions.outputs.skip-release != 'true'
uses: ./.github/workflows/ios-pr-checks.yml
with:
branch: ${{ needs.validate_input_conditions.outputs.release-branch }}
secrets:
APPLE_API_KEY_BASE64: ${{ secrets.APPLE_API_KEY_BASE64 }}
APPLE_API_KEY_ID: ${{ secrets.APPLE_API_KEY_ID }}
APPLE_API_KEY_ISSUER: ${{ secrets.APPLE_API_KEY_ISSUER }}
ASANA_ACCESS_TOKEN: ${{ secrets.ASANA_ACCESS_TOKEN }}
MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
SSH_PRIVATE_KEY_FASTLANE_MATCH: ${{ secrets.SSH_PRIVATE_KEY_FASTLANE_MATCH }}

increment_build_number:

name: Increment Build Number
needs: [ validate_input_conditions, run_tests ]
runs-on: macos-15-xlarge
timeout-minutes: 10

steps:

- name: Check out the code
uses: actions/checkout@v4
with:
fetch-depth: 0 # Fetch all history and tags in order to extract Asana task URLs from git log
ref: ${{ needs.validate_input_conditions.outputs.release-branch }}
submodules: recursive

- name: Set up fastlane
run: bundle install

- name: Select Xcode
run: sudo xcode-select -s /Applications/Xcode_$(<.xcode-version).app/Contents/Developer

- name: Increment build number
env:
APPLE_API_KEY_BASE64: ${{ secrets.APPLE_API_KEY_BASE64 }}
APPLE_API_KEY_ID: ${{ secrets.APPLE_API_KEY_ID }}
APPLE_API_KEY_ISSUER: ${{ secrets.APPLE_API_KEY_ISSUER }}
ASANA_ACCESS_TOKEN: ${{ secrets.ASANA_ACCESS_TOKEN }}
GITHUB_TOKEN: ${{ github.token }}
run: |
bundle exec fastlane run bump_build_number platform:ios
bundle exec fastlane run update_asana_for_release \
platform:ios \
release_type:internal \
release_task_id:"${{ needs.validate_input_conditions.outputs.asana-task-id }}" \
target_section_id:"${{ vars.IOS_APP_BOARD_VALIDATION_SECTION_ID }}"
prepare_release:
name: Prepare Release
needs: [ validate_input_conditions, increment_build_number ]
uses: ./.github/workflows/ios-release.yml
with:
asana-task-url: ${{ needs.validate_input_conditions.outputs.asana-task-url }}
branch: ${{ needs.validate_input_conditions.outputs.release-branch }}
secrets:
APPLE_API_KEY_BASE64: ${{ secrets.APPLE_API_KEY_BASE64 }}
APPLE_API_KEY_ID: ${{ secrets.APPLE_API_KEY_ID }}
APPLE_API_KEY_ISSUER: ${{ secrets.APPLE_API_KEY_ISSUER }}
ASANA_ACCESS_TOKEN: ${{ secrets.ASANA_ACCESS_TOKEN }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
MM_WEBHOOK_URL: ${{ secrets.MM_WEBHOOK_URL }}
SSH_PRIVATE_KEY_FASTLANE_MATCH: ${{ secrets.SSH_PRIVATE_KEY_FASTLANE_MATCH }}

tag_and_merge:
name: Tag and Merge Branch
needs: [ validate_input_conditions, prepare_release ]
uses: ./.github/workflows/ios-tag-release-update-asana.yml
with:
asana-task-url: ${{ needs.validate_input_conditions.outputs.asana-task-url }}
branch: ${{ needs.validate_input_conditions.outputs.release-branch }}
base-branch: ${{ github.event.inputs.base-branch || 'main' }}
internal-release-bump: true
release-type: internal
secrets:
ASANA_ACCESS_TOKEN: ${{ secrets.ASANA_ACCESS_TOKEN }}
GHA_ELEVATED_PERMISSIONS_TOKEN: ${{ secrets.GHA_ELEVATED_PERMISSIONS_TOKEN }}
98 changes: 98 additions & 0 deletions .github/workflows/ios-code-freeze.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
name: iOS - Code Freeze

on:
workflow_dispatch:
inputs:
version:
description: "New release version (calculated automatically if not provided)"
required: false
type: string


jobs:

create_release_branch:

name: Create Release Branch

runs-on: macos-15-xlarge
timeout-minutes: 10

outputs:
release_branch_name: ${{ steps.make_release_branch.outputs.release_branch_name }}
asana_task_url: ${{ steps.make_release_branch.outputs.asana_task_url }}

steps:

- name: Assert main branch
run: |
if [ "${{ github.ref_name }}" != "main" ]; then
echo "👎 Not the main branch"
exit 1
fi
- name: Check out the code
uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: recursive

- name: Prepare fastlane
run: bundle install

- name: Make release branch
id: make_release_branch
env:
ASANA_ACCESS_TOKEN: ${{ secrets.ASANA_ACCESS_TOKEN }}
GITHUB_TOKEN: ${{ github.token }}
run: |
bundle exec fastlane run start_new_release \
platform:"ios" \
version:"${{ inputs.version }}" \
github_handle:"${{ github.actor }}" \
target_section_id:"${{ vars.IOS_APP_BOARD_VALIDATION_SECTION_ID }}"
run_tests:
name: Run Tests

needs: create_release_branch
uses: ./.github/workflows/ios-pr-checks.yml
with:
branch: ${{ needs.create_release_branch.outputs.release_branch_name }}
secrets:
APPLE_API_KEY_BASE64: ${{ secrets.APPLE_API_KEY_BASE64 }}
APPLE_API_KEY_ID: ${{ secrets.APPLE_API_KEY_ID }}
APPLE_API_KEY_ISSUER: ${{ secrets.APPLE_API_KEY_ISSUER }}
ASANA_ACCESS_TOKEN: ${{ secrets.ASANA_ACCESS_TOKEN }}
MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
SSH_PRIVATE_KEY_FASTLANE_MATCH: ${{ secrets.SSH_PRIVATE_KEY_FASTLANE_MATCH }}

prepare_release:
name: Prepare Release
needs: [ create_release_branch, run_tests ]
uses: ./.github/workflows/ios-release.yml
with:
asana-task-url: ${{ needs.create_release_branch.outputs.asana_task_url }}
branch: ${{ needs.create_release_branch.outputs.release_branch_name }}
secrets:
APPLE_API_KEY_BASE64: ${{ secrets.APPLE_API_KEY_BASE64 }}
APPLE_API_KEY_ID: ${{ secrets.APPLE_API_KEY_ID }}
APPLE_API_KEY_ISSUER: ${{ secrets.APPLE_API_KEY_ISSUER }}
ASANA_ACCESS_TOKEN: ${{ secrets.ASANA_ACCESS_TOKEN }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
MM_WEBHOOK_URL: ${{ secrets.MM_WEBHOOK_URL }}
SSH_PRIVATE_KEY_FASTLANE_MATCH: ${{ secrets.SSH_PRIVATE_KEY_FASTLANE_MATCH }}

tag_and_merge:
name: Tag and Merge Branch
needs: [ create_release_branch, prepare_release ]
uses: ./.github/workflows/ios-tag-release-update-asana.yml
with:
asana-task-url: ${{ needs.create_release_branch.outputs.asana_task_url }}
branch: ${{ needs.create_release_branch.outputs.release_branch_name }}
release-type: internal
secrets:
ASANA_ACCESS_TOKEN: ${{ secrets.ASANA_ACCESS_TOKEN }}
GHA_ELEVATED_PERMISSIONS_TOKEN: ${{ secrets.GHA_ELEVATED_PERMISSIONS_TOKEN }}
23 changes: 21 additions & 2 deletions .github/workflows/ios-pr-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,25 @@ on:
push:
branches: [ main, "release/**" ]
pull_request:
workflow_call:
inputs:
branch:
description: "Branch name"
required: false
type: string
secrets:
APPLE_API_KEY_BASE64:
required: true
APPLE_API_KEY_ID:
required: true
APPLE_API_KEY_ISSUER:
required: true
ASANA_ACCESS_TOKEN:
required: true
MATCH_PASSWORD:
required: true
SSH_PRIVATE_KEY_FASTLANE_MATCH:
required: true

jobs:
swiftlint:
Expand Down Expand Up @@ -129,8 +148,8 @@ jobs:

name: Make Release Build

# Dependabot doesn't have access to all secrets, so we skip this job
if: github.actor != 'dependabot[bot]'
# Dependabot doesn't have access to all secrets, so we skip this job, also skip for nightly release bump
if: github.actor != 'dependabot[bot]' && github.event_name != 'workflow_call'

runs-on: macos-15
timeout-minutes: 30
Expand Down
Loading

0 comments on commit f356843

Please sign in to comment.