Skip to content

[steps] Support local composite functions in hook steps - #4062

Open
sswrk wants to merge 5 commits into
szymonswierk/eng-22387-steps-unify-no-if-gating-policyfrom
szymonswierk/eng-22387-steps-composite-functions-in-hooks
Open

[steps] Support local composite functions in hook steps#4062
sswrk wants to merge 5 commits into
szymonswierk/eng-22387-steps-unify-no-if-gating-policyfrom
szymonswierk/eng-22387-steps-composite-functions-in-hooks

Conversation

@sswrk

@sswrk sswrk commented Jul 23, 2026

Copy link
Copy Markdown
Member

Why

Hook steps currently reject uses: ./... local composite functions. Users should be able to reuse the same composites in hooks as in the main workflow.

How

A composite function used in a hook is expanded into its inner steps at parse time, the same way it is in the main workflow, and the whole expansion becomes a single hook entry. The step's if: gates the expansion as a whole.

Hook construction now takes a catalog of composite functions. Without it, referencing a composite fails with a missing-function error instead of the previous "not supported in hooks" error.

Wiring reading the composite functions files will be added in follow-up PRs in the stack.

Test Plan

Added unit tests.

@linear-code

linear-code Bot commented Jul 23, 2026

Copy link
Copy Markdown

ENG-22387

sswrk commented Jul 23, 2026

Copy link
Copy Markdown
Member Author

@codecov

codecov Bot commented Jul 23, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 62.23%. Comparing base (e693624) to head (72786a9).

Additional details and impacted files
@@                                    Coverage Diff                                     @@
##           szymonswierk/eng-22387-steps-unify-no-if-gating-policy    #4062      +/-   ##
==========================================================================================
+ Coverage                                                   62.22%   62.23%   +0.01%     
==========================================================================================
  Files                                                         995      995              
  Lines                                                       44754    44764      +10     
  Branches                                                     9412     9415       +3     
==========================================================================================
+ Hits                                                        27845    27855      +10     
  Misses                                                      15462    15462              
  Partials                                                     1447     1447              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@sswrk
sswrk force-pushed the szymonswierk/eng-22387-steps-unify-no-if-gating-policy branch from ccd27cf to 88b25ed Compare July 23, 2026 16:17
@sswrk
sswrk force-pushed the szymonswierk/eng-22387-steps-composite-functions-in-hooks branch 2 times, most recently from e118ae0 to 5a88848 Compare July 23, 2026 17:06
@sswrk
sswrk force-pushed the szymonswierk/eng-22387-steps-unify-no-if-gating-policy branch from 88b25ed to afe2ad9 Compare July 23, 2026 17:06
@sswrk
sswrk force-pushed the szymonswierk/eng-22387-steps-unify-no-if-gating-policy branch from afe2ad9 to de031b5 Compare July 24, 2026 11:43
@sswrk
sswrk force-pushed the szymonswierk/eng-22387-steps-composite-functions-in-hooks branch 2 times, most recently from 642f105 to 40b60f7 Compare July 24, 2026 11:49
@sswrk
sswrk force-pushed the szymonswierk/eng-22387-steps-unify-no-if-gating-policy branch 2 times, most recently from 73ece96 to be7ec02 Compare July 24, 2026 12:31
@sswrk
sswrk force-pushed the szymonswierk/eng-22387-steps-composite-functions-in-hooks branch 2 times, most recently from fd5922a to 44fec11 Compare July 24, 2026 13:02
@sswrk
sswrk force-pushed the szymonswierk/eng-22387-steps-unify-no-if-gating-policy branch 2 times, most recently from 0236cea to f14d4f6 Compare July 24, 2026 14:12
@sswrk
sswrk force-pushed the szymonswierk/eng-22387-steps-composite-functions-in-hooks branch from 44fec11 to 56907d3 Compare July 24, 2026 14:12
@sswrk
sswrk force-pushed the szymonswierk/eng-22387-steps-unify-no-if-gating-policy branch from f14d4f6 to fb5d85f Compare July 24, 2026 14:40
@sswrk
sswrk force-pushed the szymonswierk/eng-22387-steps-composite-functions-in-hooks branch from 56907d3 to a107305 Compare July 24, 2026 14:41
@sswrk
sswrk force-pushed the szymonswierk/eng-22387-steps-unify-no-if-gating-policy branch from fb5d85f to 0a629b7 Compare July 24, 2026 14:59
@sswrk
sswrk force-pushed the szymonswierk/eng-22387-steps-composite-functions-in-hooks branch from a107305 to 95e91de Compare July 24, 2026 14:59
@sswrk
sswrk force-pushed the szymonswierk/eng-22387-steps-unify-no-if-gating-policy branch from 0a629b7 to 32f79bd Compare July 24, 2026 15:16

@hSATAC hSATAC left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few non-blocking nits. Most of them are about composite behaviour that predates this PR rather than anything it introduces, so they are all fine to split out into a separate PR if you would rather keep this one focused.

Comment thread packages/steps/src/CompositeFunctionExpander.ts Outdated
Comment thread packages/steps/src/hooks.ts Outdated
Comment thread packages/steps/src/BuildWorkflow.ts Outdated
Comment thread packages/steps/src/hooks.ts
Comment thread packages/steps/src/hooks.ts

@hSATAC hSATAC left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing I noticed while reviewing this: I don’t think this PR is doing anything wrong, but it does make an existing behavior difference more likely to surface for users.

Today, when a single hook entry expands into multiple steps, the later steps are gated differently depending on which side the hook runs on:

  • In a before_* hook, if an earlier step fails, later steps without an if: are skipped.
  • In an after_* hook, later steps still run.

This PR preserves that existing behavior. The difference is that, until now, multi-step hook entries could only come from function groups that we own. We don’t have many function groups, and users are also unlikely to use them inside hooks, so this difference probably hasn’t been very visible in practice.

With composite functions, users can now define and reuse the same multi-step unit themselves:

# .eas/functions/publish/function.yml
runs:
  steps:
    - run: ./login.sh
    - run: ./push.sh

When used in steps:, ./push.sh is skipped if ./login.sh fails. When the same composite is used in after_build, ./push.sh still runs. I verified this behavior on the branch.

I think this could be surprising because the author of a composite may not know where it will eventually be used, so the behavior isn’t something they can fully account for inside the composite itself.

I don’t think this needs to block the PR, but I wanted to flag it so we can decide whether we want to document the difference, align the default behavior for after_* hooks, or keep it as-is.

One related detail if we document it: success() and failure() inside a composite reflect the overall job status, not the result of the previous step. That means if: ${{ success() }} is not a reliable fail-fast guard inside an after_* hook, since the hook may already be running after the job has failed.

To express “only run if the previous step succeeded,” users would need to pass that state explicitly, for example:

- id: login
  run: |
    ./login.sh
    set-output ok true
  outputs: [ok]

- run: ./push.sh
  if: ${{ steps.login.outputs.ok == 'true' }}

The same behavior applies to function groups, so whatever we decide here could cover both.

@sswrk
sswrk force-pushed the szymonswierk/eng-22387-steps-unify-no-if-gating-policy branch from 336986e to bfe042d Compare July 28, 2026 12:58
@sswrk
sswrk force-pushed the szymonswierk/eng-22387-steps-composite-functions-in-hooks branch from 98ef96f to ff9cb50 Compare July 28, 2026 12:58
@sswrk

sswrk commented Jul 28, 2026

Copy link
Copy Markdown
Member Author

@hSATAC Thank you for noting that, and yes, this was done like that for the sake of consistency. But taking a step back, as a user I'd expect composite functions/function groups to fast-fail within them even in the after_* hook (and then let the next steps in the hook run).

Corrected the behavior for both composite functions and function groups.

@sswrk
sswrk force-pushed the szymonswierk/eng-22387-steps-composite-functions-in-hooks branch from ff9cb50 to 4a56ee2 Compare July 28, 2026 13:11
@sswrk
sswrk force-pushed the szymonswierk/eng-22387-steps-unify-no-if-gating-policy branch from bfe042d to c692851 Compare July 28, 2026 15:30
@sswrk
sswrk force-pushed the szymonswierk/eng-22387-steps-composite-functions-in-hooks branch from 4a56ee2 to 70ce854 Compare July 28, 2026 15:30
@sswrk
sswrk force-pushed the szymonswierk/eng-22387-steps-unify-no-if-gating-policy branch from c692851 to f9f51cc Compare July 29, 2026 09:01
@sswrk
sswrk force-pushed the szymonswierk/eng-22387-steps-composite-functions-in-hooks branch from 70ce854 to 3702906 Compare July 29, 2026 09:01
@sswrk
sswrk force-pushed the szymonswierk/eng-22387-steps-unify-no-if-gating-policy branch from f9f51cc to e693624 Compare July 29, 2026 09:26
@sswrk
sswrk force-pushed the szymonswierk/eng-22387-steps-composite-functions-in-hooks branch from 3702906 to 7136a56 Compare July 29, 2026 09:27
@github-actions

Copy link
Copy Markdown

⏩ The changelog entry check has been skipped since the "no changelog" label is present.

@sswrk
sswrk requested a review from hSATAC July 29, 2026 13:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no changelog PR that doesn't require a changelog entry

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants