Skip to content

[pull] latest from npm:latest#161

Merged
pull[bot] merged 15 commits into
DavidLacombe46:latestfrom
npm:latest
May 20, 2026
Merged

[pull] latest from npm:latest#161
pull[bot] merged 15 commits into
DavidLacombe46:latestfrom
npm:latest

Conversation

@pull
Copy link
Copy Markdown

@pull pull Bot commented May 20, 2026

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

reggi and others added 15 commits May 20, 2026 12:20
## Summary

Adds permission flags to trust create operations. Users must now specify
at least one of `--allow-publish` or `--allow-stage-publish` (alias:
`--allow-staged-publish`) when creating trust configurations.

## Changes

- Add `--allow-publish` and `--allow-stage-publish` flags to all trust
provider commands (GitHub, GitLab, CircleCI)
- Require at least one permission flag when creating trust
configurations
- Include permissions in the request body and display output
- Add `PERMISSIONS` constants for permission values
- Update tests and completion snapshots for new flags

## Related

- #9201

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
When the user has `min-release-age=N` in their `.npmrc`, the config flatten
function derives a `before` date used by pacote. Whenever pacote spawns a
child npm process (e.g. preparing a `git:` or `github:` dep), it forwards
`--before=<date>` to the child. The child then loads the same `.npmrc` and
the previously declared mutual-exclusivity between `before` and
`min-release-age` caused a hard configuration error.

This makes the two options coexist: the `exclusive` constraints are
removed and both flatten functions resolve to the earlier of the two
effective dates, never widening the user's most conservative bound.
The `min-release-age` flatten no longer mutates the per-source config
object (the prior `obj.before = ...` / `delete obj['min-release-age']`
mutations were vestigial and only masked the conflict at the parent
level, not in spawned children).

`min-release-age` is also added to the `params` arrays for `outdated`
and `update` so it remains visible in their command help; it was
previously displayed implicitly via the `before` exclusive grouping.

Fixes: #9291
# Introducing `npm stage` 🎉

A new command for staged publishing — allowing package maintainers to
decouple the act of publishing from proof-of-presence (2FA), making
automated workflows more secure.

🔗
[Docs](https://github.com/npm/cli/blob/014d8b211ae4a2eb35e65a3f54cb962ca04f009f/docs/lib/content/commands/npm-stage.md)

## Why Staged Publishing?

With `npm stage publish`, an automated workflow can stage a package
version *without* a 2FA prompt. The maintainer can then review and
approve the staged package at their convenience, providing 2FA only at
the approval step. This keeps proof-of-presence in the loop while
keeping CI/CD fully automated.

## Subcommands

| Command | Description | Requires 2FA |
| --- | --- | --- |
| `npm stage publish [<package-spec>]` | Stage a package for publishing
| No |
| `npm stage list [<package-spec>]` | List all staged package versions |
No |
| `npm stage view <stage-id>` | View details of a specific staged
package | No |
| `npm stage approve <stage-id>` | Approve and publish a staged package
| Yes |
| `npm stage reject <stage-id>` | Reject and remove a staged package |
Yes |
| `npm stage download <stage-id>` | Download the staged tarball for
inspection | No |

## How It Works

1. **Stage** — CI runs `npm stage publish` using any token type (no 2FA
needed). The package version is held in a pending state, not publicly
available.
2. **Review** — Maintainer runs `npm stage list` to see pending staged
packages, and `npm stage view <id>` or `npm stage download <id>` to
inspect them.
3. **Approve or Reject** — Maintainer runs `npm stage approve <id>`
(with 2FA) to publish, or `npm stage reject <id>` to discard.

## Key Behaviors

- Staged packages share the same semver uniqueness constraint as
published packages — you can't publish a version that's already staged.
- Normal `npm publish` continues to work alongside staged publishing.
- Multiple versions of the same package can be staged concurrently.
- `npm stage publish` has full parity with `npm publish` (respects
`"private": true`, workspace support, etc).
- Tags are immutable once staged — reject and re-stage to change a tag.

## Future Work

- **Trust relationship permissions** — A follow-up PR will add granular
command permissions to `npm trust`, with `--allow-publish` and
`--allow-stage-publish` flags to control whether a trust relationship
can be used for `npm publish`, `npm stage publish`, or both.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
`npm stage download <id> --json` currently emits the package contents
under a literal `"undefined"` key because `logTar` is called without a
`key` option.

### Before

```json
{
  "undefined": {
    "name": "polo-meow-meow-meow",
    "version": "1.0.3",
    ...
  }
}
```

### After

```json
{
  "polo-meow-meow-meow": {
    "name": "polo-meow-meow-meow",
    "version": "1.0.3",
    ...
  }
}
```

This matches the JSON shape of `npm publish --json` and `npm pack
--json`.

### Background

The `key == null` fallback in `lib/utils/tar.js` (that would have
rendered a bare object when no key was passed) was removed from `latest`
in #9247 ("fix: sync json output of pack and publish") as a `BREAKING
CHANGE`. Per that PR:

> BREAKING CHANGE: the --json output of `npm pack` and `npm publish`
have changed. They are now always consistent, and in the same format.
>
> Previously, `npm pack` would output an array of entries and `npm
publish` an object. The `npm publish` object also changed forms
depending on if workspaces were being published.
>
> Now, the output is always an object with the package name as the top
level index.

When #9201 (npm stage) landed, it added a new `logTar` caller in
`lib/commands/stage/download.js` that did not pass a `key`, silently
violating the v12 contract established in #9247 and producing the
`"undefined"` wrapper. This PR brings the new caller into compliance.

### Repro

```
npm stage download <stage-id> --json
```

A follow-up backports this to `release/v11` for consistent output across
branches: #9381.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@pull pull Bot locked and limited conversation to collaborators May 20, 2026
@pull pull Bot added the ⤵️ pull label May 20, 2026
@pull pull Bot merged commit 4296f64 into DavidLacombe46:latest May 20, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants