Resolve several issues in bump script/lane (#1075)

- Simplify build/version updates by moving MARKETING_VERSION and
CURRENT_PROJECT_VERSION to Config.xcconfig
- Provide Ruby (for fastlane) and Bash (for CI) versions of
xconfig-get/set
- Copy release notes atomically inside the lane to guarantee they are
included in the version commit
- Add -nt to skip the build tag
This commit is contained in:
Davide 2025-01-18 18:13:54 +01:00 committed by GitHub
parent 72c4a11c5e
commit 8972d9773e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 105 additions and 82 deletions

View File

@ -10,7 +10,6 @@ env:
FASTLANE_USERNAME: ${{ secrets.FASTLANE_USERNAME }}
FASTLANE_PASSWORD: ${{ secrets.FASTLANE_PASSWORD }}
TESTFLIGHT_PREFACE: ${{ vars.TESTFLIGHT_PREFACE }}
XCODEPROJ: "Passepartout.xcodeproj/project.pbxproj"
PLATFORMS: "iOS macOS tvOS"
concurrency:
@ -29,8 +28,8 @@ jobs:
- name: Save app version
id: app_version
run: |
VERSION=`ci/version-number.sh $XCODEPROJ`
BUILD=`ci/build-number.sh $XCODEPROJ`
VERSION=`ci/version-number.sh`
BUILD=`ci/build-number.sh`
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "build=$BUILD" >> $GITHUB_OUTPUT
- name: Run Xcode tests

View File

@ -1,6 +1,6 @@
source "https://rubygems.org"
gem "fastlane", :github => "keeshux/fastlane", :ref => "57b2e988e862b14c557419210dc5bd7c9a1636cc"
gem "fastlane", :github => "keeshux/fastlane", :ref => "77198d601b9237c223dfe5550ce1c20f43140c79"
gem "dotenv"
plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile')

View File

@ -1,7 +1,7 @@
GIT
remote: https://github.com/keeshux/fastlane.git
revision: 57b2e988e862b14c557419210dc5bd7c9a1636cc
ref: 57b2e988e862b14c557419210dc5bd7c9a1636cc
revision: 77198d601b9237c223dfe5550ce1c20f43140c79
ref: 77198d601b9237c223dfe5550ce1c20f43140c79
specs:
fastlane (2.226.0)
CFPropertyList (>= 2.3, < 4.0.0)
@ -58,30 +58,30 @@ GEM
artifactory (3.0.17)
atomos (0.1.3)
aws-eventstream (1.3.0)
aws-partitions (1.1022.0)
aws-sdk-core (3.214.0)
aws-partitions (1.1040.0)
aws-sdk-core (3.216.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-sdk-kms (1.97.0)
aws-sdk-core (~> 3, >= 3.216.0)
aws-sigv4 (~> 1.5)
aws-sdk-s3 (1.176.1)
aws-sdk-core (~> 3, >= 3.210.0)
aws-sdk-s3 (1.178.0)
aws-sdk-core (~> 3, >= 3.216.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.5)
aws-sigv4 (1.10.1)
aws-sigv4 (1.11.0)
aws-eventstream (~> 1, >= 1.0.2)
babosa (1.0.4)
base64 (0.2.0)
bigdecimal (3.1.8)
bigdecimal (3.1.9)
claide (1.1.0)
colored (1.2)
colored2 (3.1.2)
commander (4.6.0)
highline (~> 2.0.0)
csv (3.3.0)
csv (3.3.2)
declarative (0.0.20)
digest-crc (0.6.5)
rake (>= 12.0.0, < 14.0.0)
@ -108,8 +108,8 @@ GEM
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-multipart (1.1.0)
multipart-post (~> 2.0)
faraday-net_http (1.0.2)
faraday-net_http_persistent (1.2.0)
faraday-patron (1.0.0)
@ -117,11 +117,10 @@ GEM
faraday-retry (1.0.3)
faraday_middleware (1.2.1)
faraday (~> 1.0)
fastimage (2.3.1)
fastimage (2.4.0)
fastlane-plugin-translate_gpt (0.1.8.2)
loco_strings (~> 0.1.4.1)
ruby-openai (~> 3.7)
fastlane-plugin-versioning (0.7.0)
fastlane-sirp (1.0.0)
sysrandom (~> 1.0)
gh_inspector (1.1.3)
@ -170,8 +169,8 @@ GEM
multi_xml (>= 0.5.2)
httpclient (2.8.3)
jmespath (1.6.2)
json (2.9.0)
jwt (2.9.3)
json (2.9.1)
jwt (2.10.1)
base64
loco_strings (0.1.4.1)
nokogiri (~> 1.13, >= 1.13.8)
@ -185,14 +184,14 @@ GEM
nanaimo (0.4.0)
naturally (2.2.1)
nkf (0.2.0)
nokogiri (1.17.2)
nokogiri (1.18.1)
mini_portile2 (~> 2.8.2)
racc (~> 1.4)
nokogiri (1.17.2-arm64-darwin)
nokogiri (1.18.1-arm64-darwin)
racc (~> 1.4)
optparse (0.6.0)
os (1.1.4)
plist (3.7.1)
plist (3.7.2)
public_suffix (6.0.1)
racc (1.8.1)
rake (13.2.1)
@ -201,12 +200,12 @@ GEM
trailblazer-option (>= 0.1.1, < 0.2.0)
uber (< 0.2.0)
retriable (3.1.2)
rexml (3.3.9)
rexml (3.4.0)
rouge (3.28.0)
ruby-openai (3.7.0)
httparty (>= 0.18.1)
ruby2_keywords (0.0.5)
rubyzip (2.3.2)
rubyzip (2.4.1)
security (0.1.5)
signet (0.19.0)
addressable (~> 2.8)
@ -248,7 +247,6 @@ DEPENDENCIES
dotenv
fastlane!
fastlane-plugin-translate_gpt
fastlane-plugin-versioning
BUNDLED WITH
2.5.17

@ -1 +1 @@
Subproject commit d46881b818ac532032324ad518c89779b7ae45a1
Subproject commit f6d85fdf1e186fa13c820166f3a414962bcc52c1

View File

@ -262,17 +262,7 @@
/* End PBXFileReference section */
/* Begin PBXFileSystemSynchronizedRootGroup section */
0E3D7F242D347A41003F1C4B /* Packages */ = {
isa = PBXFileSystemSynchronizedRootGroup;
exceptions = (
);
explicitFileTypes = {
};
explicitFolders = (
);
path = Packages;
sourceTree = "<group>";
};
0E3D7F242D347A41003F1C4B /* Packages */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = Packages; sourceTree = "<group>"; };
/* End PBXFileSystemSynchronizedRootGroup section */
/* Begin PBXFrameworksBuildPhase section */
@ -1229,7 +1219,6 @@
"ASSETCATALOG_COMPILER_APPICON_NAME[sdk=appletvos*]" = TV;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_ENTITLEMENTS = Passepartout/App/App.entitlements;
CURRENT_PROJECT_VERSION = 3718;
ENABLE_PREVIEWS = YES;
INFOPLIST_FILE = Passepartout/App/App.plist;
INFOPLIST_KEY_CFBundleDisplayName = "$(TARGET_NAME)";
@ -1250,7 +1239,6 @@
INFOPLIST_KEY_UISupportsDocumentBrowser = NO;
LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
MARKETING_VERSION = 3.0.1;
PRODUCT_BUNDLE_IDENTIFIER = "$(CFG_APP_ID)";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@ -1268,7 +1256,6 @@
"ASSETCATALOG_COMPILER_APPICON_NAME[sdk=appletvos*]" = TV;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_ENTITLEMENTS = Passepartout/App/App.entitlements;
CURRENT_PROJECT_VERSION = 3718;
ENABLE_PREVIEWS = YES;
INFOPLIST_FILE = Passepartout/App/App.plist;
INFOPLIST_KEY_CFBundleDisplayName = "$(TARGET_NAME)";
@ -1289,7 +1276,6 @@
INFOPLIST_KEY_UISupportsDocumentBrowser = NO;
LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
MARKETING_VERSION = 3.0.1;
PRODUCT_BUNDLE_IDENTIFIER = "$(CFG_APP_ID)";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@ -1329,7 +1315,6 @@
buildSettings = {
CODE_SIGN_ENTITLEMENTS = Passepartout/LoginItem/LoginItem.entitlements;
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 3718;
ENABLE_HARDENED_RUNTIME = YES;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
INFOPLIST_KEY_CFBundleDisplayName = "$(TARGET_NAME)";
@ -1338,7 +1323,6 @@
INFOPLIST_KEY_NSHumanReadableCopyright = "$(CFG_COPYRIGHT)";
INFOPLIST_KEY_UIRequiredDeviceCapabilities = arm64;
LD_RUNPATH_SEARCH_PATHS = "@executable_path/../Frameworks";
MARKETING_VERSION = 3.0.0;
PRODUCT_BUNDLE_IDENTIFIER = "$(CFG_LOGIN_ITEM_ID)";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
@ -1354,7 +1338,6 @@
buildSettings = {
CODE_SIGN_ENTITLEMENTS = Passepartout/LoginItem/LoginItem.entitlements;
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 3718;
ENABLE_HARDENED_RUNTIME = YES;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
INFOPLIST_KEY_CFBundleDisplayName = "$(TARGET_NAME)";
@ -1363,7 +1346,6 @@
INFOPLIST_KEY_NSHumanReadableCopyright = "$(CFG_COPYRIGHT)";
INFOPLIST_KEY_UIRequiredDeviceCapabilities = arm64;
LD_RUNPATH_SEARCH_PATHS = "@executable_path/../Frameworks";
MARKETING_VERSION = 3.0.0;
PRODUCT_BUNDLE_IDENTIFIER = "$(CFG_LOGIN_ITEM_ID)";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
@ -1408,7 +1390,6 @@
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_ENTITLEMENTS = Passepartout/Tunnel/Tunnel.entitlements;
CURRENT_PROJECT_VERSION = 3718;
INFOPLIST_FILE = Passepartout/Tunnel/Tunnel.plist;
INFOPLIST_KEY_CFBundleDisplayName = "$(TARGET_NAME)";
INFOPLIST_KEY_NSHumanReadableCopyright = "$(CFG_COPYRIGHT)";
@ -1418,7 +1399,6 @@
"@executable_path/../../Frameworks",
);
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../../../../Frameworks";
MARKETING_VERSION = 3.0.0;
PRODUCT_BUNDLE_IDENTIFIER = "$(CFG_TUNNEL_ID)";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@ -1434,14 +1414,12 @@
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_ENTITLEMENTS = Passepartout/Tunnel/Tunnel.entitlements;
CURRENT_PROJECT_VERSION = 3718;
INFOPLIST_FILE = Passepartout/Tunnel/Tunnel.plist;
INFOPLIST_KEY_CFBundleDisplayName = "$(TARGET_NAME)";
INFOPLIST_KEY_NSHumanReadableCopyright = "$(CFG_COPYRIGHT)";
INFOPLIST_KEY_UIRequiredDeviceCapabilities = arm64;
LD_RUNPATH_SEARCH_PATHS = "@executable_path/../../Frameworks";
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../../../../Frameworks";
MARKETING_VERSION = 3.0.0;
PRODUCT_BUNDLE_IDENTIFIER = "$(CFG_TUNNEL_ID)";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@ -1457,7 +1435,6 @@
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_ENTITLEMENTS = Passepartout/Intents/Intents.entitlements;
CURRENT_PROJECT_VERSION = 3718;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = Passepartout/Intents/Intents.plist;
@ -1469,7 +1446,6 @@
"@executable_path/../../Frameworks",
);
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../../../../Frameworks";
MARKETING_VERSION = 3.0.0;
PRODUCT_BUNDLE_IDENTIFIER = com.algoritmico.ios.Passepartout.Intents;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@ -1488,7 +1464,6 @@
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_ENTITLEMENTS = Passepartout/Intents/Intents.entitlements;
CURRENT_PROJECT_VERSION = 3718;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = Passepartout/Intents/Intents.plist;
@ -1497,7 +1472,6 @@
INFOPLIST_KEY_UIRequiredDeviceCapabilities = arm64;
LD_RUNPATH_SEARCH_PATHS = "@executable_path/../../Frameworks";
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../../../../Frameworks";
MARKETING_VERSION = 3.0.0;
PRODUCT_BUNDLE_IDENTIFIER = com.algoritmico.ios.Passepartout.Intents;
PRODUCT_NAME = "$(TARGET_NAME)";
"PROVISIONING_PROFILE_SPECIFIER[sdk=appletvos*]" = "match AppStore com.algoritmico.ios.Passepartout.Intents tvos";

View File

@ -26,6 +26,9 @@
// Configuration settings file format documentation can be found at:
// https://help.apple.com/xcode/#/dev745c5c974
MARKETING_VERSION = 3.0.1
CURRENT_PROJECT_VERSION = 3718
// tweak these based on app and team
CFG_APP_ID = com.algoritmico.ios.Passepartout
CFG_APP_STORE_ID = 1433648537

View File

@ -1,4 +1,4 @@
#!/bin/sh
cwd=`dirname $0`
xcodeproj="$cwd/../Passepartout.xcodeproj/project.pbxproj"
$cwd/xcode-get-setting.sh $xcodeproj CURRENT_PROJECT_VERSION "([0-9]+)"
xcconfig="$cwd/../Passepartout/Config.xcconfig"
$cwd/xcconfig-get.sh $xcconfig CURRENT_PROJECT_VERSION

View File

@ -1,4 +1,4 @@
#!/bin/sh
cwd=`dirname $0`
xcodeproj="$cwd/../Passepartout.xcodeproj/project.pbxproj"
$cwd/xcode-get-setting.sh $xcodeproj MARKETING_VERSION "([0-9]\.[0-9]\.[0-9])"
xcconfig="$cwd/../Passepartout/Config.xcconfig"
$cwd/xcconfig-get.sh $xcconfig MARKETING_VERSION

12
ci/xcconfig-get.sh Executable file
View File

@ -0,0 +1,12 @@
#!/bin/bash
if [[ -z "$1" ]]; then
echo "Path to Xcode project required"
exit 1
fi
if [[ -z "$2" ]]; then
echo "Setting key required"
exit 1
fi
xcconfig="$1"
setting_key="$2"
grep $setting_key $xcconfig | sed -E "s/^.*${setting_key} = (.*)$/\1/"

View File

@ -8,10 +8,10 @@ if [[ -z "$2" ]]; then
exit 1
fi
if [[ -z "$3" ]]; then
echo "Setting regex required"
echo "Setting value required"
exit 1
fi
xcodeproj="$1"
xcconfig="$1"
setting_key="$2"
setting_pattern="$3"
grep $setting_key $xcodeproj | sed -E "s/^.*${setting_key} = ${setting_pattern};/\1/" | uniq | tr -d '\n'
setting_value="$3"
sed -i "" -E "s/^(.*${setting_key} =) .*$/\1 ${setting_value}/" $xcconfig

View File

@ -7,4 +7,5 @@ FL_VERSION_NUMBER_TARGET="Passepartout"
FL_BUILD_NUMBER_PROJECT="Passepartout.xcodeproj"
PILOT_BETA_APP_DESCRIPTION="Passepartout is your go-to app for VPN and privacy."
XCCONFIG_PATH="Passepartout/Config.xcconfig"
API_PACKAGE_PATH="Packages/App/Sources/CommonAPI/API"

View File

@ -15,9 +15,12 @@
fastlane_require "dotenv"
fastlane_require "fileutils"
load "xcconfig.rb"
Dotenv.load ".env.secret"
setup_ci if ENV["CI"]
xcconfig = ENV["XCCONFIG_PATH"]
api = ENV["API_PACKAGE_PATH"]
metadata = "fastlane/metadata"
logname = "CHANGELOG.txt"
@ -49,23 +52,32 @@ lane :bump do |options|
UI.user_error!("CHANGELOG editor cancelled")
end
end
version = options[:version]
build = options[:build]
increment_build_number(build_number: build)
unless version.nil? || version.empty?
increment_version_number_in_xcodeproj(version_number: version)
version = options[:version]
if build.nil? || build.empty?
build = xcconfig_get("../#{xcconfig}", "CURRENT_PROJECT_VERSION").to_i + 1
end
git_add(
path: [api, metadata, logname]
)
commit_version_bump(
message: "Bump version",
force: true
)
add_git_tag(
includes_lane: false,
sign: true
xcconfig_set("../#{xcconfig}", "CURRENT_PROJECT_VERSION", build)
unless version.nil? || version.empty?
xcconfig_set("../#{xcconfig}", "MARKETING_VERSION", version)
end
system("../scripts/copy-release-notes.sh")
git_commit(
path: [
xcconfig,
api,
metadata,
logname
],
message: "Bump version"
)
unless options[:no_tag]
add_git_tag(
includes_lane: false,
sign: true,
build_number: build
)
end
end
desc "Run Xcode tests"

View File

@ -3,4 +3,3 @@
# Ensure this file is checked in to source control!
gem 'fastlane-plugin-translate_gpt'
gem 'fastlane-plugin-versioning'

23
fastlane/xcconfig.rb Normal file
View File

@ -0,0 +1,23 @@
def xcconfig_set(path, key, value)
unless File.exist?(path)
raise "File not found: #{path}"
end
content = File.read(path)
pattern = /^(#{key}) = .*$/
replacement = "\\1 = #{value}"
modified_content = content.gsub(pattern, replacement)
File.write(path, modified_content)
end
def xcconfig_get(path, key)
unless File.exist?(path)
raise "File not found: #{path}"
end
pattern = /^#{key} = (.*)$/
File.foreach(path) do |line|
if (match = line.match(pattern))
return match[1]
end
end
nil
end

View File

@ -28,6 +28,10 @@ while [[ $# -gt 0 ]]; do
opt_no_log="no_log:true"
shift # past argument
;;
-nt)
opt_no_tag="no_tag:true"
shift
;;
-d)
opt_dry_run=1
shift # past argument
@ -47,8 +51,7 @@ set -- "${positional_args[@]}" # restore positional parameters
cwd=`dirname $0`
cmd_api="$cwd/update-bundled-api.sh"
cmd_release_notes="$cwd/copy-release-notes.sh"
cmd_fastlane="cd $cwd/.. && bundle exec fastlane bump $opt_version $opt_build $opt_since $opt_no_log"
cmd_fastlane="cd $cwd/.. && bundle exec fastlane bump $opt_version $opt_build $opt_since $opt_no_log $opt_no_tag"
if [[ -n $opt_dry_run ]]; then
echo "version = $opt_version"
@ -56,10 +59,10 @@ if [[ -n $opt_dry_run ]]; then
echo "since = $opt_since"
echo "no_api = $opt_no_api"
echo "no_log = $opt_no_log"
echo "no_tag = $opt_no_tag"
if [[ -z $opt_no_api ]]; then
echo "$cmd_api"
fi
echo "$cmd_release_notes"
echo "$cmd_fastlane"
exit 0
fi
@ -67,5 +70,4 @@ fi
if [[ -z $opt_no_api ]]; then
eval "$cmd_api"
fi
eval "$cmd_release_notes"
eval "$cmd_fastlane"