Allow aw.yml packages to install shared JavaScript modules - #60536
Conversation
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
There was a problem hiding this comment.
🟢 Approval recommended
The destination validation, ownership integration, tests, and documentation consistently implement the requested support.
Pull request overview
Adds package support for installing and managing shared .mjs and .cjs workflow helpers.
Changes:
- Allows validated JavaScript module destinations under
.github/workflows/shared/. - Integrates shared scripts with package ownership and lifecycle handling.
- Adds tests, documentation, schema guidance, and a changeset.
File summaries
| File | Description |
|---|---|
pkg/parser/schemas/aw_manifest_schema.json |
Documents supported shared scripts. |
pkg/cli/add_package_ownership.go |
Recognizes scripts as package resources. |
pkg/cli/add_package_manifest_resources.go |
Validates .mjs and .cjs destinations. |
pkg/cli/add_package_manifest_resources_test.go |
Tests allowed and rejected paths. |
docs/src/content/docs/specs/repository-package-manifest-specification.md |
Updates the package specification. |
docs/src/content/docs/reference/aw-yml-package-manifest.md |
Updates user-facing reference documentation. |
.changeset/patch-aw-yml-shared-js-resources.md |
Records the patch release change. |
Review details
- Files reviewed: 7/7 changed files
- Comments generated: 0
- Review effort level: Balanced (auto)
Note
Copilot is running an experiment and ran this review at Balanced.
💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.
|
🧠 Matt Pocock Skills Reviewer has completed the skills-based review. ✅ Warning Firewall blocked 1 domainThe following domain was blocked by the firewall during workflow execution:
To allow these domains, add them to the network:
allowed:
- defaults
- "github.com"See Network Configuration for more information.
|
|
✅ Ponytail Reviewer completed successfully! Lean already. Ship. Warning Firewall blocked 1 domainThe following domain was blocked by the firewall during workflow execution:
To allow these domains, add them to the network:
allowed:
- defaults
- "ab.chatgpt.com"See Network Configuration for more information.
|
|
No ADR enforcement needed: PR does not have the 'implementation' label and has ≤100 new lines of code in business logic directories.
|
|
Warning Threat Detection Engine Failure — The analysis engine could not complete. This is a tooling failure, not a security finding. What happenedThe threat detection engine failed to produce results. Review the workflow run logs for details.
|
|
✅ Test Quality Sentinel completed test quality analysis. Warning Threat Detection Engine Failure — The analysis engine could not complete. This is a tooling failure, not a security finding. What happenedThe threat detection engine failed to produce results. Review the workflow run logs for details.
|
There was a problem hiding this comment.
Impeccable Review — refactor_cleanup
Applied distill + extract lens (backend validation/schema change extending an existing resource-allowlist pattern; no UI surface).
Findings: none blocking or high-signal. The change:
- Reuses the existing
validateManifestResourceDestinationswitch andisPackageResourceDestinationpredicate consistently across parse, ownership-tracking, and stale-removal paths (add_package_manifest_resources.go,add_package_ownership.go), keeping install/update/remove lifecycle uniform with the pre-existing.github/aw/andISSUE_TEMPLATEcases. - Case-insensitive
.mjs/.cjssuffix check plusWorkflowsDirSlash+"shared/"prefix correctly excludes sibling dirs likeshared-adjacent/(verified via the new test file andgo test ./pkg/cli/... -run TestValidateManifestResourceDestinationSharedWorkflowScripts, all passing). - Path traversal is still rejected upstream by
cleanManifestRelativePathbefore this validator runs, so.github/workflows/shared/../runtime.mjsis blocked (covered by the added test). - Docs/spec/schema/changeset are all updated consistently with the new allowlist entry.
Ran go build ./... and the targeted test — both succeed.
🧵 Reviewed using Impeccable skills by Impeccable Skills Reviewer · copilot · sonnet50 · 36.8 AIC · ⌖ 14.6 AIC · ⊞ 8.4K
There was a problem hiding this comment.
Skills-Based Review 🧠
Applied /tdd and /codebase-design to this small, well-scoped manifest-resources change. Two suggestions posted inline; nothing blocking.
📋 Key Themes & Highlights
Key Themes
- Test coverage gap: unit tests cover the validation predicate well, but there's no end-to-end test exercising install + ownership-record round trip for the new
.mjs/.cjsdestination type, unlike the existingISSUE_TEMPLATEcoverage. - Duplicated matching logic: the
shared/prefix + extension check is implemented independently in bothvalidateManifestResourceDestinationandisSharedWorkflowScriptDestination, which could drift if either is updated later.
Positive Highlights
- ✅ Path traversal and extension restrictions are preserved and explicitly tested (including the
../traversal negative case). - ✅ Docs (reference, spec) and the changeset are updated consistently with the code change.
- ✅ Package ownership/ lifecycle wiring (
isPackageResourceDestination) was updated alongside validation, keeping install/update/removal consistent.
Warning
Firewall blocked 1 domain
The following domain was blocked by the firewall during workflow execution:
github.com
To allow these domains, add them to the network.allowed list in your workflow frontmatter:
network:
allowed:
- defaults
- "github.com"See Network Configuration for more information.
🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · copilot · sonnet50 · 119.9 AIC · ⌖ 15 AIC · ⊞ 10.4K
Comment /matt to run again
| "destination": ".github/workflows/shared/../runtime.mjs", | ||
| }, "aw.yml") | ||
| require.Error(t, err) | ||
| } |
There was a problem hiding this comment.
[/tdd] Good unit coverage for validateManifestResourceDestination, but there's no end-to-end test proving a .mjs/.cjs resource actually gets written to disk and recorded in package ownership metadata (the existing TestAddWorkflowsWithTracking_PackageResourceWritesOwnershipRecord pattern in add_command_test.go only covers the ISSUE_TEMPLATE destination type).
💡 Suggested addition
Add a variant of TestAddWorkflowsWithTracking_PackageResourceWritesOwnershipRecord (or extend it via table-driven cases) using DestinationPath: ".github/workflows/shared/runtime.mjs", asserting the file is written verbatim and the ownership record's destination field matches. This closes the gap between "destination string is accepted" and "the new resource type round-trips through install + ownership + removal correctly," which is the actual behavior users depend on.
@copilot please address this.
There was a problem hiding this comment.
Added TestAddWorkflowsWithTracking_PackageSharedScriptResourceWritesOwnershipRecord covering the .mjs destination end-to-end (write to disk + ownership record) in 7730687.
|
|
||
| func validateManifestResourceDestination(destination string) error { | ||
| switch { | ||
| case strings.HasPrefix(destination, constants.WorkflowsDirSlash+"shared/"): |
There was a problem hiding this comment.
[/codebase-design] The new shared/ case duplicates the extension-matching logic already present in isSharedWorkflowScriptDestination (in add_package_ownership.go) with slightly different mechanics (strings.HasPrefix+TrimPrefix here vs. filepath.Clean+ToSlash there). Two independent implementations of "what counts as a shared JS resource" is a seam that will drift silently if one is updated later.
💡 Suggested consolidation
Extract a single helper, e.g. isSharedWorkflowScriptPath(destination string) (remaining string, ok bool), used by both validateManifestResourceDestination and isSharedWorkflowScriptDestination/isPackageResourceDestination. This keeps the acceptance rule (prefix + .mjs/.cjs suffix) defined in exactly one place, matching the deep-module principle of a single source of truth for a piece of domain logic reused across the manifest-parsing and ownership-tracking modules.
@copilot please address this.
There was a problem hiding this comment.
validateManifestResourceDestination now delegates to isSharedWorkflowScriptDestination for the shared-script acceptance check, so the prefix+extension rule is defined in one place (7730687).
|
@copilot run pr-finisher skill |
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
|
🎉 This pull request is included in a new release. Release: |
Package manifests rejected
.mjsand.cjsresources targeting.github/workflows/shared/, preventing packages from shipping JavaScript helpers alongside shared workflows.Manifest support
.mjsand.cjsresources under.github/workflows/shared/.Package lifecycle
Documentation