Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

wei18/local-composite-action

Use this GitHub action with your project
Add this Action to an existing workflow or create a new one
View on Marketplace
Open more actions menu

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

37 Commits
37 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

📦 local-composite-action

English | 繁體中文

Test Release Marketplace License

Reference sibling actions with uses: ./../org/repo — pure bash, no tokens, no permissions, no extra checkout

Reference sibling actions in your own repository with uses: ./../org/repo/... — even when your composite action is consumed remotely. Pure bash, no extra checkout, no tokens, no permissions.

😖 The problem

Your repository ships a composite action that calls another local action in the same repo:

# org/repo/.github/actions/main/action.yml
runs:
  using: 'composite'
  steps:
    - uses: ./.github/actions/helper   #

This works inside your own workflows, but the moment someone consumes your action remotely (uses: org/repo/.github/actions/main@v1), it fails with a confusing error:

Error: Can't find 'action.yml' under '...'. Did you forget to run actions/checkout?

That's because uses: ./... resolves against the consumer's $GITHUB_WORKSPACE, not your action's own checkout under _actions/.

✨ The fix

Add one step at the top of your composite action, then reference your local actions through ./../org/repo/...:

# org/repo/.github/actions/main/action.yml
runs:
  using: 'composite'
  steps:
    - uses: wei18/local-composite-action@v1
      with:
        action_repository: ${{ github.action_repository }}
        action_path: ${{ github.action_path }}

    - name: Run a local action from the same repository
      uses: ./../org/repo/.github/actions/helper   #

    - name: Run another one
      uses: ./../org/repo/.github/actions/another-helper   #

Important

Write the ./../org/repo/... part in all lowercase — a lowercase symlink is always created, regardless of how the caller's uses: line is cased.

🔍 How it works

The runner checks your action out under _actions/, while uses: ./<path> resolves relative to $GITHUB_WORKSPACE. This action bridges the two with a single symlink:

/home/runner/work
├── _actions/org/repo/v1/   ◄─┐  your action's checkout
├── org/repo ─────────────────┘  symlink created by this action
└── consumer/consumer/          $GITHUB_WORKSPACE

uses: ./../org/repo/<path> then resolves through the symlink into your checkout — the exact same commit the consumer pinned, with paths matching your repo layout.

  • ✅ No permissions: required
  • ✅ No tokens or secrets
  • ✅ No network access — pure bash, zero dependencies

Why not just actions/checkout again?

local-composite-action second actions/checkout
Extra clone none — reuses the existing checkout full fetch per job
Private repos works out of the box needs a token/PAT
Version drift always the consumer's pinned ref ref must be duplicated and kept in sync
Workspace untouched risks clobbering consumer files

What about the upcoming $/ syntax?

GitHub has proposed a native $/ syntax (e.g. uses: $/path/to/action) that resolves sibling actions in the same repository at the same SHA. As of mid-2026 it is still a proposal with no release date.

local-composite-action native $/ (proposed)
Available today not yet shipped
Same-repo sibling actions ✅ once shipped
Cross-repository references ✅ any repo already under _actions* out of scope

* pass that repository's org/repo as action_repository explicitly.

Once $/ ships, prefer it for same-repo references — this action remains useful for cross-repository layouts, which $/ explicitly does not cover.

📥 Inputs

Name Description Required
action_repository Your action's org/repo. Pass ${{ github.action_repository }}
action_path Your composite action's path. Pass ${{ github.action_path }} Recommended*

* Without action_path, the repository is located by searching the runner's _actions directory, which can be ambiguous if the same repository is used at multiple refs within one job. Passing it makes resolution exact.

🛠️ Troubleshooting

Could not find action repository (org/repo) from path (...) The provided path doesn't sit inside your repository's checkout and the _actions fallback found nothing. Pass both inputs as shown in the fix.

action_repository is empty GITHUB_ACTION_REPOSITORY is empty when an action is referenced by a local path (uses: ./...). In that case symlinks aren't needed — or pass your org/repo explicitly.

Can't find 'action.yml' on the ./../org/repo/... step Check that the ./../org/repo part is all lowercase and that this action ran before the failing step in the same composite action.

🧪 Tested

Every push and pull request runs a unit test suite against simulated runner layouts, plus a self-referential integration test — this repository uses its own action to test itself.

📄 License

MIT © wei18

Releases

Used by

Contributors

Languages

Morty Proxy This is a proxified and sanitized view of the page, visit original site.