{{ message }}
Repository navigation
Support self-referencing $/ uses: syntax in the pin tool - #84
Merged
Merged
Conversation
`uses: $/…` references an action or reusable workflow in the same repo as the defining file, resolved at the running commit. It is inherently pinned — parallel to the existing `./…` local treatment — so the tool records no lockfile entry, never flags it unpinned, and passes it through untouched. A trailing `@ref` is invalid (a self-reference always resolves to the running ref) and is rejected. Detection lives in internal/workflowfile (IsSelfRepoAction / SelfRepoRefHasVersion); no change to the shared actions-lockfile/go parser is required, since the CLI classifies `$/` before calling ParseActionRef, mirroring how `./` is handled. ExtractActionRefs now returns a RefScan that splits `$/` values into valid self-repo refs and the malformed `$/…@ref` form. Two new finding categories carry this through the pipeline: self-repo-action (benign, info) and invalid-self-repo-ref (error). The offline --verify-local path also rejects `$/…@ref`. Nested `$/` inside a fetched composite resolves as a same-tarball self-reference (parent repo at its own ref): still traversed for cross-repo transitive deps, but records no new pin or edge. Sub-issue github/actions-dispatch#800.
`--migrate-local-actions` rewrites same-repo `uses: ./…` composite action references to the `uses: $/…` self-reference form. Only `./…` paths that resolve to an in-repo action file (action.yml/action.yaml) are rewritten, which is the equivalence guard that makes `$/` a safe drop-in for `./`; reusable-workflow calls are never candidates. The flag is skipped under --no-fix and also works alongside --verify-local. Existing local-action findings now point at the flag as a remediation hint. Kept separate from core `$/` support so it can be dropped for a leaner PR.
Adds three offline (--verify-local) scenarios to the shared catalog.yml so both the Go scenario loader and the Ruby integration harness cover `$/`: - self_repo_action_valid: bare `$/` at step level verifies clean (inherently pinned, no lockfile entry required). - self_repo_reusable_workflow_valid: `$/` at reusable-workflow call level (jobs.<id>.uses) verifies clean. - self_repo_ref_rejected: `$/…@ref` exits 1 with invalid-self-repo-ref. Covers core `$/` support; independent of the --migrate-local-actions commit.
Adds two layers of coverage for `$/` self-references nested several levels
deep inside fetched composites, where the transitive closure must still be
walked and pinned:
- Unit (resolver): TestResolveAllRecursiveSelfRepoDeepMultiLevel drives a
four-level `$/` chain in one repo, a shared `$/` child reached via two
parents (dedup), a `$/` nested inside a *different* repo (proving `$/`
binds to the enclosing tarball, not the entry repo), and a diamond back
to an already-seen cross-repo tarball. Asserts the exact 5-tarball closure,
no self-parent edges on collapsed `$/` siblings, and precise parent sets.
- Integration (catalog): self_repo_deep_transitive is a real_repo scenario
against nodeselector/actions-test-fixtures. Its deep-self-ref workflow
pulls a remote composite whose internals chain `$/` three levels deep; the
tool fetches the tarball, walks the chain, and pins the cross-repo
transitive dep (actions-test-fixtures-b) reached through it.
The fixtures (deep-self-ref/{,-b,-c} + the workflow) were added to
nodeselector/actions-test-fixtures@main separately.
Previously the migration only rewrote `./…` -> `$/…` in workflow files, so a composite action that internally used `uses: ./helper` was left on the unsupported `./` form. It now also sweeps every in-repo composite action definition (action.yml/action.yaml under the repo root, `.git` skipped) and rewrites their local steps too, including ones nested several directories deep. The equivalence guard is unchanged: a `./…` is only rewritten when it resolves to an in-repo action file, so unresolvable or out-of-repo paths are left untouched. This does not change the hard limit that a `./…` inside a *remote* fetched composite cannot be onboarded (CompositeLocalPathError) — that is not our repo to rewrite. Adds DiscoverCompositeActionFiles plus unit coverage for the workflow + composite sweep and the discovery walk.
Adds a deep variant of the composite-local-path limit: a $/ self-reference chain several levels deep whose leaf uses `uses: ./…`. Because the tool cannot resolve a ./ inside a remotely fetched composite, the whole chain is non-onboardable even though every hop before the leaf is a valid $/ ref, and the block surfaces transitively rather than at the entry action. - catalog: composite_local_path_blocked_deep (real repo, references the new deep-blocked fixture in actions-test-fixtures) asserting the failure names the leaf's ./ path. - unit: TestResolveAllRecursiveCompositeLocalPathErrorDeep exercises the same chain offline via seeded tarballs, no token needed.
Adds an end-to-end command test for --migrate-local-actions over a scratch repo that mixes a local composite ref with a real remote action. It drives the actual pipeline with a stubbed resolver and asserts both sides of the mutation in one pass: - workflow: ./my-action -> $/my-action, while actions/setup-go@v6.0.0 keeps its ref (the pin lives in the detached lockfile); - in-repo composite action.yml files rewritten too, including the nested one (./helper -> $/helper, ./nested/deep -> $/nested/deep); - lockfile: pins actions/setup-go to its resolved commit and records nothing for the $/ self refs (they are inherently pinned). Previous migration coverage only asserted file contents; this closes the gap by proving the lockfile stays correct across the ./ -> $/ rewrite.
…atalog The migrate+pin end-to-end behaviour was only asserted at the Go unit level. This adds an integration-harness scenario that runs the real binary with --migrate-local-actions over a repo mixing a local composite ref with a pinnable remote action, and asserts both sides of the mutation: - the workflow and in-repo composite action.yml files are rewritten from ./ to $/ (including a nested composite), and the unresolvable ./nonexistent is left alone; - the lockfile pins the real remote dep (actions/checkout) and records nothing for the $/ self refs. To express this the catalog gains a few capabilities: - fixtures.files: lay down arbitrary repo-relative files (composite action.yml definitions) before the run; - expect.files_contain / files_exclude: assert substrings in repo files after the run; - expect.lockfile_excludes: assert the lockfile omits a substring (e.g. $/). Harness and Go catalog schema are extended to match. Existing scenarios are unaffected.
…wording Aligns naming with the locked ecosystem decision: internal code identifiers use the SelfRepository family (dropping the SelfRepo abbreviation), and user-facing finding-category tokens use the canonical self-reference phrasing. The frozen contracts (FF literal actions_self_repository, wire value selfRepository) are not present in this repo and are untouched. Identifiers renamed (SelfRepo* -> SelfRepository*): IsSelfRepoAction, SelfRepoRefHasVersion, SelfRepoRefs, SelfRepoRefErrs, SelfRepoAction (category), InvalidSelfRepoRef (category), MigrateLocalActionsToSelfRepo, selfRepoPrefix, selfRepoFinding, and their tests. selfrepo.go/selfrepo_test.go renamed to selfrepository*.go. Category tokens (user-facing): self-repo-action -> self-reference-action invalid-self-repo-ref -> invalid-self-reference Integration catalog scenario names self_repo_* renamed to self_reference_* and the token assertion updated to match. Comments/test descriptions using "self-repo" reworded to "self-reference".
Adds a "Where does a test belong?" section to AGENTS.md so agents (and humans) pick the right layer instead of reflexively asserting the same claim in both Go and the catalog. Captures the two-layer model (hermetic Go vs real-binary catalog) and the CI pitfalls that have bitten us: needs_token scenarios only run in the non-blocking live job, only stub-tagged scenarios run in the blocking stub job, and same-assertion duplication across layers is cost, not defense-in-depth.
Canonical term is "self repository" ($/ = same repository at running SHA), not "self reference" — reverting the wording introduced in the prior follow-up. Go identifiers stay in the SelfRepository family. Finding-category tokens (user-facing): self-reference-action -> self-repository-action invalid-self-reference -> invalid-self-repository-ref Integration catalog scenarios self_reference_* -> self_repository_* and the token assertion updated to match. README heading and prose, plus code comments/test descriptions, reworded from "self-reference"/"self-referencing" to "self repository" (using "self repository reference" where a noun reads better). Frozen contracts (actions_self_repository, selfRepository) remain absent and untouched.
# Conflicts: # internal/pipeline/run.go
There was a problem hiding this comment.
Pull request overview
Adds $/ self-references to workflow parsing, diagnostics, resolution, migration, and documentation.
Changes:
- Classifies and validates
$/references. - Resolves nested self-references in remote composites.
- Adds
--migrate-local-actionsand integration coverage.
Show a summary per file
Review details
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 27/27 changed files
- Comments generated: 3
- Review effort level: Medium
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Implements
$/self-referencinguses:support in the pin/lockfile tool.