m

module
v0.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 18, 2026 License: Apache-2.0

README

m

m is the source-only Go CLI for declaring an RFL-style platform in Git, provisioning its GCP/GKE infrastructure through Pulumi Automation API, bootstrapping one central Argo CD control plane, registering runtime clusters, releasing immutable images, delivering declared secret versions, and reporting metadata status. It has no image, routing, or deployment owner of its own.

Install

Install the latest tagged version from source:

go install github.com/rustforlife/m/cmd/m@latest

Linux amd64 and arm64 archives are also attached to each GitHub release. m --version reports the tagged version.

Development

Go 1.26 and the module lock files own the build and dependency contract.

Pulumi Automation API executes locally by default on the invoking laptop or CI runner through state.execution: local; state.backend: pulumi-cloud remains the checkpoint owner and does not imply remote execution.

go test ./...
go vet ./...
go run ./cmd/m --help

The no-cloud integration test exercises init, doctor, provider bootstrap, environment plan/up, Argo bootstrap, cluster registration, and status with temporary Git state and fake provider commands. It never contacts GCP.

Normal workflow

Start with non-secret answers, then review and commit the generated .m/ state before bootstrapping Argo.

m init -f answers.yaml
m doctor
m provider bootstrap gcp-main
m plan -e ops
m up -e ops
m app up argocd -e ops
m secret set argocd/repository-private-key -e ops -f private-key.pem
m secret set argocd/repository-write-private-key -e ops -f private-key.pem
m app up gitops-promoter -e ops
m secret set gitops-promoter/github-app-private-key -e ops -f private-key.pem
m render
git add .m && git commit
m bootstrap
m plan -e dev
m up -e dev
m register -e dev
m kubeconfig -e dev -f /tmp/m-dev.kubeconfig
m status

Piped secret input requires --yes because stdin carries the payload and cannot also answer the confirmation prompt.

plan, workflow plan, doctor, status, secret list, and secret status are read-only apart from empty Pulumi stack metadata allowed by the specification. render replaces only the intentional .m/generated-gitops/ boundary. up, workflow up, bootstrap, register, release, and secret set require confirmation unless --yes is supplied. m never commits, pushes, opens a pull request, changes branch protection, deploys an application outside Argo, reads a secret through a user-facing command, or destroys provider resources.

m kubeconfig -e ENVIRONMENT -f PATH writes one mode-0600 GKE kubeconfig through the active gcloud credential. The destination must not already exist; the command does not grant cloud IAM, Kubernetes RBAC, database access, or application privileges.

After every declared environment exists and at least one promoted Git application declares image.publish: true plus its immutable source.repositoryId, run m artifacts up. Run it again after provisioning a new environment or changing declared image publishers; up performs its own preview, while standalone m artifacts plan is only a read-only preview. The shared artifacts stack derives the regional deployable-images/<application> path and owns the registry, cleanup policy, cross-project node readers, and repository-ID-bound publisher identities; source-repository workflows still build, sign, and publish.

After every declared provider and environment plus the artifacts stack exist, use m workflow plan and m workflow up. The dedicated Pulumi stack owns only the provider-qualified secret-writer, environment-project, and image-publisher variables consumed by checked-in workflows. It uses GITHUB_TOKEN, GH_TOKEN, or the active gh token without storing that credential in Pulumi state. Workflows remain checked into their owning repositories; application repositories do not receive a second .m/ tree.

Provider bootstrap creates planner and deployer identities for their declared cloud grants, but their GitHub federation remains deny-all until exact checked-in workflows have a protected source for the matching private m revision. Do not enable either identity for a generic repository or branch workflow.

Offboard a publisher in reviewed stages. Set image.publish: false but retain source.repositoryId, then run m artifacts up; the retained update adopts the revocable deletion policy, disables the account, and removes its federation/writer grants. Next run m workflow up; the workflow stack refuses to remove repository variables until the disabled-publisher output proves active authority is gone. Finally remove source.repositoryId or the application manifest, run m artifacts up to delete the disabled account, and run m render. The shared publisher WIF provider remains with an impossible condition when no publishers are active, avoiding GCP soft-delete/name-reuse delays; the registry, images, and environment-reader grants remain platform-owned until platform teardown.

Every provider, environment, application, artifacts, and workflow preview can save a Pulumi update plan with --save-plan FILE; the matching apply accepts --plan FILE. A saved-plan apply skips a new preview and lets Pulumi constrain the update to the reviewed operations. Keep plan files in a protected CI artifact or task-local temporary directory, never Git, and delete them after the apply. Without --plan, each apply retains the normal preview-and-confirm flow.

m plan -e dev --save-plan "$RUNNER_TEMP/m-environment-dev.plan.json"
m up -e dev --plan "$RUNNER_TEMP/m-environment-dev.plan.json" --yes

.m/generated-gitops/ is an intentional generated boundary owned exclusively by m; edit .m/platform.yaml, .m/apps/*.yaml, or .m/registrations/*.yaml instead. See DESIGN.md for ownership and package boundaries.

Use m render --check in validation to verify the committed generated state without changing it.

The platform repository is also the single application-registration owner. Add or change .m/apps/<application>.yaml, run m render, review and commit the generated state, and let the existing root Application reconcile it. The referenced application repository does not run m; it supplies the declared chart path and environment values.

Promoted applications keep image repository and digest selections in their source repository's environment values. m release updates only non-promoted applications whose image remains platform-manifest-owned.

An environment postgres declaration makes m up -e ENVIRONMENT own one shared private Cloud SQL instance, private service access, Data API enablement, and the protected deployer's privileged IAM database user. An application infrastructure.postgres.database declaration makes m app up APPLICATION -e ENVIRONMENT create only that protected logical database and one passwordless runtime/migration identity, then use the Cloud SQL Data API to verify provider ownership, revoke public access, and grant only the runtime database/schema capabilities. The mutation requires the already-selected deployer credential and M_GCP_EXECUTION_SERVICE_ACCOUNT set to that exact service-account email; m does not impersonate or mint another credential. Application stack outputs include the connection name, private-service CIDR, database name, IAM database username, and Google service account consumed by reviewed source-repository values. The application chart must use namespace and Kubernetes service account APPLICATION/APPLICATION; ongoing schema migrations and their objects remain owned by the application role. m never embeds a database password. Application-database teardown remains outside version one.

When initialization enables Actions runners, m declares the ARC controller plus one organization-scoped m-build scale set in the control-plane cluster. The scale set uses a pinned upstream runner image, zero idle runners, one-runner maximum, and a separate GitHub App private-key contract. The App requires the organization-level Self-hosted runners read/write permission; Docker-in-Docker is not enabled by default because it requires privileged runner containers.

Directories

Path Synopsis
cmd
m command
internal
cli

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL