Send a change upstream
$ grim push Cart -m "fix(cart): correct totals" --dry-run
You found the bug while working on a client's project, and you fixed it where you stood: inside src/Cart/, a module grim install put there. The fix now exists in one project. The next grim update would check the module out again at a newer release, and every other project still has the bug.
Modules and themes are released from a monorepo, and the package repositories are written by its release process alone. So a change does not go back to the package. grim push sends it to the monorepo as a pull request, one unit at a time, and it returns to every project with the next train.
Usage
$ grim push Cart --dry-run # base and diffstat, nothing sent
$ grim push Cart -m "fix(cart): correct totals" # open the pull request
$ grim push --theme frontend/shop-front -m "feat(shop-front): add print stylesheet"Run it anywhere inside the project. The real push needs the GitHub CLI gh, logged in, and write access to the monorepo. A dry run needs only to be able to read it.
Arguments and options
Open a pull request against the monorepo with your change to one module or theme
Usage
grim push [--theme THEME] [--theme-type THEME-TYPE] [-m|--message MESSAGE] [--dry-run] [--patch] [--repo REPO] [--base BASE] [--] [<module>]Arguments
| Argument | Description |
|---|---|
module |
Module to push, by src/ directory name (e.g. Cart) (optional) |
Options
| Option | Description |
|---|---|
--theme=THEME |
Theme to push, as |
--theme-type=THEME-TYPE |
Theme type when --theme carries only the slug (default: frontend) |
-m, --message=MESSAGE |
PR title, conventional-commit style (e.g. "fix(hvpdoku): correct footer link") |
--dry-run |
Show the base, the title and the diff; push nothing |
--patch |
With --dry-run, print the full patch instead of a diffstat |
--repo=REPO |
Upstream repository (default: grim.json upstream.repo, else the monorepo) |
--base=BASE |
Upstream branch to target (default: master) |
What it actually does
- Checks the title.
-mbecomes both the commit message and the pull request title, and it is held to the conventional-commit rules the monorepo enforces:type(scope): subjectwith the scope optional, one line, at most 100 characters, a lowercase subject with no full stop. A bad title is rejected before anything is fetched. - Fetches the monorepo into
.grim/upstream/inside the project. The clone is blobless and sparse on the one unit path, and later pushes reuse it. - Finds the base commit. That is the newest commit on the upstream branch whose copy of the unit is identical to the release you have installed. Branching from there is what keeps the pull request down to your change, even when the project is several trains behind.
- Builds the branch.
grim-push/module/cart, orgrim-push/theme/frontend/shop-front, starts at the base. The unit is replaced with your working copy: tracked files plus new ones the unit's own.gitignoredoes not exclude. Deleted files are deleted there too. - Shows the change. The title and a diffstat, or the full patch with
--patch. With--dry-runit ends here withDry run — nothing pushed. - Commits, pushes and opens the pull request with
gh, and prints its URL. The body is three lines: the unit, the release it was installed at, the base commit.
Pitfalls
Do not commit inside the unit
The installed release is recognised by the unit's HEAD. Leave your edits uncommitted in src/Cart/. Once you commit there, HEAD no longer matches anything upstream and the search ends in No commit on acme/platform master carries this exact module Cart. The lightest way out is git reset --soft HEAD~1 inside the unit, which puts HEAD back on the tag and keeps your work. The remedy grim prints works too: stash or undo the commit, grim update, apply the change again, push.
Core modules cannot be pushed
Core reaches a project as one copied tree, not as a clone per module, so there is nothing to find a base with. Users is a core module is the start of that refusal. Make the change in a checkout of the monorepo itself and open the pull request there.
A second push replaces the first
The branch name is fixed per unit and the push is forced. Pushing Cart again, before the first pull request is merged, rewrites that pull request with the current state of src/Cart/. That is the way to answer a review. It also means two unrelated fixes to one module travel together or one after the other, not side by side.
--base is a branch, not a commit
It names the upstream branch to target, master unless grim.json says otherwise. The base commit is always found by grim.
The pull request could not be opened
When the push succeeds and gh pr create fails, the branch is already upstream. grim prints a compare URL; open it in a browser and create the pull request by hand.
Your gh token is missing the scope(s) … is not a permissions problem in the monorepo. The token gh holds lacks repo or read:packages. Run grim auth:login, as the message says.
After it finishes
The pull request is reviewed and squash-merged in the monorepo. The next train carries the change, and grim update brings it back into this project as part of a release.
Questions
Where does it push when the project belongs to another organisation?
To the repository named in grim.json under upstream.repo, on the branch under upstream.branch. --repo and --base override both for one run. Set the block once and commit it, so everybody on the project pushes to the same place.
Can I push a module I created with grim make:module?
Not this way. Such a module has a repository of its own and no copy upstream, so no base commit exists. Push it with git from src/<Name>/.
What happens to node_modules/ inside a theme?
It stays home. Only tracked files and untracked files that the unit's .gitignore lets through are copied.
Related spells
grim make:module
Forge a new module
Scaffold a module under src/ with a provider, routes, a working admin CRUD and its own GitHub repository.
grim make:theme
Weave a new theme
Scaffold a frontend or admin theme in the project, with its layouts and entry points, and publish it to a GitHub repository of its own.
grim manifest:validate
Check a manifest
Validate module.json, theme.json and core.json against the manifest schema on your machine, before CI does it for you.
grim update
Board the newest train
Move core, every module and every theme onto the newest release train grim.json allows, or a single module within the train it is on.
grim auth:login
Log grim in to GitHub
Give grim a GitHub token, from your gh login or a personal access token, and hand the same token to Composer and Docker.