Monorepo Support
A single GitHub repository can host more than one independently-deployed PlatformApplication — for example my-app-api and my-app-frontend, or an app and a server pair. This page covers how to lay out the .platform folder and wire the dispatch workflow so each sub-application deploys on its own, without one clobbering another's manifests.
This page is about deployment manifests — how many PlatformApplications one repository can dispatch. It's unrelated to NX-Based Monorepo Workflow or the multi-stack CI/CD example, which are about build tooling for multiple source projects in one repo. The two are orthogonal — a repo can use either build style and still dispatch one or many PlatformApplications.
What You'll Learn
- The
.platform/kubernetes/layout for multiple sub-applications in one repo - The
resource-base-pathdispatch input that makes this possible - How this affects namespaces and the generated
.platformrepository folders
Folder Layout
By default, a repository's .platform/kubernetes/ tree describes exactly one application — see Platform Folder Anatomy. For a monorepo, nest one such tree per sub-application under a directory named for that sub-application:
.platform
└── kubernetes
├── my-app-api
│ ├── base
│ │ ├── application.yaml
│ │ ├── application_customizations.yaml
│ │ └── kustomization.yaml
│ └── dev
│ ├── application_patch.yaml
│ └── kustomization.yaml
└── my-app-frontend
├── base
│ ├── application.yaml
│ ├── application_customizations.yaml
│ └── kustomization.yaml
└── dev
├── application_patch.yaml
└── kustomization.yaml
Each sub-application's tree is otherwise identical to the single-app case — same files, same purpose, just one level deeper.
Use the sub-application's own PlatformApplication name (metadata.name in its application.yaml) as the subdirectory name — my-app-api, my-app-frontend, and so on — rather than a shorter or unrelated label. The same value then flows through as directory-name and the last segment of resource-base-path below, so the folder name, the namespace, and the PlatformApplication name all match. That alignment is what makes kubectl get platformapplication -n my-app-api and .platform/kubernetes/my-app-api/ refer to the same thing at a glance.
The base/ folder itself doesn't strictly have to live under .platform/kubernetes/<sub-app>/ today — but every environment overlay for a given sub-application (dev/, stg/, prd/) currently does. resource-base-path sets a single prefix per dispatch call, and the workflow appends /<environment> to it, so a sub-application can't have its environments split across different resource-base-path locations — keep dev, stg, and prd for the same sub-application together under the same subdirectory, as shown above.
Wiring the Dispatch
The Platform Application Manifest Dispatch action needs one call per sub-application, each with:
- A distinct
directory-name— this is what becomes the namespace and the folder name in the org's.platformrepository. - A
resource-base-pathpointing at that sub-application's folder, without the environment segment — the consumer workflow appends/<environment>itself.
- name: Update API Manifest
uses: p6m-actions/platform-application-manifest-dispatch@v1
with:
repository: ${{ github.repository }}
image-name: "my-app-api"
directory-name: "my-app-api"
environment: "dev"
digest: ${{ steps.build-api.outputs.digest }}
update-manifest-token: ${{ secrets.P6M_UPDATE_MANIFEST_TOKEN }}
platform-dispatch-url: ${{ vars.P6M_PLATFORM_DISPATCH_URL }}
# Resolves to .platform/kubernetes/my-app-api/dev
resource-base-path: ".platform/kubernetes/my-app-api"
- name: Update Frontend Manifest
uses: p6m-actions/platform-application-manifest-dispatch@v1
with:
repository: ${{ github.repository }}
image-name: "my-app-frontend"
directory-name: "my-app-frontend"
environment: "dev"
digest: ${{ steps.build-frontend.outputs.digest }}
update-manifest-token: ${{ secrets.P6M_UPDATE_MANIFEST_TOKEN }}
platform-dispatch-url: ${{ vars.P6M_PLATFORM_DISPATCH_URL }}
# Resolves to .platform/kubernetes/my-app-frontend/dev
resource-base-path: ".platform/kubernetes/my-app-frontend"
In both calls, directory-name and the last segment of resource-base-path are the same value — the PlatformApplication's own name — for the reason noted above.
Repeat both the directory-name/resource-base-path pair in promote.yaml for any environment beyond dev — using the same values as build.yaml for a given sub-application is what keeps build and promote pointed at the same folder.
resource-base-pathresource-base-path: ".platform/kubernetes/my-app-api/dev" would resolve to .platform/kubernetes/my-app-api/dev/dev. The dispatch consumer always appends /<environment> on top of whatever resource-base-path you give it.
Backward compatibility
Omitting resource-base-path (or passing an empty string) preserves the original single-application behavior: the base resolves to .platform/kubernetes/<environment>, exactly as it did before this input existed. Existing single-PlatformApplication repos need no changes.
Not to be confused with resource-directory-name
platform-application-manifest-dispatch also has an older, unrelated resource-directory-name input. It's still accepted and forwarded, but it does not affect where the dispatch consumer looks for manifests — resource-base-path is the input for a monorepo layout.
Result
Each dispatch call produces its own folder in the organization's .platform repository — kubernetes/my-app-api/dev/kustomization.yaml and kubernetes/my-app-frontend/dev/kustomization.yaml in the example above — each referencing the matching subdirectory back in your application repo. ArgoCD's ApplicationSet picks up both folders as independent Applications. See Platform Repository Anatomy and ArgoCD Integration for how that sync works.
Namespaces
Because directory-name drives the Kubernetes namespace, each sub-application needs its own distinct value — the same rule that normally applies per-repository in Changing Your Application Namespace now applies per (repository, directory-name) pair. Don't reuse a directory-name across sub-applications, and don't reuse one that's already in use by an unrelated repo.
Related
- Platform Dispatch Action — the action configured above
- Platform Folder Anatomy — the single-application folder shape this pattern repeats per sub-app
- Platform Repository Anatomy — the generated folders on the platform side
- ArgoCD Integration — how ArgoCD turns those folders into running workloads