Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Alfmob 33 implemented ci cd #7

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
58 changes: 58 additions & 0 deletions Alfie/.github/workflows/alfie.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
---
name: Alfie CI/CD

on:
push:
branches:
- main
- release/**
workflow_dispatch:

env:
IOS_DESTINATION: "platform=iOS Simulator,name=iPhone 14"
DEVELOPER_DIR: "/Applications/Xcode_16.app/Contents/Developer"

jobs:
branch-validation:
runs-on: macos-latest
steps:
- name: Checkout Code
uses: actions/checkout@v3

- name: Install Fastlane
run: gem install fastlane

- name: Run Linting, Analysis, and Tests
run: fastlane validate_branch
env:
IOS_DESTINATION: ${{ env.IOS_DESTINATION }}

testflight-build:
p4checo marked this conversation as resolved.
Show resolved Hide resolved
needs: branch-validation
runs-on: macos-latest
if: startsWith(github.ref, 'refs/heads/release/')
steps:
- name: Checkout Code
uses: actions/checkout@v3

- name: Set up SSH for Bitbucket
run: |
mkdir -p ~/.ssh
echo "${{ secrets.BITBUCKET_SSH_KEY }}" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan -t rsa bitbucket.org >> ~/.ssh/known_hosts

- name: Install Fastlane
run: gem install fastlane

- name: Deploy to TestFlight
run: fastlane beta
env:
ASC_KEY_ID: ${{ secrets.ASC_KEY_ID }}
ASC_ISSUER_ID: ${{ secrets.ASC_ISSUER_ID }}
ASC_API_KEY: ${{ secrets.APP_STORE_CONNECT_API_KEY }}
MATCH_GIT_URL: ${{ secrets.MATCH_GIT_URL }}
MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
GIT_USER_NAME: ${{ secrets.GIT_USER_NAME }}
GIT_EMAIL: ${{ secrets.GIT_EMAIL }}
GIT_TOKEN: ${{ secrets.GIT_TOKEN }}
18 changes: 18 additions & 0 deletions Alfie/Alfie.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@
DAC900752B87D04100F9819C /* LocalizableGeneral.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = LocalizableGeneral.xcstrings; sourceTree = "<group>"; };
DAE910212B8CAD81008DC191 /* ForceAppUpdateView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ForceAppUpdateView.swift; sourceTree = "<group>"; };
DAEDF87E2B7AD606000C3604 /* LocalizableHome.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalizableHome.swift; sourceTree = "<group>"; };
FCA0B27E2CEF3F12000339F6 /* alfie.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = alfie.yml; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -721,6 +722,7 @@
BE8B021B2B616976007AE489 = {
isa = PBXGroup;
children = (
FCA0B27B2CEF3EE7000339F6 /* .github */,
BEA12B7C2B62665B00DA7608 /* Packages */,
BE8B02262B616976007AE489 /* Alfie */,
BE8B02372B616979007AE489 /* AlfieTests */,
Expand Down Expand Up @@ -1015,6 +1017,22 @@
path = DeepLinking;
sourceTree = "<group>";
};
FCA0B27B2CEF3EE7000339F6 /* .github */ = {
isa = PBXGroup;
children = (
FCA0B27D2CEF3EFB000339F6 /* workflows */,
);
path = .github;
sourceTree = "<group>";
};
FCA0B27D2CEF3EFB000339F6 /* workflows */ = {
isa = PBXGroup;
children = (
FCA0B27E2CEF3F12000339F6 /* alfie.yml */,
);
path = workflows;
sourceTree = "<group>";
};
Comment on lines +1020 to +1035
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no need to add the .github folder to the .xcodeproj, neither the alfie.yml file

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the idea is that we can edit these files while working on the project in Xcode, instead of having to open another editor.

To your point, I think we might not need to add the whole folder and just add the relevant files.

IMO we just need to be careful that these files aren't added to the app target, but I don't see any problem in adding them to the project as references. In other projects I've worked on we even create a group without folder, and add file references to it for all these CI/tooling/setup/documentation files

/* End PBXGroup section */

/* Begin PBXNativeTarget section */
Expand Down
3 changes: 3 additions & 0 deletions Alfie/Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
source "https://rubygems.org"

gem "fastlane"
222 changes: 222 additions & 0 deletions Alfie/Gemfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
GEM
remote: https://rubygems.org/
specs:
CFPropertyList (3.0.7)
base64
nkf
rexml
addressable (2.8.7)
public_suffix (>= 2.0.2, < 7.0)
artifactory (3.0.17)
atomos (0.1.3)
aws-eventstream (1.3.0)
aws-partitions (1.1013.0)
aws-sdk-core (3.214.0)
aws-eventstream (~> 1, >= 1.3.0)
aws-partitions (~> 1, >= 1.992.0)
aws-sigv4 (~> 1.9)
jmespath (~> 1, >= 1.6.1)
aws-sdk-kms (1.96.0)
aws-sdk-core (~> 3, >= 3.210.0)
aws-sigv4 (~> 1.5)
aws-sdk-s3 (1.174.0)
aws-sdk-core (~> 3, >= 3.210.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.5)
aws-sigv4 (1.10.1)
aws-eventstream (~> 1, >= 1.0.2)
babosa (1.0.4)
base64 (0.2.0)
claide (1.1.0)
colored (1.2)
colored2 (3.1.2)
commander (4.6.0)
highline (~> 2.0.0)
declarative (0.0.20)
digest-crc (0.6.5)
rake (>= 12.0.0, < 14.0.0)
domain_name (0.6.20240107)
dotenv (2.8.1)
emoji_regex (3.2.3)
excon (0.112.0)
faraday (1.10.4)
faraday-em_http (~> 1.0)
faraday-em_synchrony (~> 1.0)
faraday-excon (~> 1.1)
faraday-httpclient (~> 1.0)
faraday-multipart (~> 1.0)
faraday-net_http (~> 1.0)
faraday-net_http_persistent (~> 1.0)
faraday-patron (~> 1.0)
faraday-rack (~> 1.0)
faraday-retry (~> 1.0)
ruby2_keywords (>= 0.0.4)
faraday-cookie_jar (0.0.7)
faraday (>= 0.8.0)
http-cookie (~> 1.0.0)
faraday-em_http (1.0.0)
faraday-em_synchrony (1.0.0)
faraday-excon (1.1.0)
faraday-httpclient (1.0.1)
faraday-multipart (1.0.4)
multipart-post (~> 2)
faraday-net_http (1.0.2)
faraday-net_http_persistent (1.2.0)
faraday-patron (1.0.0)
faraday-rack (1.0.0)
faraday-retry (1.0.3)
faraday_middleware (1.2.1)
faraday (~> 1.0)
fastimage (2.3.1)
fastlane (2.225.0)
CFPropertyList (>= 2.3, < 4.0.0)
addressable (>= 2.8, < 3.0.0)
artifactory (~> 3.0)
aws-sdk-s3 (~> 1.0)
babosa (>= 1.0.3, < 2.0.0)
bundler (>= 1.12.0, < 3.0.0)
colored (~> 1.2)
commander (~> 4.6)
dotenv (>= 2.1.1, < 3.0.0)
emoji_regex (>= 0.1, < 4.0)
excon (>= 0.71.0, < 1.0.0)
faraday (~> 1.0)
faraday-cookie_jar (~> 0.0.6)
faraday_middleware (~> 1.0)
fastimage (>= 2.1.0, < 3.0.0)
fastlane-sirp (>= 1.0.0)
gh_inspector (>= 1.1.2, < 2.0.0)
google-apis-androidpublisher_v3 (~> 0.3)
google-apis-playcustomapp_v1 (~> 0.1)
google-cloud-env (>= 1.6.0, < 2.0.0)
google-cloud-storage (~> 1.31)
highline (~> 2.0)
http-cookie (~> 1.0.5)
json (< 3.0.0)
jwt (>= 2.1.0, < 3)
mini_magick (>= 4.9.4, < 5.0.0)
multipart-post (>= 2.0.0, < 3.0.0)
naturally (~> 2.2)
optparse (>= 0.1.1, < 1.0.0)
plist (>= 3.1.0, < 4.0.0)
rubyzip (>= 2.0.0, < 3.0.0)
security (= 0.1.5)
simctl (~> 1.6.3)
terminal-notifier (>= 2.0.0, < 3.0.0)
terminal-table (~> 3)
tty-screen (>= 0.6.3, < 1.0.0)
tty-spinner (>= 0.8.0, < 1.0.0)
word_wrap (~> 1.0.0)
xcodeproj (>= 1.13.0, < 2.0.0)
xcpretty (~> 0.3.0)
xcpretty-travis-formatter (>= 0.0.3, < 2.0.0)
fastlane-sirp (1.0.0)
sysrandom (~> 1.0)
gh_inspector (1.1.3)
google-apis-androidpublisher_v3 (0.54.0)
google-apis-core (>= 0.11.0, < 2.a)
google-apis-core (0.11.3)
addressable (~> 2.5, >= 2.5.1)
googleauth (>= 0.16.2, < 2.a)
httpclient (>= 2.8.1, < 3.a)
mini_mime (~> 1.0)
representable (~> 3.0)
retriable (>= 2.0, < 4.a)
rexml
google-apis-iamcredentials_v1 (0.17.0)
google-apis-core (>= 0.11.0, < 2.a)
google-apis-playcustomapp_v1 (0.13.0)
google-apis-core (>= 0.11.0, < 2.a)
google-apis-storage_v1 (0.31.0)
google-apis-core (>= 0.11.0, < 2.a)
google-cloud-core (1.7.1)
google-cloud-env (>= 1.0, < 3.a)
google-cloud-errors (~> 1.0)
google-cloud-env (1.6.0)
faraday (>= 0.17.3, < 3.0)
google-cloud-errors (1.4.0)
google-cloud-storage (1.47.0)
addressable (~> 2.8)
digest-crc (~> 0.4)
google-apis-iamcredentials_v1 (~> 0.1)
google-apis-storage_v1 (~> 0.31.0)
google-cloud-core (~> 1.6)
googleauth (>= 0.16.2, < 2.a)
mini_mime (~> 1.0)
googleauth (1.8.1)
faraday (>= 0.17.3, < 3.a)
jwt (>= 1.4, < 3.0)
multi_json (~> 1.11)
os (>= 0.9, < 2.0)
signet (>= 0.16, < 2.a)
highline (2.0.3)
http-cookie (1.0.7)
domain_name (~> 0.5)
httpclient (2.8.3)
jmespath (1.6.2)
json (2.8.2)
jwt (2.9.3)
base64
mini_magick (4.13.2)
mini_mime (1.1.5)
multi_json (1.15.0)
multipart-post (2.4.1)
nanaimo (0.4.0)
naturally (2.2.1)
nkf (0.2.0)
optparse (0.6.0)
os (1.1.4)
plist (3.7.1)
public_suffix (6.0.1)
rake (13.2.1)
representable (3.2.0)
declarative (< 0.1.0)
trailblazer-option (>= 0.1.1, < 0.2.0)
uber (< 0.2.0)
retriable (3.1.2)
rexml (3.3.9)
rouge (2.0.7)
ruby2_keywords (0.0.5)
rubyzip (2.3.2)
security (0.1.5)
signet (0.19.0)
addressable (~> 2.8)
faraday (>= 0.17.5, < 3.a)
jwt (>= 1.5, < 3.0)
multi_json (~> 1.10)
simctl (1.6.10)
CFPropertyList
naturally
sysrandom (1.0.5)
terminal-notifier (2.0.0)
terminal-table (3.0.2)
unicode-display_width (>= 1.1.1, < 3)
trailblazer-option (0.1.2)
tty-cursor (0.7.1)
tty-screen (0.8.2)
tty-spinner (0.9.3)
tty-cursor (~> 0.7)
uber (0.1.0)
unicode-display_width (2.6.0)
word_wrap (1.0.0)
xcodeproj (1.27.0)
CFPropertyList (>= 2.3.3, < 4.0)
atomos (~> 0.1.3)
claide (>= 1.0.2, < 2.0)
colored2 (~> 3.1)
nanaimo (~> 0.4.0)
rexml (>= 3.3.6, < 4.0)
xcpretty (0.3.0)
rouge (~> 2.0.7)
xcpretty-travis-formatter (1.0.1)
xcpretty (~> 0.2, >= 0.0.7)

PLATFORMS
arm64-darwin-23
ruby

DEPENDENCIES
fastlane

BUNDLED WITH
2.5.23
6 changes: 6 additions & 0 deletions Alfie/fastlane/Appfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
app_identifier("com.mindera.alfie.debug") # The bundle identifier of your app
itc_team_id("116567802") # App Store Connect Team ID
team_id("74L475LDQT") # Developer Portal Team ID

# For more information about the Appfile, see:
# https://docs.fastlane.tools/advanced/#appfile
53 changes: 53 additions & 0 deletions Alfie/fastlane/Fastfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# This file contains the fastlane.tools configuration
# You can find the documentation at https://docs.fastlane.tools
#
# For a list of all available actions, check out
#
# https://docs.fastlane.tools/actions
#
# For a list of all available plugins, check out
#
# https://docs.fastlane.tools/plugins/available-plugins
#

# Uncomment the line if you want fastlane to automatically update itself
# update_fastlane

platform :ios do
desc "Validate branch with linting, analysis, and tests"
lane :validate_branch do
sh("swiftlint") # Runs SwiftLint
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there's a swiftlint fastlane action. I have mixed feelings about bundling swiftlint executable in the project, but I tend to prefer it being povided externally (e.g. via brew, SPM plugin, ...)

sh("xcodebuild analyze -scheme Alfie -destination '#{ENV['IOS_DESTINATION']}'")
sh("xcodebuild test -scheme Alfie -destination '#{ENV['IOS_DESTINATION']}'")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

perhaps use run_tests action (aka scan) ?

https://docs.fastlane.tools/getting-started/ios/running-tests/

We can also set SCAN_DESTINATION and any other env var once which then gets passed automatically to each fastlane action. Take a look here for scan's parameters, for instance.

end

desc "Deploy to TestFlight using Git tags"
lane :beta do
api_key = app_store_connect_api_key(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need to store the api_key, as this action stores it on the environment for subsequent actions to use (such as upload_to_testflight, match, etc)

key_id: ENV['ASC_KEY_ID'],
issuer_id: ENV['ASC_ISSUER_ID'],
key_filepath: ENV['ASC_API_KEY']
)

match(type: "appstore", readonly: false, api_key: api_key)

increment_build_number
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we are incrementing the build number, but how is it updated after each build?

Shouldn't we get the last tag's value, extract the BN, then increment and set it on the Xcode project instead?


version = get_version_number(xcodeproj: "Alfie.xcodeproj")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can and probably should store the Xcode project's path on an env var, which avoids duplication and possible errors.

build_number = get_build_number(xcodeproj: "Alfie.xcodeproj")
sh("git config user.name '#{ENV['GIT_USER_NAME']}'")
sh("git config user.email '#{ENV['GIT_EMAIL']}'")
sh("git tag v#{version}-#{build_number}")
sh("git push origin --tags")

build_app(
scheme: "Alfie",
export_options: { method: "app-store" },
api_key: api_key
)

upload_to_testflight(api_key: api_key)
end
end