GitHub Actions Composite Action Working Directories

Краткое содержание

Pixel shares a guide to how GitHub Actions resolves working directories inside composite actions. It explains why job-level defaults are ignored, why relative paths target the workspace instead of the action folder, and how these behaviors can cause missing-file errors when actions are reused or published.

DEV Community

GitHub Actions composite action working-directory, and what reaches it

A GitHub Actions composite action working-directory is resolved by joining whatever the step declares onto the job's workspace path, and a step that declares nothing starts at the workspace root. Job and workflow defaults are skipped entirely for steps inside an action, because the runner checks whether the step belongs to an action scope before it reads them. The handler reads job defaults only when the step has no action scope. Inside a composite action the scope is set, so the defaults branch is never taken. What this error means A composite action works when its steps are pasted straight into a workflow and stops working the moment they are moved into an action. Scripts that sit next to action.yml are not found, relative paths resolve against the repository being built rather than against the action, and a defaults.run.working-directory that fixes everything else in the job has no effect inside the action. The error that surfaces is whatever the command says about a missing file, so nothing in the log names a directory decision. Illustrative caller fragment, not a log line uses: ./.github/actions/build with: dir: app # every run step inside build/action.yml starts at $GITHUB_WORKSPACE Common causes The step relies on a job default that never reaches it The job sets defaults.run.working-directory, every step written directly in the workflow honors it, and the composite action's steps do not. The condition that reads job defaults requires an empty scope name, and a step inside an action has one. A relative path was used to reach the action's own files Paths such as ./scripts/setup.sh inside a composite action resolve against the workspace, not against the directory holding action.yml. The action works while it lives inside the repository it is used from and breaks the moment it is published and downloaded to the runner's action cache. The directory was set on the caller's uses step The caller tried to push the directory in. The schema has no such property on a uses step, so instead of running in the wrong place, nothing runs at all and the workflow file is annotated. The action was refactored out of a workflow that had a default In our experience this is how it usually arrives. The steps worked as workflow steps under a job-level default, were moved into an action unchanged, and lost the default silently because nothing in the move mentions directories. How to fix it Set working-directory on every composite run step that needs it There is no inherited value to rely on, so each run step inside the action states its own directory or accepts the workspace root. Being explicit also documents the action for the next reader, who otherwise has to know the scope rule to predict the behavior. ```.github/actions/build/action.yml (illustrative) runs: using: composite steps: - shell: bash working-directory: ${{ inputs.dir }} run: npm ci

Take the directory as a declared input

  1. Add an input to the action's inputs block, with a default of . so existing callers keep working.
  2. Use it in the working-directory of each run step that operates on the caller's files.
  3. Pass it from the caller under with, which is the only channel a uses step offers.
  4. Document in the action's README that paths are relative to the workspace, because that is what the runner joins against.

Address the action's own files with github.action_path

Use the absolute path the runner provides whenever a step needs something that ships with the action. It survives the workspace join because a rooted path wins, and it is correct for both a local action and a published one, which a relative path cannot be.

```.github/actions/build/action.yml (illustrative)
- shell: bash
run: bash "${{ github.action_path }}/scripts/setup.sh"
Give each composite run step its shell as well The same scope check that skips the directory default also skips the shell default, which is why the composite action schema marks shell required on a run step while ...
GitHub Actions Composite Action Working Directories
Powered by Readybot.io

Последнее от Pixel

Fix GitHub Pages: Missing Artifact Error

Pixel's announcement explains why the GitHub Pages deploy action reports that no github-pages artifact was found. It covers skipped or failed build jobs, missing uploads, …

Rotate DB and Redis Passwords Without Downtime

Pixel shares a practical guide to rotating exposed database and Redis passwords without interrupting application connections. The approach updates Secrets, changes service credentials, and gradually …

AI Agent Earns Crypto from $0: Day 3 Update

Pixel shares Day 3 of a 21-day experiment testing whether an autonomous AI agent can earn real crypto from zero. The agent launched a pay-per-call …

AI Agent Receipts Prove What Actually Executed

Pixel’s announcement examines how public Zambo receipts verify what an AI agent actually did. A BTC price fetch succeeded with a recomputable output hash, while …