Skip to content

Commit

Permalink
ci: add comment on GitHub issue(s) for alpha builds (#56) (#60)
Browse files Browse the repository at this point in the history
The commit improves Fastlane Fastifle with a new internal method which will publish a comment on issues related to the current alpha build. Thus when an alpha build is done and its TestFlight upload processed, a comment will be publishe for each related issue.
Documentation has been also improved with details about the type of GitHub personal access token to define as secret.
The internal CI/CD software solution has been used for tests.
This commit also replaces some Shell commands for GitHub REST API HTTP request with some Ruby standard API.

Closes #56

Tested-by: Pierre-Yves Lapersonne <[email protected]>
Signed-off-by: Pierre-Yves Lapersonne <[email protected]>
  • Loading branch information
pylapp committed Aug 5, 2024
1 parent a30d9f5 commit d960506
Show file tree
Hide file tree
Showing 8 changed files with 245 additions and 51 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- [Showcase] Publication of comment on issues about new alpha build upload on TestFlight ([#56](https://github.com/Orange-OpenSource/ouds-ios/issues/56))
- [Library] Add raw tokens and semantic tokens for border ([#30](https://github.com/Orange-OpenSource/ouds-ios/issues/30))
- [Library] Define Swift Package architecture of library and tokens (raw and semantic) ([#33](https://github.com/Orange-OpenSource/ouds-ios/issues/33))
- [Showcase] Distribute demo app development version ([#12](https://github.com/Orange-OpenSource/ouds-ios/issues/12))
Expand Down
4 changes: 2 additions & 2 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@
source "https://rubygems.org"

gem 'cocoapods', '1.15.2'

gem 'fastlane', '2.221.1'
gem 'fastlane-plugin-changelog', '0.16.0'
gem 'fastlane-plugin-mattermost', '1.3.2'

gem 'json', '2.7.2'
gem 'net-http', '0.4.1'
gem 'xcode-install', '2.8.1'

plugins_path = File.join(File.dirname(__FILE__), 'Showcase/fastlane', 'Pluginfile')
Expand Down
5 changes: 5 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,8 @@ GEM
nanaimo (0.3.0)
nap (1.1.0)
naturally (2.2.1)
net-http (0.4.1)
uri
netrc (0.11.0)
nkf (0.2.0)
optparse (0.5.0)
Expand Down Expand Up @@ -280,6 +282,7 @@ GEM
concurrent-ruby (~> 1.0)
uber (0.1.0)
unicode-display_width (2.5.0)
uri (0.13.0)
word_wrap (1.0.0)
xcode-install (2.8.1)
claide (>= 0.9.1)
Expand Down Expand Up @@ -314,6 +317,8 @@ DEPENDENCIES
fastlane (= 2.221.1)
fastlane-plugin-changelog (= 0.16.0)
fastlane-plugin-mattermost (= 1.3.2)
json (= 2.7.2)
net-http (= 0.4.1)
xcode-install (= 2.8.1)

BUNDLED WITH
Expand Down
8 changes: 4 additions & 4 deletions Showcase/Showcase.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -561,7 +561,7 @@
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 4;
CURRENT_PROJECT_VERSION = 5;
DEVELOPMENT_ASSET_PATHS = "\"Showcase/Preview Content\"";
DEVELOPMENT_TEAM = MG2LSJNJB6;
ENABLE_PREVIEWS = YES;
Expand All @@ -577,7 +577,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 0.0.0;
MARKETING_VERSION = 0.1.0;
PRODUCT_BUNDLE_IDENTIFIER = "com.orange.ouds.demoapp-debug";
PRODUCT_NAME = "OUDS Showcase";
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
Expand All @@ -599,7 +599,7 @@
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 4;
CURRENT_PROJECT_VERSION = 5;
DEVELOPMENT_ASSET_PATHS = "\"Showcase/Preview Content\"";
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = MG2LSJNJB6;
Expand All @@ -616,7 +616,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 0.0.0;
MARKETING_VERSION = 0.1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.orange.ouds.demoapp;
PRODUCT_NAME = "OUDS Showcase";
PROVISIONING_PROFILE_SPECIFIER = "";
Expand Down
109 changes: 94 additions & 15 deletions Showcase/fastlane/Fastfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
# Software description: A SwiftUI components library with code examples for Orange Unified Design System
#

require 'net/http'
require 'json'

# App features configuration
# --------------------------

Expand Down Expand Up @@ -151,22 +154,30 @@ platform :ios do
# ------------------------------------------------------------
desc "BUILD & UPLOAD TO TESTFLIGHT ALPHA APP"
lane :alpha do |params|
puts "👉 Alpha (commit hash = '#{params[:commitHash]}, issue number = '#{params[:issueNumber]}')"
issues_numbers = params[:issueNumber]
puts "👉 Alpha (commit hash = '#{params[:commitHash]}, issue number = '#{issues_numbers}')"

if issues_numbers.nil? || issues_numbers.empty?
puts "❌ Error: No issues numbers have been given for alpha builds, nothing will be done"
publish_mattermost_notification("⚙️ 😰 Tried to build alpha version without mentioning issues numbers!")
raise "Bad prerequisites error - missing pipeline variable"
end

Dir.chdir "../Showcase/Resources/Assets.xcassets" do
sh "rm -Rf AppIconRelease.appiconset"
sh "cp -R AppIconDev.appiconset AppIconRelease.appiconset"
end

# CFBundleVersion and CFBundleShortVersionString must follow rules with integers and periods, should not change them
# But still possible to change CFBundleDisplayName
new_display_name = "OUDS Showcase ALPHA (#{params[:issueNumber]})"
new_display_name = "OUDS Showcase ALPHA (#{issues_numbers})"
puts "ℹ️ New display name version will be: '#{new_display_name}'"
set_info_plist_value(path: "#{Dir.pwd}/../Showcase/Info.plist", key: "CFBundleDisplayName", value: new_display_name)

# Details for the GUI in the app
set_info_plist_value(path: "#{Dir.pwd}/../Showcase/Info.plist", key: "OUDSBuildType", value: "ALPHA")
set_info_plist_value(path: "#{Dir.pwd}/../Showcase/Info.plist", key: "OUDSBuildTag", value: "#{params[:commitHash][0,7]}".strip)
set_info_plist_value(path: "#{Dir.pwd}/../Showcase/Info.plist", key: "OUDSBuildDetails", value: "#{params[:issueNumber]}")
set_info_plist_value(path: "#{Dir.pwd}/../Showcase/Info.plist", key: "OUDSBuildDetails", value: "#{issues_numbers}")

build_and_upload(isAlpha: true, upload: true)
end
Expand Down Expand Up @@ -228,6 +239,7 @@ platform :ios do
update_build_number
build
upload(type: "alpha")
public_github_notifications_build_details

else # Beta case (not production too), detailSymbol should be here commit hash
detailSymbol = params[:detailSymbol]
Expand Down Expand Up @@ -428,23 +440,37 @@ platform :ios do
else
# Check if given tag exists yet
puts "ℹ️ Check if '#{tag}' exists yet"
result=sh("curl -s 'https://api.github.com/repos/Orange-OpenSource/ouds-ios/git/refs/tags/#{tag}' | jq -r '.ref'") # TODO Shell error management
# If tag exists, CURL response is formatted like "refs/tags/tag"
if "refs/tags/#{tag}".eql? result.strip # Removes line break available in command result

uri = URI("https://api.github.com/repos/Orange-OpenSource/ouds-ios/tags")
response = Net::HTTP.get(uri)
tags = JSON.parse(response)

if tags.any? { |t| t['name'] == tag }
puts "ℹ️ The tag '#{tag}' still exists, won't create new tag"
return false
else
puts "ℹ️ Commit SHA to tag is '#{IOS_APP_COMMIT_SHA}'"
# Just a light tag is enough
sh("curl -L \
-X POST \
-H 'Accept: application/vnd.github+json' \
-H 'Authorization: Bearer #{GITHUB_ACCESS_TOKEN}'\
-H 'X-GitHub-Api-Version: 2022-11-28' \
https://api.github.com/repos/Orange-OpenSource/ouds-ios/git/refs \
-d '{\"ref\":\"refs/tags/#{tag}\",\"sha\":\"#{IOS_APP_COMMIT_SHA}\"}'") # TODO Shell error management

uri = URI("https://api.github.com/repos/Orange-OpenSource/ouds-ios/git/refs")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true

request = Net::HTTP::Post.new(uri.path)
request['Accept'] = 'application/vnd.github+json'
request['Authorization'] = "Bearer #{GITHUB_ACCESS_TOKEN}"
request['X-GitHub-Api-Version'] = '2022-11-28'
request.body = { ref: "refs/tags/#{tag}", sha: IOS_APP_COMMIT_SHA }.to_json

response = http.request(request)

if response.code.to_i == 201
puts "ℹ️ Light tag '#{tag}' published in repository"
return true
end
else
puts "❌ Error: Failed to publish light tag '#{tag}'"
return false
end
end
end
end

Expand All @@ -457,6 +483,59 @@ platform :ios do
)
end

# Send a comment to the GitHub related GitHub issues about a new available build.
# Will find in Info.plist of demo app all the suitable needed details.
def public_github_notifications_build_details
build_version = get_app_version
build_number = get_build_number(xcodeproj: OUDS_PROJECT)
build_display_name = get_info_plist_value(path: "#{Dir.pwd}/../Showcase/Info.plist", key: "CFBundleDisplayName")
build_type = get_info_plist_value(path: "#{Dir.pwd}/../Showcase/Info.plist", key: "OUDSBuildType")
build_tag = get_info_plist_value(path: "#{Dir.pwd}/../Showcase/Info.plist", key: "OUDSBuildTag")
build_details = get_info_plist_value(path: "#{Dir.pwd}/../Showcase/Info.plist", key: "OUDSBuildDetails")

build_issues_numbers = build_details.scan(/\d+/).map(&:to_i)

build_issues_numbers.each do |issue_number|
uri = URI("https://api.github.com/repos/Orange-OpenSource/ouds-ios/issues/#{issue_number}")
response = Net::HTTP.get(uri)
issue = JSON.parse(response)

if issue['message'] == 'Not Found'
puts "❌ Error: Issue '#{issue_number}' does not exist"
else

comment_to_upload=<<-EOF
📣 **New TestFlight ALPHA upload** 🚀
- Display name: **#{build_display_name}**
- Version: #{build_version}
- Build number: **#{build_number}**
- Build tag: #{build_tag}
- Build type: #{build_type}
- Build details (GitHub):#{build_details}
_This is an automated message sent with *Fastlane* from our CI/CD pipeline 🤘_
EOF

uri = URI("https://api.github.com/repos/Orange-OpenSource/ouds-ios/issues/#{issue_number}/comments")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true

request = Net::HTTP::Post.new(uri.path)
request['Authorization'] = "Bearer #{GITHUB_ACCESS_TOKEN}"
request['Content-Type'] = 'application/json'
request.body = { body: comment_to_upload }.to_json

response = http.request(request)

if response.code.to_i == 201
puts "ℹ️ Comment posted on issue '#{issue_number}'"
else
puts "❌ Error: Failed to post comment on issue '#{issue_number}'"
end
end
end
end

# Get version set in the Xcode project
def get_app_version
version = get_version_number(
Expand Down
80 changes: 80 additions & 0 deletions Showcase/fastlane/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
fastlane documentation
----

# Installation

Make sure you have the latest version of the Xcode command line tools installed:

```sh
xcode-select --install
```

For _fastlane_ installation instructions, see [Installing _fastlane_](https://docs.fastlane.tools/#installing-fastlane)

# Available Actions

## iOS

### ios update_build_number

```sh
[bundle exec] fastlane ios update_build_number
```

UPDATE BUILD NUMBER WITH TIMESTAMP

### ios test

```sh
[bundle exec] fastlane ios test
```

RUN TESTS BY TRIGGERING THE TESTS PLANS OF THE PROJECT

### ios prepare_release

```sh
[bundle exec] fastlane ios prepare_release
```

READ AND SET NEXT RELEASE NOTE IN CHANGELOG

### ios buildDebugApp

```sh
[bundle exec] fastlane ios buildDebugApp
```

BUILD DEBUG APP

### ios alpha

```sh
[bundle exec] fastlane ios alpha
```

BUILD & UPLOAD TO TESTFLIGHT ALPHA APP

### ios beta

```sh
[bundle exec] fastlane ios beta
```

BUILD & UPLOAD TO TESTFLIGHT BETA APP

### ios prod

```sh
[bundle exec] fastlane ios prod
```

BUILD & UPLOAD TO TESTFLIGHT (if set in options: upload) PROD APP

----

This README.md is auto-generated and will be re-generated every time [_fastlane_](https://fastlane.tools) is run.

More information about _fastlane_ can be found on [fastlane.tools](https://fastlane.tools).

The documentation of _fastlane_ can be found on [docs.fastlane.tools](https://docs.fastlane.tools).
Loading

0 comments on commit d960506

Please sign in to comment.