Skip to content
Open
Show file tree
Hide file tree
Changes from 4 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
38 changes: 38 additions & 0 deletions .github/workflows/release-on-main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: Release On Main

on:
push:
branches:
- main

permissions:
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The contents: write permission is correct for tagging and creating GitHub releases, but it's set at the workflow level, granting it to all jobs (currently just one). Consider using job-level permissions to keep the scope minimal and make the intent explicit:

Suggested change
permissions:
permissions:
contents: read
jobs:
release:
runs-on: ubuntu-latest
permissions:
contents: write

contents: write

concurrency:
group: release-on-main
cancel-in-progress: false

jobs:
release:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security: action tags (@v4) are mutable — a tag can be moved to a different commit without notice. Pin to a full commit SHA to prevent supply-chain attacks:

Suggested change
uses: actions/checkout@v4
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

Same for actions/setup-node@v4 below.

with:
fetch-depth: 0

- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actions are pinned to mutable major-version tags (@v4), not immutable commit SHAs. A compromised or accidentally broken actions/checkout@v4 or actions/setup-node@v4 release would affect this workflow with no notice. Since this workflow has contents: write and publishes to npm, the blast radius of a supply-chain issue here is significant.

Pin to commit SHAs, e.g.:

uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683  # v4.2.2
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af  # v4.1.0

registry-url: https://registry.npmjs.org

- name: Install dependencies
run: npm ci

- name: Release (changelog-driven)
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: ./scripts/release.sh
20 changes: 20 additions & 0 deletions .release-it.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding "requireUpstream": true to the git section. Without it, release-it won't verify that the local branch tracks a remote and is up-to-date, which complements the clean-tree check but doesn't replace it.

Suggested change
{
{
"git": {
"requireCleanWorkingDir": true,
"requireUpstream": true,
"requireBranch": "main",

"git": {
"requireCleanWorkingDir": true,
"requireBranch": "main",
"tagName": "v${version}",
"commitMessage": "chore(release): v${version} [skip ci]",
"commit": true,
"tag": true,
"push": true
},
"npm": {
"publish": true
},
"github": {
"release": true
},
"hooks": {
"before:init": "if [ \"$SKIP_RELEASE_TESTS\" = \"true\" ]; then echo 'Skipping tests/build via SKIP_RELEASE_TESTS'; else npm test && npm run build; fi"
}
}
42 changes: 42 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog and this project follows Semantic Versioning.

## [Unreleased]

### Added

- _No unreleased changes yet._

## [v1.0.0] - 2026-03-14

### Added

- Initial standalone extraction of the semantic webpack/rspack configuration diff engine from Shakapacker.
- CLI package and binstub: `pack-config-diff`.
- Deep diff engine with support for:
- objects and arrays
- functions, `RegExp`, and `Date`
- class-instance-aware behavior for plugin-like objects
- ignore keys/paths, max depth, and path separator options
- Cross-platform path normalization and base-path detection.
- Rich output formatter support:
- `detailed`
- `summary`
- `json`
- `yaml`
- `markdown`
- Contextual documentation mapping for common webpack/rspack config keys.
- Comprehensive test suite ported from Shakapacker plus integration coverage.

### Improved

- Plugin-aware comparison mode for class-instance configs (`--plugin-aware`).
- Module rule matching by `rule.test` to reduce reorder noise (`--match-rules-by-test`).
- Markdown table output with escaping and deterministic entry sorting.

### Build

- Added `prepare` script so installs from GitHub build `dist/` automatically.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The [Unreleased] and [v1.0.0] headings use Keep a Changelog's link-reference style but there are no link definitions at the bottom of the file. Most renderers and changelog tooling (e.g. git-cliff, standard-version) expect comparison links here.

Add these at the end of the file:

[Unreleased]: https://github.com/shakacode/pack-config-diff/compare/v1.0.0...HEAD
[v1.0.0]: https://github.com/shakacode/pack-config-diff/releases/tag/v1.0.0

10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,16 @@ npm test

Test suites are ported from Shakapacker's `test/configDiffer` and run against this extracted package.

## Release

- Changelog: [`CHANGELOG.md`](./CHANGELOG.md)
- Maintainer release guide: [`docs/releasing.md`](./docs/releasing.md)
- Prerelease protocol: [`docs/releasing.md#prerelease-protocol`](./docs/releasing.md#prerelease-protocol)
- Update changelog via `/update-changelog`, then merge/push to `main`
- Release automation workflow: `.github/workflows/release-on-main.yml`
- Release engine config: `.release-it.json`
- Local dry run: `npm run release:dry-run`

## License

MIT
91 changes: 91 additions & 0 deletions docs/releasing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# Releasing `pack-config-diff`

This repository uses a changelog-driven release flow modeled after Shakapacker:

- You update `CHANGELOG.md` via `/update-changelog`.
- You commit and push to `main`.
- CI runs the release script (powered by `release-it`), bumps `package.json`, publishes npm, tags, and creates the GitHub release.

## Prerequisites

1. Repository has `NPM_TOKEN` configured in GitHub Actions secrets.
2. Repository has `GITHUB_TOKEN` available to the workflow (default Actions token is used).
3. Maintainer has permissions to merge to `main`.
4. You have `/update-changelog` available in your workflow.

## Stable Release Protocol

1. Ensure release-ready PRs are merged.
2. Run:

```text
/update-changelog release
```

3. Review `CHANGELOG.md` for the new top version header (for example `## [v1.2.3] - YYYY-MM-DD`).
4. Commit and push only changelog/documentation changes.
5. Merge/push to `main`.

That push triggers `.github/workflows/release-on-main.yml`, which executes `./scripts/release.sh` and will:

1. Read target version from the top changelog version header.
2. Bump `package.json` (and `package-lock.json`) to that version.
3. Run tests/build.
4. Commit/push the version bump to `main`.
5. Publish to npm (`latest` for stable).
6. Create/push tag `vX.Y.Z`.
7. Create GitHub release via `release-it`.

Release behavior is configured in:

- `.release-it.json`
- `scripts/release.sh`

## Prerelease Protocol (`rc` / `beta`)

### Rules

- Do not manually edit `package.json` version for release prep.
- Use `/update-changelog rc` or `/update-changelog beta` to produce prerelease headers.
- Prerelease versions must use npm semver prerelease format:
- `1.2.3-rc.0`
- `1.2.3-beta.0`

### Steps

1. Run:

```text
/update-changelog rc
```

or

```text
/update-changelog beta
```

2. Confirm top changelog header is prerelease, e.g. `## [v1.2.3-rc.0] - YYYY-MM-DD`.
3. Commit and push changelog changes.
4. Merge/push to `main`.

Release automation will detect prerelease version and publish to npm dist-tag `next` automatically.

## Dry Run / Local Verification (Optional)

You can validate locally without publishing:

```bash
npm run release:dry-run
```

This checks branch, changelog/version state, and test/build readiness, and prints planned release actions.

## Post-Release Checks

1. npm package version/dist-tag:
- <https://www.npmjs.com/package/pack-config-diff>
2. Git tag exists:
- `vX.Y.Z`
3. GitHub release exists:
- <https://github.com/shakacode/pack-config-diff/releases>
Loading
Loading