Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ updates:
applies-to: version-updates
patterns:
- '*'
# These exact versions define coordinated compatibility axes rather than
# ordinary "latest" dependencies. update-types ignores routine updates only;
# Dependabot security updates remain eligible.
# These exact versions define coordinated compatibility axes or sensitive
# release tooling rather than ordinary "latest" dependencies. update-types
# ignores routine updates only; Dependabot security updates remain eligible.
ignore:
- dependency-name: 'react'
update-types:
Expand Down Expand Up @@ -58,6 +58,11 @@ updates:
- 'version-update:semver-major'
- 'version-update:semver-minor'
- 'version-update:semver-patch'
- dependency-name: 'release-it'
update-types:
- 'version-update:semver-major'
- 'version-update:semver-minor'
- 'version-update:semver-patch'
- dependency-name: '@types/node'
update-types:
- 'version-update:semver-major'
Expand Down
28 changes: 28 additions & 0 deletions .release-it.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"$schema": "https://unpkg.com/release-it@21/schema/release-it.json",
"git": {
"requireBranch": "main",
"requireCleanWorkingDir": false,
"requireUpstream": true,
"addUntrackedFiles": false,
"commit": true,
"commitMessage": "馃敄 release v${version}",
"tag": true,
"tagName": "v${version}",
"tagAnnotation": "Release v${version}",
"push": true,
"pushArgs": ["--follow-tags", "--atomic"]
},
"npm": {
"publish": false
},
"github": {
"release": false
},
"hooks": {
"before:bump": [
"node scripts/release-preflight.mjs --check-only ${version}",
"npm run release:check"
]
}
}
5 changes: 5 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ it remains representative of the supported toolchain. Playwright Test must
match the digest-pinned container and its browser binaries. Update either set
manually and review any affected browser snapshots.

`release-it` is part of the publishing authority rather than an ordinary
development dependency. Update it manually after the release-flow dry run and
isolated synchronized-main release smoke test pass; routine Dependabot updates
are disabled without suppressing security updates.

GitHub's repository-level dependency security features are expected to cover
the tracked packed-consumer lockfile. `npm run security:audit` also checks that
independent lockfile explicitly; its routine updates remain part of the manual
Expand Down
65 changes: 55 additions & 10 deletions docs/RELEASING.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# Release Process

> **Pre-release status:** `release-it`, `.github/workflows/release.yml`, the
> `npm-publish` environment, and npm trusted publishing are not configured yet.
> This document defines the controls that must land before `1.0.0-rc.0`; progress
> is tracked in `MODERNIZATION_PLAN.md`.
> **Pre-release status:** `release-it` is configured, but
> `.github/workflows/release.yml`, the `npm-publish` environment, and npm trusted
> publishing are not configured yet. Do not create a release tag until that
> workflow exists. Progress is tracked in `MODERNIZATION_PLAN.md`.

`@picr/react-grid-gallery` is published only by the maintainer through GitHub
Actions. Do not run `npm publish` from a development machine or add a long-lived
Expand All @@ -16,8 +16,15 @@ another release.

## Controls

- Release commits and tags must come from protected `main` after required CI
passes.
- Ordinary changes must still reach protected `main` through reviewed pull
requests. The maintainer's administrator bypass is reserved for the
release-it-generated version commit and tag described below.
- The complete release checks run locally before release-it changes the version.
The tag-triggered workflow repeats its release gates before npm receives an
artifact.
- Local release checks run while `package.json` still contains the current
version (`0.0.0-development` before the first release). The tag workflow is
therefore the authoritative validation of the final versioned tarball.
- The release workflow must use the repository's verified Corepack bootstrap
and integrity-pinned npm version.
- Trusted publishing must use OIDC without `NODE_AUTH_TOKEN`. Bootstrap or
Expand All @@ -44,12 +51,50 @@ After bootstrap, configure stage-only npm trusted publishing for the permanent
workflow and a release-tag-restricted `npm-publish` GitHub environment. Verify
the prerelease's repository-linked provenance before staging `1.0.0`.

## Creating A Release

The unpublished development version is `0.0.0-development`. It exists only so
the first release candidate can advance cleanly to `1.0.0-rc.0`; never publish
the development placeholder.

Update local `main`, then manually add one non-empty `## v<version>` or
`## v<version> / YYYY-MM-DD` section to `CHANGELOG.md`. That file must be the
only unstaged tracked change. Untracked planning files are not added to the
release commit.

```sh
git switch main
git pull --ff-only
# Edit CHANGELOG.md.
npm run release:dry-run -- <version>
npm run release -- <version>
```

The worktree guard fetches `origin/main`, requires local `main` to match it
exactly, and rejects every tracked change except the unstaged changelog update.
The dry-run preflight validates and prints the exact curated release-note
section before previewing release-it's write operations. It does not repeat the
complete release gate. Review that printed text before continuing. The real run
reuses that preflight and runs `npm run release:check`. It then bumps
`package.json` and `package-lock.json`, creates the
`馃敄 release v<version>` commit and annotated tag, and atomically pushes both to
`main` using the maintainer's administrator bypass. If branch protection rejects
the commit, the tag is not pushed either.

Release-it never publishes to npm. Pushing the tag starts the independent
trusted-publishing workflow, which validates the final versioned tarball,
publishes or stages it, and owns GitHub Release creation with a scoped,
short-lived workflow token. A public GitHub Release must not precede successful
npm publication; the workflow may use a draft while staged npm approval is
pending. Do not use administrator bypass for ordinary development work.

## Normal Releases

`release-it` prepares the version commit, tag, curated GitHub Release, and
changelog guard. Pushing the release tag starts the publishing workflow. GitHub
OIDC stages the package at npm, and npm 2FA approval is the single human gate
before it becomes public.
`release-it` creates the version commit and annotated tag directly from
synchronized `main`. Pushing the release tag starts the publishing workflow.
GitHub OIDC stages the package at npm, npm 2FA approval is the single human gate
before it becomes public, and the workflow publishes the curated GitHub Release
only after the package is available.

## Emergency Recovery

Expand Down
Loading
Loading