Skip to content

Support source-to-destination mappings for inert nested packages #52770

Description

@Dongbumlee

Problem

Nested aw.yml packages intentionally treat .github/** entries as repository-root-relative (see #41790). This makes it impossible for a distribution repository to keep executable workflow assets inert under a nested package directory and install them into .github/** in the consuming repository.

A distribution layout such as:

repo/
  factory/
    aw.yml
    payload/
      workflows/controller.yml
      workflows/reviewer.md

needs to install as:

.github/workflows/controller.yml
.github/workflows/reviewer.md

The current manifest accepts only path strings and cannot express separate source and destination paths. Moving the source files to repository-root .github/workflows/ makes them active in the distribution repository, which is unsafe for packages containing deterministic controllers.

This is a feature request, not a regression report: current .github/** behavior matches ADR/PR #41790.

Expected capability

Allow package entries to declare a package-relative source and repository-relative destination while preserving existing string-entry behavior.

Illustrative syntax (maintainers may choose another shape):

includes:
  - source: payload/workflows/reviewer.md
    destination: .github/workflows/reviewer.md
    kind: agentic-workflow
  - source: payload/workflows/controller.yml
    destination: .github/workflows/controller.yml
    kind: action-workflow

Security and compatibility requirements

  • Existing string entries remain backward compatible.
  • source is resolved relative to the package root, including nested packages.
  • destination is resolved relative to the consuming repository root.
  • Reject absolute paths, .., symlinks, destination collisions, duplicate basenames, and writes outside approved namespaces.
  • Continue compiling agentic Markdown and copying deterministic YAML verbatim.
  • Never execute package-provided post-install shell code.
  • Preserve manifest-scoped source tracking for gh aw update.

Agentic implementation plan

  1. Schema and model

    • Update pkg/parser/schemas/aw_manifest_schema.json so includes accepts the current string form or an object containing validated source, destination, and optional kind.
    • Extend the package manifest model in pkg/cli/add_package_manifest.go with a resolved entry carrying both paths.
  2. Resolution

  3. Installation/update

    • Thread destination paths through WorkflowSpec and package install/update logic.
    • Compile .md entries using their installed destination name and copy raw .yml entries verbatim.
    • Detect multiple package entries targeting the same destination before any writes occur.
  4. Tests

    • Add nested-package tests where the remote fetch must request factory/payload/..., while installed output targets .github/workflows/....
    • Cover root packages, nested packages, mixed legacy/object entries, path traversal, absolute paths, collisions, symlinks, duplicate destinations, and update/source tracking.
    • Add an integration test for both gh aw add and gh aw add-wizard.
  5. Documentation/specification

    • Update the repository package manifest specification and reference docs.
    • Explicitly document the existing special rule: legacy string .github/** entries are repository-root-relative, while object-form source is package-relative.

Acceptance criteria

  • A nested package can keep all workflow sources outside repository-root .github/** and install them into the consuming repository's .github/workflows/**.
  • The distribution repository's workflows remain inert.
  • Existing manifests retain current behavior.
  • add, add-wizard, and update use identical mapping semantics.

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions