This documentation is available as Markdown for AI agents and LLMs. See the full Markdown index or append .md to any documentation URL.
PostHog 的 EAS Workflows 配方 从在 PostHog 中标记首次部署,到使用 EAS Workflows 实现分阶段发布、自动熔断开关和需审批的发布流程。
EAS Workflows 可以将 PostHog 操作作为 CI 流水线中的步骤运行。下面的每个配方都是一个可以直接复制使用的完整工作流,它们共同构建出一条完整的渐进式交付流水线:
简洁的更多配方列表 涵盖了更具体的需求。有关每个函数所接受的所有输入,请参阅 EAS Workflows 语法参考 。
开始使用
一条命令即可设置这些配方所需的一切。请从项目目录运行:
- eas integrations:posthog:connect
它会将一个 PostHog 项目关联到你的 Expo 项目,并将这些函数读取的凭据保存为 EAS 环境变量。使用 PostHog 指南会完整介绍设置过程。
当命令要求输入个人 API 密钥时,请使用“Source map upload”预设以及 feature_flag:read、feature_flag:write、query:read 和 annotation:write 作用域创建密钥。一个密钥即可覆盖本页中的所有配方。如果你之前使用权限范围更窄的密钥完成了连接,请创建一个新密钥,并将其设置为具有 Sensitive 可见性的 POSTHOG_CLI_API_KEY 环境变量 。
信息 在 GitHub 事件(例如推送到 main)上运行的工作流,需要将你的 EAS 项目关联到 GitHub 仓库。请参阅开始使用 EAS 工作流 。
在 PostHog 时间线中标记部署
每次发布更新时发送一个 PostHog 事件。这样,每次部署都会显示在 PostHog 数据中,你可以检查指标变化是否与某个版本发布相对应。
.eas/workflows/mark-deploy.yml name : Publish update and mark it in PostHog
on :
push :
branches : [ 'main' ]
jobs :
publish :
type : update
params :
branch : main
mark_deploy :
needs : [ publish]
steps :
- uses : eas/posthog_capture_event
with :
event : ota_update_published
properties :
eas/account : ${ { account.name } }
eas/project_id : ${ { app.id } }
eas/workflow_id : ${ { workflow.id } }
eas/update_id : ${ { needs.publish.outputs.first_update_group_id } }
eas/runtime_version : ${ { fromJSON(needs.publish.outputs.updates_json | | '[ ] ')[ 0 ] .runtimeVersion } }
branch : main
工作原理
update 作业会将 EAS Update 发布到 main 分支。
eas/posthog_capture_event 会在其运行后,使用标准 EAS 属性 记录此次部署。eas/account、eas/project_id 和 eas/workflow_id 来自始终可用的工作流上下文;eas/update_id 和 eas/runtime_version 来自更新作业的输出 。使用fingerprint运行时版本策略 时,运行时版本会根据项目的指纹 ,在原生运行时发生变化时随之更新。
由于未设置 distinct_id,该事件是匿名的,不会创建个人资料。
标注发布版本
发布更新时在 PostHog 中创建注释。注释会作为标记显示在项目中的每个图表上,因此你可以直接在受影响的图表上查看每次发布。
.eas/workflows/annotate-release.yml name : Annotate release in PostHog
on :
push :
branches : [ 'main' ]
jobs :
publish :
type : update
params :
branch : main
annotate :
needs : [ publish]
steps :
- uses : eas/posthog_annotation
with :
content : Published update for runtime ${ { fromJSON(needs.publish.outputs.updates_json | | '[ ] ')[ 0 ] .runtimeVersion } } to main
工作原理
update 作业会发布更新。
eas/posthog_annotation 会将注释固定在当前时间,内容中的运行时版本用于标识此次发布。
上传用于错误追踪的源代码映射
上传源代码映射,以便错误追踪能够将崩溃符号化回原始代码。源代码映射的上传方式取决于生成 bundle 的预打包任务。两种方式都需要按照使用 PostHog 指南完成 PostHog 设置。
build 会自行上传源代码映射。posthog-react-native/expo 配置插件会在原生构建期间上传源代码映射,因此该任务无需额外配置:
.eas/workflows/build-production.yml name : Build for production
on :
push :
branches : [ 'main' ]
jobs :
build :
type : build
params :
platform : ios
profile : production
更新只会发布 JavaScript,因此需要在发布后上传其源代码映射。update 任务无法运行额外步骤,并且源代码映射必须存在于执行上传操作的任务磁盘上。因此,请在自定义任务中使用 eas update 发布一个平台的更新,并在那里添加上传步骤:
.eas/workflows/update-with-sourcemaps.yml name : Publish update with source maps
on :
push :
branches : [ 'main' ]
jobs :
publish_update :
steps :
- uses : eas/checkout
- uses : eas/install_node_modules
- run : npx eas- cli@latest update - - branch main - - platform ios - - auto - - non- interactive
- uses : eas/posthog_upload_sourcemaps
with :
directory : dist
工作原理
eas update --platform ios 会发布更新,并将导出结果(包括源代码映射)保留在 dist 目录中。每个任务只导出一个原生平台:完整导出还会包含 Web bundle,而 PostHog 的 Hermes 上传会拒绝该 bundle。
eas/posthog_upload_sourcemaps 会将这些映射上传到 PostHog 错误追踪,因此来自该更新的堆栈跟踪可以符号化回原始代码。它使用PostHog Metro 配置 ,为每个 bundle 提供可将其与源代码映射匹配的区块 ID。有关符号化的工作原理,请参阅错误追踪 。
在标志后发布功能
将功能的发布状态保存在仓库中的文件里,并让工作流将其应用到 PostHog。发布功能或扩大其发布范围都会变成一个只修改一个文件的拉取请求。
.eas/feature-rollout.json {
"flag" : "new-checkout" ,
"rollout_percentage" : 10
}
.eas/workflows/feature-release.yml name : Apply the feature rollout from the repo
on :
push :
branches : [ 'main' ]
paths : [ '.eas/feature-rollout.json' ]
jobs :
publish :
type : update
params :
branch : main
read_rollout :
outputs :
flag : ${ { steps.rollout.outputs.flag } }
percent : ${ { steps.rollout.outputs.percent } }
steps :
- uses : eas/checkout
- id : rollout
run : |
set-output flag "$(node -p "require('./.eas/feature-rollout.json').flag")"
set-output percent "$(node -p "require('./.eas/feature-rollout.json').rollout_percentage")"
apply_rollout :
needs : [ publish, read_rollout]
steps :
- uses : eas/posthog_flag_rollout
with :
flag : ${ { needs.read_rollout.outputs.flag } }
active : true
rollout_percentage : ${ { needs.read_rollout.outputs.percent } }
工作原理
paths 筛选器仅在 .eas/feature-rollout.json 发生更改时运行此工作流,因此该文件就是定义发布状态的位置。
read_rollout 使用 set-output 读取文件,并通过该作业的 outputs 暴露这些值。
eas/posthog_flag_rollout 会在两个依赖项都完成后应用标志状态,因此只有在读取该标志的代码上线后,标志才会切换。
根据错误率逐步发布或回滚
向一小部分用户发布,观察错误率,然后让工作流做出决定。当错误率保持较低时,它会将功能标记扩大到所有用户。当错误率不理想时,它会关闭功能标记。无论哪种情况,中间都不需要有人盯着仪表板。
.eas/workflows/canary-rollout.yml name : Canary rollout that rolls forward or back
on :
push :
branches : [ 'main' ]
jobs :
publish :
type : update
params :
branch : main
canary :
needs : [ publish]
steps :
- uses : eas/posthog_flag_rollout
with :
flag : new- checkout
active : true
rollout_percentage : 25
error_gate :
needs : [ canary]
steps :
- uses : eas/posthog_wait_for_metric
with :
query : SELECT count() FROM events WHERE event = '$exception' AND timestamp > now() - INTERVAL 30 MINUTE
operator : lte
threshold : 5
interval_seconds : 60
timeout_seconds : 1800
full_rollout :
needs : [ error_gate]
steps :
- uses : eas/posthog_flag_rollout
with :
flag : new- checkout
rollout_percentage : 100
roll_back :
after : [ error_gate]
if : ${ { failure() } }
steps :
- uses : eas/posthog_flag_rollout
with :
flag : new- checkout
active : false
工作原理
update 作业会发布代码,然后 eas/posthog_flag_rollout 将其提供给 25% 的用户。
eas/posthog_wait_for_metric 会运行 HogQL 查询,并等待过去 30 分钟内的异常数量降至 5 个或更少。门槛通过后,full_rollout 会将功能标记扩大到 100%。如果糟糕的发布导致数量持续偏高,门槛会超时并失败,而 full_rollout 永远不会运行。
发生失败时,roll_back 会关闭功能标记。它使用 after 和 if: ${{ failure() }} ,因为 needs 依赖在这里无法正常工作。当 needs 依赖失败时,作业会在其 if 条件求值之前被跳过。failure() 反映整个工作流运行的状态,因此请确保此工作流专注于发布及其门槛。
发布 EAS Update channel,或在失败时回滚
上面的发布流程通过 PostHog 功能标志控制曝光范围。如果改用 EAS Update channel 百分比 进行发布,同一个门控机制会驱动 eas channel:rollout:发布更新,将一部分用户引导至该更新,观察错误率,然后将发布范围扩大到所有用户,或执行回滚。与这里的其他方案相比,它涉及更多 EAS 功能:更新任务、channel 发布、指标门控以及结果事件。
.eas/workflows/channel-rollout.yml name : 扩大或回滚的 Channel 发布
on :
push :
branches : [ 'main' ]
jobs :
publish :
type : update
params :
branch : rollout
start_rollout :
needs : [ publish]
steps :
- run : npx eas- cli@latest channel: rollout production - - action create - - branch rollout - - percent 10 - - runtime- version 1.0.0 - - non- interactive
error_gate :
needs : [ start_rollout]
steps :
- id : gate
uses : eas/posthog_wait_for_metric
with :
query : SELECT count() FROM events WHERE event = '$exception' AND timestamp > now() - INTERVAL 15 MINUTE
operator : lt
threshold : 10
interval_seconds : 60
timeout_seconds : 900
- uses : eas/posthog_capture_event
with :
event : channel_rollout_cleared
properties :
eas/account : ${ { account.name } }
eas/project_id : ${ { app.id } }
eas/workflow_id : ${ { workflow.id } }
error_count : ${ { steps.gate.outputs.value } }
widen :
needs : [ error_gate]
steps :
- run : npx eas- cli@latest channel: rollout production - - action end - - outcome republish- and- revert - - non- interactive
revert :
after : [ error_gate]
if : ${ { failure() } }
steps :
- run : npx eas- cli@latest channel: rollout production - - action end - - outcome revert - - non- interactive
工作原理
update 任务会将更新发布到 rollout 分支,然后 eas channel:rollout 会在 production channel 上启动发布,将 10% 的用户引导至新更新。--runtime-version 的值必须与已发布更新的运行时版本一致。
eas/posthog_wait_for_metric 会持续等待,直到最近 15 分钟内的异常数量保持在 10 以下,然后通过步骤的 value 输出记录通过门控时的数量。
门控通过后,widen 会使用 --outcome republish-and-revert 结束发布,将新更新发布给所有用户。
门控失败后,revert 会使用 --outcome revert 结束发布,将用户送回之前的更新。它使用了与功能标志回滚 相同的 after 加 if: ${{ failure() }} 模式。
在人工审批下将功能标记全面发布
在功能标记达到 100% 之前,于 EAS 控制面板中暂停工作流并请求明确审批。适用于不希望端到端自动化的发布流程。
.eas/workflows/approved-ga.yml name : Take a feature to GA with human approval
jobs :
approve :
name : Approve new- checkout GA?
type : require- approval
go_full :
needs : [ approve]
steps :
- uses : eas/posthog_flag_rollout
with :
flag : new- checkout
active : true
rollout_percentage : 100
bookkeeping :
needs : [ go_full]
steps :
- uses : eas/posthog_capture_event
with :
event : feature_went_ga
properties :
eas/account : ${ { account.name } }
eas/project_id : ${ { app.id } }
eas/workflow_id : ${ { workflow.id } }
flag : new- checkout
工作原理
require-approval 作业会暂停工作流,直到有人在 EAS 控制面板中批准或拒绝该操作。
如果获得批准,eas/posthog_flag_rollout 会将功能标记发布到 100%。如果被拒绝,该作业会失败,并跳过 go_full。
后续事件会记录该功能标记达到全面发布的时间。
使用终止开关关闭功能
只需一条命令即可为所有人关闭某项功能。此工作流没有 on 触发器,因此只有在你启动它时才会运行,例如在发生事故期间。
.eas/workflows/kill-switch.yml name : 立即禁用新结账
jobs :
disable_flag :
steps :
- uses : eas/posthog_flag_rollout
with :
flag : new- checkout
active : false
audit_trail :
needs : [ disable_flag]
steps :
- uses : eas/posthog_capture_event
with :
event : kill_switch_pulled
properties :
eas/account : ${ { account.name } }
eas/project_id : ${ { app.id } }
eas/workflow_id : ${ { workflow.id } }
flag : new- checkout
工作原理
使用以下命令运行:
- eas workflow:run kill-switch.yml
eas/posthog_flag_rollout 会关闭该标记,后续事件会记录这一操作。
在错误激增时自动关闭功能
这是上一节方案中的紧急开关,并连接到错误门控,因此部署后错误率激增时,它会自动关闭该功能。
.eas/workflows/auto-kill-switch.yml name : 在错误激增时自动关闭 new- checkout
on :
push :
branches : [ 'main' ]
jobs :
publish :
type : update
params :
branch : main
error_gate :
needs : [ publish]
steps :
- uses : eas/posthog_wait_for_metric
with :
query : SELECT count() FROM events WHERE event = '$exception' AND timestamp > now() - INTERVAL 10 MINUTE
operator : lt
threshold : 20
interval_seconds : 60
timeout_seconds : 600
auto_kill_switch :
after : [ error_gate]
if : ${ { failure() } }
steps :
- uses : eas/posthog_flag_rollout
with :
flag : new- checkout
active : false
- uses : eas/posthog_capture_event
with :
event : auto_kill_switch_pulled
properties :
eas/account : ${ { account.name } }
eas/project_id : ${ { app.id } }
eas/workflow_id : ${ { workflow.id } }
flag : new- checkout
工作原理
update 作业会发布更新,而 eas/posthog_wait_for_metric 会等待,直到过去 10 分钟内的异常数量低于 20。如果有问题的更新导致数量持续偏高,门控将超时并失败。
auto_kill_switch 作业使用与标记回滚 相同的 after 加 if: ${{ failure() }} 模式。
eas/posthog_flag_rollout 会关闭标记,执行与手动紧急开关相同的操作,并记录该开关是自动触发的。
用户采用后宣布发布
当有足够多的用户使用新更新后,发布一条 Slack 消息。该工作流会等待真实的采用情况,而不是在部署完成后立即宣布。
.eas/workflows/announce-on-adoption.yml name : Announce release once adopted
on :
push :
branches : [ 'main' ]
jobs :
publish :
type : update
params :
branch : main
adoption_gate :
needs : [ publish]
steps :
- uses : eas/posthog_wait_for_metric
with :
query : SELECT count(DISTINCT distinct_id) FROM events WHERE timestamp > now() - INTERVAL 1 HOUR
operator : gte
threshold : 50
interval_seconds : 120
timeout_seconds : 3600
announce :
needs : [ adoption_gate]
type : slack
environment : production
params :
webhook_url : ${ { env.SLACK_WEBHOOK_URL } }
message : The latest update is live and 50 or more users are on it.
工作原理
update 作业发布更新。
eas/posthog_wait_for_metric 会等待,直到过去一小时内至少有 50 位不同的用户发送事件。
slack 作业会在门控条件满足后宣布发布。将 SLACK_WEBHOOK_URL 作为 环境变量 设置在 EAS 上。
更多配方
针对更具体需求的简短配方。
等待特定事件
等待工作流,直到特定事件到达,例如部署后冒烟测试报告成功,而不是根据聚合指标进行门控。
.eas/workflows/wait-for-smoke-test.yml name : Wait for smoke test to pass
jobs :
wait_for_smoke_test :
steps :
- uses : eas/posthog_wait_for_query
with :
query : SELECT count() > 0 FROM events WHERE event = 'smoke_test_passed' AND timestamp > now() - INTERVAL 30 MINUTE
interval_seconds : 15
timeout_seconds : 600
eas/posthog_wait_for_query 会在查询返回 true 后解除等待。30 分钟的时间窗口可以防止旧的冒烟测试事件立即解除门控。
检查每晚的错误预算
按照计划运行门控,而不是在部署后运行,将其作为独立的健康检查。
.eas/workflows/error-budget.yml name : Nightly error- budget check
on :
schedule :
- cron : '0 6 * * *'
jobs :
assert_error_budget :
steps :
- uses : eas/posthog_wait_for_metric
with :
query : SELECT count() FROM events WHERE event = '$exception' AND timestamp > now() - INTERVAL 24 HOUR
operator : lt
threshold : 100
interval_seconds : 30
timeout_seconds : 60
on.schedule.cron 触发器独立于任何部署运行,因此它可以作为持续的健康检查,而不是针对特定发布的门控。
标记商店提交
对于原生版本,eas/posthog_capture_event 的工作方式与更新版本相同。
.eas/workflows/store-release.yml name : Build, submit to the store, mark it in PostHog
jobs :
build :
type : build
params :
platform : ios
profile : production
submit :
needs : [ build]
type : submit
params :
build_id : ${ { needs.build.outputs.build_id } }
profile : production
mark_release :
needs : [ submit, build]
steps :
- uses : eas/posthog_capture_event
with :
event : store_build_submitted
properties :
eas/account : ${ { account.name } }
eas/project_id : ${ { app.id } }
eas/workflow_id : ${ { workflow.id } }
eas/build_id : ${ { needs.build.outputs.build_id } }
eas/channel : ${ { needs.build.outputs.channel } }
platform : ios
profile : production
重要说明
凭据来自 connect 命令。 每个函数默认使用 eas integrations:posthog:connect 设置的环境变量,并且在需要覆盖时都接受 api_key 输入。要自行设置这些变量,请将以下内容添加为 EAS 环境变量 :eas/posthog_capture_event 使用 EXPO_PUBLIC_POSTHOG_API_KEY,其他所有函数使用 POSTHOG_CLI_API_KEY 和 POSTHOG_CLI_PROJECT_ID。语法参考 列出了每个函数所需的作用域。
超时的门控会使步骤失败。 eas/posthog_wait_for_metric 和 eas/posthog_wait_for_query 不接受 ignore_error 输入,因此未通过的门控会停止发布流程,而不是让流程继续。
条件满足后,门控会立即通过。 检查低错误数量的门控可能在第一次检查时就通过,包括部署后立即检查的情况,此时用户可能尚未使用新更新。当你需要先让错误有机会显现时,请将其与采用率门控结合使用,例如用户采用后宣布发布 中的门控。
将查询限定到当前运行。 事件和指标查询会返回历史数据。添加 timestamp > now() - INTERVAL ... 过滤条件,或添加当前运行专用的属性,以免旧事件立即解除门控。设置 release tagging 后,每个客户端事件都会附加 eas/update_id、eas/channel 和 eas/runtime_version,因此你可以使用 properties['eas/update_id'] 过滤门控,将其限定到确切的发布版本。