Scan a site's composer files for a core upgrade
scan_composerWhich of a site's drupal/* packages need a new release for a target core, and which have none? Send composer.lock and composer.json once; do not query one package at a time. The answer is the release scan for every package, plus extra.patches as check_patches items. Constraints are read by composer's own semver library.
composer_lock: the whole file, or its path to get the upload command. A real lock does not fit a call. With the path, the files go from disk to the api by curl and only the plan comes back. composer_json: adds constraints and extra.patches. Sent as text with a lock path, the command lists every patch to send. target_core: 11.4 or 11.4.5. Empty scans against the installed core (target_is_installed): what can be updated without a core upgrade.
installed_unknown: the release data does not have the installed version; the row offers no older release. installed_from_tag: the project's git tag answered instead. Neither is a finding about the site.
A sub-module has no releases of its own; drupal.org packages it as a metapackage built from its project's release. Its row says submodule_of and has that project's answer. The lock's type, require and extra.drupal.datestamp fields pair a metapackage with its project.
rows, problems first. no_release: no published release supports the target; latest_any and dev_branch say what exists. update: a compatible release the site does not have; latest, latest_core. unknown: not a drupal.org project in the bundle; note says where its releases are. current: installed_supports and nothing newer needed; such a row has package, installed and installed_supports only. counts covers every package even when rows are cut.
candidates, on every row that is not current: the newest three releases, each with version, core constraint, date and supports_target. project_profile adds installs and branches to the same three.
patches: one item per extra.patches entry with the installed version filled in. Pass them to check_patches after composer update; local paths need the file text. A patch on a package outside drupal/ gets no item and no row; outside_drupal lists it.
patches:true answers with plan instead: every patch judged against the release its package would install for target_core. plan.counts: the verdict tally. plan.package_counts: the scan tallies. plan.no_release: the packages that block the target. plan.patches: one row per patch needing a decision (conflicts, unknown, merged). plan.applying: the number that still apply. The scan rows are not in a plan; call again without patches for them.
A patch whose package has no release for the target is judged against the branch when the lock installs a dev version. Otherwise it is unknown, with the reason in note. plan.warnings: a package is in no_release because of something the site controls. Each warning gives the requirement to change: its own constraint, or its minimum stability. A row's project for reroll_patch is its package without the drupal/ prefix.
A plan never has a re-rolled diff. plan.next_step points at reroll_patch, one call per patch, when any patch no longer applies.
bundle_date: when the release data was published. A release after it is invisible here. Confirm a no_release with composer show or drupal.org before acting.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| patches | No | Judge the site's patches in the same call: each one against the release its package would install for target_core. Returns a verdict per patch instead of items to check yourself. | |
| patch_files | No | The text of every patch listed in extra.patches, keyed by the source as written: a path (patches/x.patch) or its base name, or the URL. Only needed with patches:true. Fetch a URL patch yourself and send its text under that URL. For a merge request .patch URL, send its .diff form under a second key too. | |
| target_core | No | Core version to move to, e.g. 11.4 or 11.4.5. Leave empty to scan against the core the site already runs: which packages have a newer release for it. | |
| composer_json | No | The contents of composer.json (require, require-dev, extra.patches). Send the text; this server cannot read your filesystem. Optional; without it there are no constraints and no patches. | |
| composer_lock | Yes | The text of composer.lock. A real lock is too big to paste: send its path (composer.lock) instead. The answer is then the curl command that uploads the files from the site root. | |
| installed_core | No | What each installed release requires of core, keyed by composer name. Read it from the site's own vendor directory: composer show -f json <pkg>, or the drupal/core entry of its composer.json. Send it and the installed release is judged by what it declares. |