Release Channel Resolution Safety and Withdrawn-Artifact Watch
Pricing
from $15.00 / 1,000 run_starteds
Release Channel Resolution Safety and Withdrawn-Artifact Watch
Resolve each declared range or channel tag the way a package manager does, and report when the resolved version is withdrawn, holds no live file, or moved to another version since the last run. One row for each target, with the resolved version, the rule
Pricing
from $15.00 / 1,000 run_starteds
Rating
0.0
(0)
Developer
kingii98
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
6 days ago
Last modified
Categories
Share
Know what your consumers install today.
This Actor resolves each declared range or channel tag the way a package manager does. It then reports when the resolved version is withdrawn, holds no live file, or points to a different version than in the last run.
A yanked version, a deleted file set or a moved channel tag makes the install different from the intent. Nothing changes in the consumer repository, so a scheduled run is the only signal. Without this watch, you learn about the change from a bug report.
What one run does
- It reads each target, for example
npm:express@^4.0.0ornpm:react@next. - It reads the metadata document of each package once, from the public registry of the ecosystem.
- It selects the version that the declaration resolves to:
- a channel tag names the version that the registry states. The registry, and not the version order, decides where a tag points;
- a range selects the highest version that satisfies it, inside the
candidate set that the
includePrereleasesetting allows.
- It reads the state of the resolved version: is it withdrawn (yanked or deprecated), and how many live files does it hold.
- It gives the highest safe version: the highest version that satisfies the declaration, is not withdrawn, and holds at least one live file.
- It compares the resolved version with the snapshot of the last run, which it holds in a named key-value store, and it reports a retargeted tag.
- It writes one dataset row for each target, and one run-summary record.
Supported ecosystems
| Ecosystem | Write it as | Registry | Withdrawn means | Live files |
|---|---|---|---|---|
| npm | npm:express@^4.0.0 | registry.npmjs.org | the version carries a deprecated message | the version holds a tarball. An unpublished version holds none |
| PyPI | pypi:requests@>=2.31,<3 | pypi.org | every file of the release is yanked | the files of the release that are not yanked |
| crates.io | cargo:serde@^1.0 | crates.io | the version is yanked | one file for a version that is not yanked |
crates and crates.io are other names for cargo. A target with no range
or tag, for example npm:express, takes the latest tag.
Input
| Field | Type | Default | What it does |
|---|---|---|---|
targets | array of text | four example targets | 1 to 300 targets, each one ecosystem:name@range_or_tag. One entry may hold several lines |
includePrerelease | boolean | false | Repeat here the resolver setting of your consumers. When it is off, a prerelease is no candidate for a range |
failOn | array of text | all three conditions | The conditions that make a target unsafe: withdrawn, no_live_files, tag_retargeted |
stateStoreName | text | release-channel-resolution-state | The named key-value store that holds the last resolved version of each target |
requestTimeoutSeconds | integer | 30 | The timeout of each registry request |
concurrency | integer | 4 | The largest number of packages read at the same time |
A run with an empty input uses these defaults and succeeds.
Output
One row for each target, plus one run-summary record.
| Field | What it holds |
|---|---|
target, ecosystem, package, range_or_tag, include_prerelease | The declaration, as the run read it |
resolution_status | resolved, package_not_found, registry_error, tag_not_found, unsupported_range or no_satisfying_version |
resolved_version | The version that the declaration selects today |
resolution_rule | The rule that selected it |
withdrawn, withdrawn_reason | The withdrawn state of the resolved version, and the reason that the registry states |
live_file_count | The number of live files of the resolved version |
highest_safe_version, safer_version_available | The highest version that satisfies the declaration, is not withdrawn and holds live files |
tag_retargeted, previous_version, previous_seen_at, retarget_direction | The comparison with the last run |
resolution_changed, first_run | A range that selects a new version is a change, and not a retarget. The first run of a target writes the snapshot and reports no retarget |
verdict, failure_reason, conditions | The verdict of the target |
error, note | What stopped the resolution, and what the buyer must know about it |
Verdicts
safe: the target resolved, and the resolved version holds no condition.unsafe: the resolved version holds a condition that yourfailOnlist names.degraded: the target did not resolve, or it holds a condition that yourfailOnlist does not name. You see the finding, and the gate stays yours.
A verdict is a result, and not a fault of the Actor. A run with an unsafe target succeeds, and it carries the verdict in the status message. Use the dataset, and not the run status, for your gate.
The state store, and why the Actor needs it
A retarget is visible only against an earlier observation. The Actor keeps one
record for each target in the named key-value store that
stateStoreName names. A named store stays after the run; the store of the
run does not.
- The first run of a target writes the snapshot and reports no retarget.
- A later run compares the resolved version with the stored one.
- Use one store name for each watched target list, so that two schedules do not overwrite each other.
A channel tag moves whenever the publisher releases, so tag_retargeted
reports every move of a tag. That is what a channel watch shows. Take
tag_retargeted out of failOn if you want only the withdrawn state and the
file state to make an unsafe verdict.
Pay-per-event pricing
| Event | Unit | What counts as one event |
|---|---|---|
run_started | one run | One event for each run. It is charged before the first request, so a run that stops early still pays for the work it started |
target_resolved | one resolution target evaluated | One event for each target that the run read from a registry. A target that the input got wrong, and a target that the charge limit stopped, are not charged. A target whose registry answer failed is charged, because the request was made |
channel_snapshot_stored | one target snapshot | One event for each snapshot written back to the named store. Only a target that resolved writes a snapshot |
The run never reads more targets than its maximum total charge allows. A
target above that limit gets a target_not_evaluated row, and it keeps its
stored snapshot for the next run.
Version rules, and what this Actor does not do
- npm and crates.io use the semantic version rules. PyPI uses the PEP 440 rules. Each rule set has its own tests.
- The range forms that the Actor reads are
^,~,>=,>,<=,<,=, an exact version, an x-range (1.x), a hyphen range (1.2.3 - 2.3.4),*and an or-list (^1.0.0 || ^2.0.0) for npm and Cargo; and==,!=,>=,>,<=,<,~=,===and a wildcard (==4.*) for PyPI. - A comparator admits a prerelease by the numbers alone. npm hides a
prerelease from a range that does not name one; this Actor lets
includePrereleasedecide which versions are candidates, because that setting repeats what your resolver does. - A declaration that the Actor cannot read, for example
workspace:*or a Git URL, gets theunsupported_rangestatus and the degraded verdict. It is not a failed run. - The Actor makes HTTP requests to three fixed registry hosts only. It uses no browser, no proxy, no key and no paid API.
Limits
- At most 300 targets in one run.
- At most 12 MB for one metadata document.
- At most 8 packages read at the same time.
Schedule it
Run it once a day, or before each deployment. The publisher changes a channel tag and a yank state without any change in your repository, so only a scheduled run finds it.