从通用平台导入和调用特定平台的Fastlane车道

9
我有一个React Native应用,这个应用包含一个共同的目录,里面分别有iOS和Android两个目录。 我想能够独立地发布(执行一个lane)iOS或Android版本,所以我在每个平台的目录中设置了fastlane init(在每个平台目录中创建了两个fastlane/Fastfile文件)。 Android的Fastfile大致包含以下内容:
platform :android do
  lane: release_android do
    ...
  end

关于iOS:

platform :ios do
  lane: release_ios do
    ...
  end

现在我还手动创建了一个位于通用目录中的 fastlane/Fastfile 文件,其内容如下:

import '../ios/fastlane/Fastfile'
import '../android/fastlane/Fastfile'

lane :release_all do
  release_android
  release_ios
end

然而,当我从主目录运行fastlane release_all时,它会出现错误:Could not find action or lane 'release_android'

你有什么想法吗?难道不可能从一个通用的lane中调用特定于平台的lane吗?

环境

fastlane 1.96.0

3个回答

4

这不是理想的解决方案,因为它会将您的车道执行包裹在另一个车道中,但我们在相当于release_all的地方这样做,不过我想知道是否允许并行运行这些操作:

sh "fastlane ios beta"
sh "fastlane android beta"

好的解决方案!我想知道最近的Fastlane更新是否能够正确启用它。 - mllm
这不是最好的解决方案,因为使用2FA时,您的lane会挂起,因为它在非交互模式下运行。不幸的是,我没有解决这个问题的方法,除了使用单个Fastfile。 - Luke Brandon Farrell
1
@LukeBrandonFarrell 答案是让你的 AppleStore 账户管理员或账户持有人为你创建一个 API 密钥。Google 也有类似的解决方案。 - airtonix
是的,很有道理。一个密钥可以绕过两步验证! - Luke Brandon Farrell

2

我曾经遇到相同的问题,在一番调查之后,我发现在 fastlane 上有一个问题与此确切情况相关。

你可以使用核心 fastlane 代码来切换车道,而不是通过 shell 来调用,这样就可以像 fastlane 切换车道一样。

为了避免链接失效,我在这里发布代码片段。

你可以使用车道管理器切换到另一个车道,并将平台、车道、参数或甚至环境详细信息传递给指定的车道。

请参阅源代码此处

以下是一个例子:

lane :release_all do |options|
  Fastlane::LaneManager.cruise_lane("android", "release", options)
  Fastlane::LaneManager.cruise_lane("ios", "release", options)
end

platform :android do
  lane :release do |options|
     #do android release
  end
end

platform :ios do
  lane :release do |options|
     #do iOS release
  end
end

这应该是被接受的答案。只需记得在你的主要Fastfile文件的顶部导入平台Fastfiles即可。 - Adam Bridges

0

像这样:

package.json

packages/fastlane/
  Fastfile
  config.yml

apps/someapp/
  package.json
  ios/
  android/
  app/
    App.tsx
    App.test.tsx
  fastlane/
    Fastfile
    config.yml

package.json

{
  "name": "yourmonorepo",
  "version": "0.0.1",
  "workspaces": [
    "apps/*",
    "packages/*"
  ],
  "scripts": {
    "app:someapp": "yarn workspace @you/someapp",
    ...
  }
}

packages/fastlane/config.yml

codesigning:
  git_url: git+ssh://git@your.vcs/reponame.git
  branch: master

packages/fastlane/Fastfile

fastlane_require 'config'

# this ends up always being `packages/fastlane`
HERE_DIR = File.expand_path(__dir__)
# different per app, but in the case of `someapp` it'll be `apps/someapp`
APP_ROOT = File.expand_path(File.dirname(Dir.pwd))
# the root of the repo, where your root package.json is
REPO_ROOT = File.expand_path('../..', __dir__)
STAGE_DEV = "development"
STAGE_PROD = "production"

Config.setup do |config|
    config.use_env = true
    config.env_prefix = 'YOU_FASTLANE'
    config.env_separator = '__'
    config.env_converter = :downcase
    config.env_parse_values = true
end

Settings = Config.load_files(
    "#{__dir__}/config.yml",
    "#{Dir.pwd}/config.yml"
)

APPLICATION_ID = Settings.application.id
CRYPTEX_GITURL = Settings.codesigning.git_url
CRYPTEX_BRANCH = Settings.codesigning.branch

lane :setup do
  Fastlane::LaneManager.cruise_lane(
    'ios',
    'keyfile_get',
    {
      'stage' => STAGE_DEV
    }
  )
  Fastlane::LaneManager.cruise_lane(
    'ios',
    'keystore_get',
    {
      'stage' => STAGE_DEV
    }
  )
  Fastlane::LaneManager.cruise_lane(
    'android',
    'keyfile_get',
    {
      'stage' => STAGE_DEV
    }
  )
  Fastlane::LaneManager.cruise_lane(
    'android',
    'keystore_get',
    {
      'stage' => STAGE_DEV
    }
  )
end

platform :android do
  lane :keystore_get do |options|
    stage = options[:stage] || STAGE_DEV
    UI.message("Fetched android #{stage} keystore from codesigning repo #{CRYPTEX_REPO}")
  end

  lane :keyfile_get do |options|
    stage = options[:stage] || STAGE_DEV
    UI.message("Fetched android #{stage} keyfile from codesigning repo #{CRYPTEX_REPO}")
  end

  lane :release_prod do
    # do magic here
  end
end

platform :ios do
  lane :keystore_get do |options|
    stage = options[:stage] || STAGE_DEV
    UI.message("Fetched ios #{stage} keystore from codesigning repo #{CRYPTEX_REPO}")
  end

  lane :keyfile_get do |options|
    stage = options[:stage] || STAGE_DEV
    UI.message("Fetched ios #{stage} keyfile from codesigning repo #{CRYPTEX_REPO}")
  end

  lane :release_prod do
    # do magic here
  end
end

apps/someapp/package.json

{
  "name": "@you/someapp",
  "version": "0.0.1",
  "scripts": {
    "fastlane": "fastlane"
  }
}

apps/someapp/fastlane/config.yml

application:
  id: com.you.someapp

apps/someapp/fastlane/Fastfile

应用程序/someapp/fastlane/Fastfile

$VERBOSE = nil

import '../../../packages/fastlane/Fastfile'

现在你可以运行:

yarn app:someapp fastlane setup

或者

yarn app:someapp fastlane ios keystore_get stage:'development'
yarn app:someapp fastlane android keystore_get stage:'development'

在CI中,你甚至可以做到:

YOU_FASTLANE__CODESIGNING__GIT_URL=https://github.com/your/repo.git \
  yarn app:someapp fastlane ios release_prod
YOU_FASTLANE__CODESIGNING__GIT_URL=https://github.com/your/repo.git \
  yarn app:someapp fastlane android release_prod

这里有一些额外的内容:

  • yarn工作区以便于管理monorepo
  • ruby config gem 以便于实现比dotenv更好的功能

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接