Why a caption checker works locally but fails in CI
Consider a hypothetical museum website that ships captions in several languages. Its team bundles a validation script and an allowlisted vocabulary file inside a local composite action. The workflow runs from the repository root, but the action expects assets relative to its own directory. A naive `./scripts/check.sh` path may resolve against the wrong working directory after a refactor. GitHub provides the `github.action_path` context and corresponding `GITHUB_ACTION_PATH` environment variable for composite actions. The purpose is to locate trusted packaged resources, not to expand the action’s permissions or approve a release.
Distinguish the action directory from the workspace
The runner’s workspace holds checked-out repository files, while a composite action’s location identifies the directory containing its packaged scripts and metadata. These are not interchangeable. A local action at `.github/actions/caption-check` and a remote pinned action can have different installation paths, but code inside the composite action can use its own action path. Before changing the workflow, sketch the boundary between repository inputs, action resources, and temporary outputs. A caption file path provided by a pull request belongs to the first category; a vetted parser distributed with the action belongs to the second.
Use composite action metadata rather than shell guesses
GitHub’s action metadata reference requires `runs.using: composite` for this kind of action and describes `runs.steps` entries with `run`, `uses`, and explicit shells where applicable. The official tutorial demonstrates assigning `GITHUB_ACTION_PATH` from `${{ github.action_path }}` in a step’s `env`. The metadata reference also shows using the variable to invoke a script shipped with the action. Prefer this documented structure to assuming `$PWD` points to the action directory. Do not interpolate a user-supplied path directly into a shell command.

Keep the bundled checker and its data under review
A trustworthy composite action can ship a small script, a versioned rule set, and a schema for caption files. Review these assets in code review and pin external action dependencies as your organization requires. Never fetch an executable from an unreviewed URL during the validation run to compensate for a missing file. `GITHUB_ACTION_PATH` is a location helper; it does not verify checksums, signatures, or the trustworthiness of the code in that directory. The release owner still needs to approve changes to both the action metadata and its bundled executable.
Pass caption inputs as data instead of executable text
When a pull request adds a new caption file, treat its contents, filename, and metadata as untrusted input. Pass selected values through a declared input or controlled environment variable, validate them, and quote filesystem paths in shell commands. Avoid placing a pull request title or subtitle content inside a `run:` script expression, where special characters could alter shell syntax. Apply explicit file extension and directory checks so a validator cannot be redirected to secrets or unrelated build directories. A clean path lookup is only one layer in this boundary.
Prove which directory the composite step sees
In a safe test repository, log a non-sensitive statement that the bundled script exists at the expected action path, without dumping the entire filesystem or environment. Compare the resolved action directory with the checked-out workspace. Invoke the checker with a synthetic caption fixture and a deliberately invalid fixture; the second should fail for a specific validation reason rather than an accidental file-not-found error. The illustrated path examples are conceptual. We have not executed a workflow, inspected a private repository, or measured the effect of this change.

Handle relative resources and working-directory changes
If a script loads a vocabulary list or JSON schema through a relative path, make that path relative to the bundled action directory rather than to whatever directory the caller selected with `working-directory`. Either pass the absolute resource path into the script or make the script resolve its own location with care. Document which resources are inside the action and which files arrive from the calling workflow. This distinction prevents a later monorepo restructuring from silently selecting the wrong dictionary while still returning a green exit code.
Keep a failure from being mistaken for editorial approval
A passing caption checker can establish that timing format, language tags, and other machine-checkable rules met the script’s requirements. It cannot prove translation quality, consent to publish a recorded voice, or historical accuracy. Save a short, non-sensitive outcome showing which input set was checked and which action revision ran. Require a separate reviewer for sensitive captions. Do not use `continue-on-error` to make mandatory failures look green, and avoid writing private transcript text into public job summaries or artifacts.

Review the action for supply-chain and permissions risks
Because a composite action runs steps in the job context, it is not automatically a separate sandbox. Minimize the job token permissions and secrets, pin trusted third-party actions, and avoid mixing untrusted pull-request execution with privileged deployment jobs. A path string supplied by GitHub does not upgrade filesystem security. If an action resource is missing, stop the check instead of falling back to whichever executable appears on the runner PATH. That failure mode is preferable to silently running a different tool with the same name.
How We Research
We cross-checked GitHub’s composite-action tutorial, metadata syntax reference, and contexts reference for the `github.action_path` and `GITHUB_ACTION_PATH` behavior. This is a hypothetical caption-QA workflow; it does not describe an executed GitHub job or validated subtitle translation. Runner versions, repository policies, and permissions must be checked in the project where the action is deployed.
Frequently Asked Questions
No. The action path points to the action’s own resources in a composite action, while the workspace holds checked-out repository content.
The contexts reference describes github.action_path as supported for composite actions. Do not rely on it in arbitrary workflow steps.
Only if that is needed and the directory contains reviewed executables. Direct invocation of a known bundled script is often easier to audit.
No. Keep external inputs untrusted, quote paths, minimize token permissions, and avoid privileged execution of unreviewed code.
No. It can verify mechanical rules but not consent, nuanced translation quality, or factual interpretation.
