Fastlane高级用法:自定义脚本的调用

5,330 阅读6分钟

前言

fastlane在移动应用开发中可以很方便的做流程自动化,由于它是基于Ruby开发的,所以对Ruby的支持相对友好。但除了自定义action外,我们还可以调用自定义脚本,比如PythonShell。这里我们研究一下如何将它制作成远端脚本库,并且能够调用Python脚本。

一、初始化fastlane仓库

1. 创建仓库

这里我们新建一个Fastlane目录,并且执行以下命令:

fastlane init

执行完成后可以看到目录结构是这样的:

.
├── Gemfile
├── Gemfile.lock
└── fastlane
    ├── Appfile
    └── Fastfile

1 directory, 4 files

项目中一般我们会用到Fastfile,这是脚本的入口文件。为了方便测试,我们可以修改一下该文件。

2. 修改Fastfile

我们添加一行输出即可:

default_platform(:ios)

platform :ios do
  desc "Description of what the lane does"
  lane :custom_lane do
    # add actions here: https://docs.fastlane.tools/actions
    UI.command_output "hello world"
  end
end

在终端中测试一下:

image-20220629133844451

执行fastlane custom_lane可以看到有hello world的日志输出,到这里其实Fastfile中的custom_lane就被成功调用了。通常我们可以在Fastfile中创建我们自定义的脚本,也可以把它们封装成action

3. 创建action

直接执行fastlane new_action并输入action名称即可,注意action命名是蛇形命名法并非驼峰。

image-20220629134956779

这里我们创建了一个convert_excelaction。注意目录结构的变化,此时fastlane目录下多了一个actions目录,里面有我们刚刚创建的convert_excel.rb

4. 修改action

这里我们只修改convert_excel.rb中的2个方法self.runself.available_options

def self.run(params)
  # fastlane will take care of reading in the parameter and fetching the environment variable:
  UI.message "Parameter input: #{params[:input]}"
end

def self.available_options
  # Define all options your action supports.
  # Below a few examples
  [
    FastlaneCore::ConfigItem.new(key: :input,
                                 env_name: "EXCEL_DIR",
                                 description: "excel_dir",
                                 is_string: true, # true: verifies the input is a string, false: every kind of value
                                 default_value: false), # the default value if the user didn't provide one
  ]
end

为了调用action我们还需要在Fastfile中添加调用入口:

desc "convert_excel"
  lane :convert_excels do |options|
  convert_excel(options)
end

注意lane的名称不能和action名称重复。

5. 调用action

直接在终端执行fastlane convert_excels input:/somepath/excel.xlsx

image-20220629142135715

执行完成后可以看到action被调用了,传入的参数input也被正常打印。

至此,Fastlane的常规使用方法我们已经基本了解,接下来我们调用自定义的python脚本。

二、配置自定义脚本

1. 创建Python脚本

这里我们在fastlane目录下创建scripts目录用于存放自定义脚本convert.py

#!/usr/bin/python
# -*- coding: UTF-8 -*-

from optparse import OptionParser


# 解析器
def addParser():
    parser = OptionParser()
    parser.add_option("-i", "--file",
                      default="./Excel/excel.xlsx",
                      help="excel file path",
                      metavar="file")
    return parser.parse_args()


# 入口
if __name__ == "__main__":
    print("Hello, Python!")
    (options, args) = addParser()
    print("options: {0}, args: {1}").format(options, args)

此时的目录结构应该是这样的:

.
├── Gemfile
├── Gemfile.lock
└── fastlane
    ├── Appfile
    ├── Fastfile
    ├── README.md
    ├── actions
    │   └── convert_excel.rb
    ├── report.xml
    └── scripts
        └── convert.py

3 directories, 8 files

2. 调用Python脚本

这里我们修改一下convert_excel.rb,在此action中调用python脚本。

def self.run(params)
  # fastlane will take care of reading in the parameter and fetching the environment variable:
  input = params[:input]
  UI.message "Parameter input: #{input}"
  
  script_path = File.expand_path("./fastlane/scripts/convert.py")
  system "python #{script_path} -i #{input}"
end

然后在终端执行fastlane convert_excels input:/somepath/excel.xlsx

image-20220629150705707

这里我们看到python脚本在action中能够正常调用,参数也能够传递过去。

至此,本地Fastlane调用自定义python脚本已经基本完成了。接下来我们将脚本库发布到git远端,本地直接调用远端脚本库。

三、配置Git远端脚本库

1. 创建远端库

这里我们在gitee上创建Fastlane仓库。

image-20220629152501153

2. 修改本地库并上传

这里我们在本地库中添加一个.gitignore文件来忽略一些文件上传到git

# OS X
.DS_Store


# Xcode
build/
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata/
*.xccheckout
profile
*.moved-aside
DerivedData
*.hmap
*.ipa


# Bundler
.bundle


# Add this line if you want to avoid checking in source code from Carthage dependencies.
# Carthage/Checkouts
Carthage/Build


# Fastlane
Gemfile.lock
fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots/**/*.png
# fastlane/README.md
fastlane/test_output

修改完成后将本地库上传到远端。

3. 调用远端库

这里我们新建一个目录测试一下

image-20220629154406309

目录中包含了fastlane/Fastfile文件,该文件只有一行代码,其实是调用了import_from_git,我们把远端库的地址传入即可。

接下来我们执行fastlane custom_lane

image-20220629160419707

通过日志可以看出,执行fastlane custom_lane其实是从远端拉取脚本库执行的。custom_lane并没有调用action,只是简单输出hello world,这里可以正常执行。那么我们测试一下调用action会发生什么,这里直接执行fastlane convert_excels input:/somepath/excel.xlsx

image-20220629161049429

很明显action可以调用,但是在之后调用python脚本报错了。

4. 远端库报错问题

这里我们可以看一下日志中的错误信息,can't open file '/Users/HiUSB/Desktop/脚本测试/Demo/fastlane/scripts/convert.py': [Errno 2] No such file or directory。很明显是找不到脚本文件,而这个路径也是有问题的。因为我们是拉取远端脚本执行,所以在/Demo/fastlane目录下只有Fastfile文件,并没有actions或者scripts目录,找不到文件自然就报错了。那么如何解决这个问题?我们预期的结果应该是本地库和远端库中的脚本都能正常执行。

四、解决报错问题

1. 解决思路

既然报错说找不到文件,那么我们得想办法让它找到。怎么找?分析日志可以看出,import_from_git执行时是将远端库clone到本地一个临时目录,那么我们要是能够让clone的目录有固定位置是不是可以很容易找到对应的文件呢?接下来我们查看一下import_from_git

2. import_from_git的配置

在官网中搜索import_from_git,可以查看到它的详细用法:

Parameters
KeyDescriptionDefault
urlThe URL of the repository to import the Fastfile from
branchThe branch or tag to check-out on the repositoryHEAD
dependenciesThe array of additional Fastfiles in the repository[]
pathThe path of the Fastfile in the repositoryfastlane/Fastfile
versionThe version to checkout on the repository. Optimistic match operator or multiple conditions can be used to select the latest version within constraints
cache_pathThe path to a directory where the repository should be cloned into. Defaults to nil, which causes the repository to be cloned on every call, to a temporary directory

注意cache_path这个参数,这是git缓存目录,可以指定clone的位置。回到Demo/fastlane/Fastfile,我们修改一下:

import_from_git(url: "https://gitee.com/hiusb/fastlane.git", branch: "master", cache_path: ".cache/fastlane")

git缓存目录有了,我们还需要让action中的python调用能够找到它。我们可以创建一个action作为辅助,项目中一些通用方法可以放在其中。

3. 创建helper

这里回到本地库Fastlane,直接执行fastlane new_action并输入action名称helper。创建完成后删除多余代码并按如下修改:

module Fastlane
  module Actions
    class HelperAction < Action
      # 本地fastlane目录
      def self.local_fastlane_dir
        local_dir = Dir.pwd + "/fastlane/.cache/fastlane/fastlane.git/fastlane"
        if not File.directory?(local_dir)
          local_dir = Dir.pwd + "/fastlane"
        end
        return local_dir
      end

      # scripts目录
      def self.scripts_dir
        local_fastlane_dir + "/scripts"
      end
    end
  end
end

4. 修改convert_excel

convert_excel.rb中对于python文件路径的获取方式需要修改一下:

def self.run(params)
  # fastlane will take care of reading in the parameter and fetching the environment variable:
  input = params[:input]
  UI.message "Parameter input: #{input}"
  
  script_path = HelperAction.scripts_dir + ("/convert.py")
  system "python #{script_path} -i #{input}"
end

5. 上传到远端并测试

我们在本地库中测试正常,将Fastlane本地库的修改推送的远端。接下来我们测试远端调用是否报错,回到Demo目录(这里务必按照步骤2修改git缓存),执行fastlane convert_excels input:/somepath/excel.xlsx

image-20220629172157221

没有报错,自定义python脚本正常调用,结果符合预期。至此,一个远端脚本库配置完成,任何接入了fastlane/Fastfile的目录都能调用远端库中的脚本。

总结

Fastlane不仅仅是移动开发中的自动化流程工具,合理的利用它我们可以完成更多的功能。代码发版、工程打包及分发、图片压缩及清理、本地化字符串管理等都可以高效完成。更方便是脚本库放在远端,需要使用的地方只要添加依赖即可。如果脚本有问题,只需要修改远端脚本库代码,真正做到了一处维护,任意处调用。