@oorabona/release-it-preset 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +413 -65
- package/config/default.js +2 -1
- package/config/helpers.js +18 -0
- package/config/hotfix.js +2 -2
- package/config/manual-changelog.js +2 -1
- package/config/republish.js +2 -1
- package/dist/scripts/populate-unreleased-changelog.js +6 -0
- package/dist/scripts/validate-release.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,6 +2,31 @@
|
|
|
2
2
|
|
|
3
3
|
Shared [release-it](https://github.com/release-it/release-it) configuration and scripts for automated versioning, changelog generation, and package publishing.
|
|
4
4
|
|
|
5
|
+
[](https://codecov.io/github/oorabona/release-it-preset)
|
|
6
|
+
[](https://github.com/oorabona/release-it-preset/actions/workflows/ci.yml)
|
|
7
|
+
[](https://npmjs.org/package/@oorabona/release-it-preset)
|
|
8
|
+
[](https://npmjs.org/package/@oorabona/release-it-preset)
|
|
9
|
+
[](https://www.typescriptlang.org/)
|
|
10
|
+
[](https://opensource.org/licenses/MIT)
|
|
11
|
+
|
|
12
|
+
## Table of Contents
|
|
13
|
+
|
|
14
|
+
- [Features](#features)
|
|
15
|
+
- [Installation](#installation)
|
|
16
|
+
- [Quick Start](#quick-start)
|
|
17
|
+
- [Available Configurations](#available-configurations)
|
|
18
|
+
- [CLI Usage](#cli-usage)
|
|
19
|
+
- [Scripts](#scripts)
|
|
20
|
+
- [Environment Variables](#environment-variables)
|
|
21
|
+
- [Configuration Override](#configuration-override)
|
|
22
|
+
- [Borrowing Scripts & Workflows](#borrowing-scripts--workflows)
|
|
23
|
+
- [Release Workflow](#release-workflow)
|
|
24
|
+
- [GitHub Actions Workflows](#github-actions-workflows)
|
|
25
|
+
- [Reusable Workflows](#reusable-workflows)
|
|
26
|
+
- [Workflow Reference](#workflow-reference)
|
|
27
|
+
- [Best Practices](#best-practices)
|
|
28
|
+
- [Troubleshooting](#troubleshooting)
|
|
29
|
+
|
|
5
30
|
## Features
|
|
6
31
|
|
|
7
32
|
- 📦 Multiple release configurations for different scenarios
|
|
@@ -80,8 +105,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
80
105
|
|
|
81
106
|
## GitHub Actions
|
|
82
107
|
|
|
83
|
-
|
|
108
|
+
### Quick Start: Reusable Workflows
|
|
109
|
+
|
|
110
|
+
Import pre-configured workflows into your repository:
|
|
84
111
|
|
|
112
|
+
**PR Validation:**
|
|
85
113
|
```yaml
|
|
86
114
|
name: PR Checks
|
|
87
115
|
|
|
@@ -89,16 +117,40 @@ on:
|
|
|
89
117
|
pull_request:
|
|
90
118
|
types: [opened, synchronize, reopened]
|
|
91
119
|
|
|
120
|
+
permissions:
|
|
121
|
+
contents: read
|
|
122
|
+
pull-requests: write
|
|
123
|
+
|
|
92
124
|
jobs:
|
|
93
125
|
validate:
|
|
94
126
|
uses: oorabona/release-it-preset/.github/workflows/reusable-verify.yml@main
|
|
95
127
|
with:
|
|
96
128
|
base-ref: origin/${{ github.base_ref }}
|
|
97
129
|
head-ref: ${{ github.sha }}
|
|
130
|
+
run-tests: true
|
|
98
131
|
secrets: inherit
|
|
99
132
|
```
|
|
100
133
|
|
|
101
|
-
|
|
134
|
+
**Publish on Tag:**
|
|
135
|
+
```yaml
|
|
136
|
+
name: Publish
|
|
137
|
+
|
|
138
|
+
on:
|
|
139
|
+
push:
|
|
140
|
+
tags: ['v*']
|
|
141
|
+
|
|
142
|
+
permissions:
|
|
143
|
+
contents: write
|
|
144
|
+
id-token: write
|
|
145
|
+
|
|
146
|
+
jobs:
|
|
147
|
+
publish:
|
|
148
|
+
uses: oorabona/release-it-preset/.github/workflows/publish.yml@main
|
|
149
|
+
secrets:
|
|
150
|
+
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
📖 **[Full Reusable Workflows Documentation](examples/reusable-workflows.md)** | 📚 **[CI/CD Integration Examples](examples/ci-integration.md)**
|
|
102
154
|
|
|
103
155
|
## Available Configurations
|
|
104
156
|
|
|
@@ -469,6 +521,7 @@ Customize behavior with environment variables:
|
|
|
469
521
|
- `GIT_REQUIRE_UPSTREAM` - Require upstream tracking (default: `false`)
|
|
470
522
|
- `GIT_REQUIRE_CLEAN` - Require clean working directory (default: `false`)
|
|
471
523
|
- `GIT_REMOTE` - Git remote name (default: `origin`)
|
|
524
|
+
- `GIT_CHANGELOG_COMMAND` - Override the git log command used for previews (default filters out release/hotfix/ci commits)
|
|
472
525
|
|
|
473
526
|
### GitHub
|
|
474
527
|
- `GITHUB_RELEASE` - Enable GitHub releases (default: `false`)
|
|
@@ -608,7 +661,7 @@ jobs:
|
|
|
608
661
|
- name: Update GitHub release and publish to npm
|
|
609
662
|
run: pnpm release-it-preset retry-publish --ci
|
|
610
663
|
env:
|
|
611
|
-
|
|
664
|
+
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
612
665
|
NPM_PUBLISH: 'true'
|
|
613
666
|
GITHUB_RELEASE: 'true'
|
|
614
667
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
@@ -619,7 +672,7 @@ jobs:
|
|
|
619
672
|
- `GITHUB_TOKEN` is provided automatically by GitHub Actions (no manual secret needed)
|
|
620
673
|
|
|
621
674
|
**Required Permissions (locally):**
|
|
622
|
-
- Set `GITHUB_RELEASE=true` and/or `NPM_PUBLISH=true` only when you explicitly want to perform those actions from your machine. Provide `GITHUB_TOKEN`/`
|
|
675
|
+
- Set `GITHUB_RELEASE=true` and/or `NPM_PUBLISH=true` only when you explicitly want to perform those actions from your machine. Provide `GITHUB_TOKEN`/`NPM_TOKEN` as needed.
|
|
623
676
|
|
|
624
677
|
### Alternative: Full CI Release
|
|
625
678
|
|
|
@@ -648,7 +701,7 @@ jobs:
|
|
|
648
701
|
- run: pnpm release-it-preset default --ci --increment ${{ inputs.version }}
|
|
649
702
|
env:
|
|
650
703
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
651
|
-
|
|
704
|
+
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
652
705
|
GITHUB_RELEASE: 'true'
|
|
653
706
|
NPM_PUBLISH: 'true'
|
|
654
707
|
```
|
|
@@ -657,18 +710,154 @@ jobs:
|
|
|
657
710
|
|
|
658
711
|
This repository includes several GitHub Actions workflows for automated CI/CD and release management.
|
|
659
712
|
|
|
660
|
-
###
|
|
713
|
+
### Reusable Workflows
|
|
714
|
+
|
|
715
|
+
Two workflows are designed for reuse in your own projects:
|
|
716
|
+
|
|
717
|
+
#### 🔄 `reusable-verify.yml` - PR Validation & Hygiene Checks
|
|
718
|
+
|
|
719
|
+
Validates TypeScript compilation, runs tests, checks release readiness, and evaluates PR hygiene (changelog updates, conventional commits).
|
|
720
|
+
|
|
721
|
+
**When to use:** Import this workflow in your PR validation to ensure code quality and release readiness.
|
|
722
|
+
|
|
723
|
+
**Inputs:**
|
|
724
|
+
|
|
725
|
+
| Input | Type | Default | Description |
|
|
726
|
+
|-------|------|---------|-------------|
|
|
727
|
+
| `node-version` | string | `'20'` | Node.js version to use |
|
|
728
|
+
| `run-tests` | boolean | `false` | Run `pnpm test` after compilation |
|
|
729
|
+
| `base-ref` | string | `''` | Base ref for diff comparisons (e.g., `origin/main`) |
|
|
730
|
+
| `head-ref` | string | `'HEAD'` | Head ref for comparisons |
|
|
731
|
+
| `install-args` | string | `'--frozen-lockfile'` | Additional pnpm install arguments |
|
|
732
|
+
| `fetch-depth` | number | `0` | Git fetch depth for checkout |
|
|
733
|
+
|
|
734
|
+
**Outputs:**
|
|
735
|
+
|
|
736
|
+
| Output | Description |
|
|
737
|
+
|--------|-------------|
|
|
738
|
+
| `release_validation` | `'true'` when release validation passes |
|
|
739
|
+
| `changelog_status` | Changelog status: `updated`, `skipped`, or `missing` |
|
|
740
|
+
| `skip_changelog` | `'true'` when `[skip-changelog]` detected in commits |
|
|
741
|
+
| `conventional_commits` | `'true'` when conventional commits detected |
|
|
742
|
+
| `commit_messages` | Base64 encoded JSON array of analyzed commit messages |
|
|
743
|
+
| `changed_files` | Base64 encoded JSON array of changed files |
|
|
744
|
+
|
|
745
|
+
**Example usage in your project:**
|
|
746
|
+
|
|
747
|
+
```yaml
|
|
748
|
+
# .github/workflows/validate-pr.yml
|
|
749
|
+
name: PR Validation
|
|
750
|
+
|
|
751
|
+
on:
|
|
752
|
+
pull_request:
|
|
753
|
+
types: [opened, synchronize, reopened]
|
|
754
|
+
|
|
755
|
+
jobs:
|
|
756
|
+
validate:
|
|
757
|
+
uses: oorabona/release-it-preset/.github/workflows/reusable-verify.yml@main
|
|
758
|
+
with:
|
|
759
|
+
node-version: '20'
|
|
760
|
+
base-ref: origin/${{ github.base_ref }}
|
|
761
|
+
head-ref: ${{ github.sha }}
|
|
762
|
+
run-tests: true
|
|
763
|
+
secrets: inherit
|
|
764
|
+
|
|
765
|
+
comment:
|
|
766
|
+
needs: validate
|
|
767
|
+
runs-on: ubuntu-latest
|
|
768
|
+
if: always()
|
|
769
|
+
permissions:
|
|
770
|
+
pull-requests: write
|
|
771
|
+
steps:
|
|
772
|
+
- uses: actions/github-script@v7
|
|
773
|
+
with:
|
|
774
|
+
script: |
|
|
775
|
+
const summary = `## 📋 PR Validation
|
|
776
|
+
|
|
777
|
+
${needs.validate.outputs.release_validation === 'true' ? '✅' : '⚠️'} Release validation
|
|
778
|
+
${needs.validate.outputs.changelog_status === 'updated' ? '✅' : 'ℹ️'} Changelog: ${needs.validate.outputs.changelog_status}
|
|
779
|
+
${needs.validate.outputs.conventional_commits === 'true' ? '✅' : 'ℹ️'} Conventional commits
|
|
780
|
+
`;
|
|
781
|
+
|
|
782
|
+
github.rest.issues.createComment({
|
|
783
|
+
owner: context.repo.owner,
|
|
784
|
+
repo: context.repo.repo,
|
|
785
|
+
issue_number: context.issue.number,
|
|
786
|
+
body: summary
|
|
787
|
+
});
|
|
788
|
+
```
|
|
789
|
+
|
|
790
|
+
#### 🔄 `build-dist.yml` - Build Compiled Distribution
|
|
791
|
+
|
|
792
|
+
Builds TypeScript sources to `dist/` and uploads as artifact for reuse in other jobs.
|
|
793
|
+
|
|
794
|
+
**When to use:** When you need compiled outputs across multiple jobs without rebuilding.
|
|
795
|
+
|
|
796
|
+
**Inputs:**
|
|
797
|
+
|
|
798
|
+
| Input | Type | Default | Description |
|
|
799
|
+
|-------|------|---------|-------------|
|
|
800
|
+
| `artifact_name` | string | `'dist-build'` | Name for the uploaded dist artifact |
|
|
801
|
+
| `ref` | string | (current) | Optional git ref to checkout before building |
|
|
661
802
|
|
|
662
|
-
|
|
803
|
+
**Outputs:**
|
|
663
804
|
|
|
664
|
-
|
|
805
|
+
| Output | Description |
|
|
806
|
+
|--------|-------------|
|
|
807
|
+
| `artifact_name` | Name of the uploaded dist artifact |
|
|
665
808
|
|
|
666
|
-
**
|
|
809
|
+
**Example usage in your project:**
|
|
810
|
+
|
|
811
|
+
```yaml
|
|
812
|
+
# .github/workflows/ci.yml
|
|
813
|
+
jobs:
|
|
814
|
+
build:
|
|
815
|
+
uses: oorabona/release-it-preset/.github/workflows/build-dist.yml@main
|
|
816
|
+
with:
|
|
817
|
+
artifact_name: my-dist
|
|
818
|
+
ref: ${{ github.sha }}
|
|
819
|
+
|
|
820
|
+
test:
|
|
821
|
+
needs: build
|
|
822
|
+
runs-on: ubuntu-latest
|
|
823
|
+
steps:
|
|
824
|
+
- uses: actions/checkout@v4
|
|
825
|
+
- uses: actions/download-artifact@v4
|
|
826
|
+
with:
|
|
827
|
+
name: ${{ needs.build.outputs.artifact_name }}
|
|
828
|
+
path: dist
|
|
829
|
+
- run: pnpm test
|
|
830
|
+
```
|
|
831
|
+
|
|
832
|
+
### Workflow Reference
|
|
833
|
+
|
|
834
|
+
#### Overview Table
|
|
835
|
+
|
|
836
|
+
| Workflow | Type | Trigger | Purpose |
|
|
837
|
+
|----------|------|---------|---------|
|
|
838
|
+
| 🔄 [reusable-verify.yml](#-reusable-verifyyml---pr-validation--hygiene-checks) | Reusable | `workflow_call` | PR validation & hygiene checks |
|
|
839
|
+
| 🔄 [build-dist.yml](#-build-distyml---build-compiled-distribution) | Reusable | `workflow_call` | Build TypeScript distribution |
|
|
840
|
+
| ⚙️ [ci.yml](#1-️-ci-github-workflowsciyml) | Standalone | Push, PR, Manual | Continuous Integration |
|
|
841
|
+
| ✅ [validate-pr.yml](#2--validate-pr-github-workflowsvalidate-pryml) | Standalone | PR | Pull request validation |
|
|
842
|
+
| 🚨 [hotfix.yml](#3--hotfix-release-github-workflowshotfixyml) | Manual | `workflow_dispatch` | Emergency hotfix releases |
|
|
843
|
+
| 🔄 [retry-publish.yml](#4--retry-publish-github-workflowsretry-publishyml) | Manual | `workflow_dispatch` | Retry failed publishing |
|
|
844
|
+
| ⚠️ [republish.yml](#5-️-republish-exceptional-github-workflowsrepublishyml) | Manual | `workflow_dispatch` | Republish existing version |
|
|
845
|
+
| 📦 [publish.yml](#6--publish-github-workflowspublishyml) | Reusable | Tag push, `workflow_call` | Automated publishing |
|
|
846
|
+
|
|
847
|
+
You can copy these workflows into your own repository (adjusting names, branches, and secrets to match your context). They work with the release-it-preset CLI defaults.
|
|
848
|
+
|
|
849
|
+
#### 1. ⚙️ **CI** (`.github/workflows/ci.yml`)
|
|
850
|
+
|
|
851
|
+
**Triggers:**
|
|
852
|
+
- Push to `main`
|
|
853
|
+
- Pull Requests to `main`
|
|
854
|
+
- Manual (`workflow_dispatch`)
|
|
667
855
|
|
|
668
856
|
**Jobs:**
|
|
669
|
-
-
|
|
670
|
-
-
|
|
671
|
-
-
|
|
857
|
+
- `build-dist` - Builds compiled distribution using reusable workflow
|
|
858
|
+
- `tests` - Runs unit tests with coverage
|
|
859
|
+
- `test-cli` - Tests all CLI commands (help, check, validate, init)
|
|
860
|
+
- `release` - Manual release creation (workflow_dispatch only)
|
|
672
861
|
|
|
673
862
|
**Manual Release:**
|
|
674
863
|
```bash
|
|
@@ -676,88 +865,247 @@ You can copy these files into your own repository (adjusting names, branches, an
|
|
|
676
865
|
# Select increment type: patch, minor, or major
|
|
677
866
|
```
|
|
678
867
|
|
|
679
|
-
|
|
868
|
+
**Secrets required:**
|
|
869
|
+
- `NPM_TOKEN` - npm automation token (for release job)
|
|
870
|
+
- `CODECOV_TOKEN` - Codecov upload token (optional)
|
|
680
871
|
|
|
681
|
-
**
|
|
872
|
+
#### 2. ✅ **Validate PR** (`.github/workflows/validate-pr.yml`)
|
|
682
873
|
|
|
683
|
-
**
|
|
684
|
-
-
|
|
685
|
-
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
-
|
|
874
|
+
**Triggers:**
|
|
875
|
+
- Pull Request `opened`, `synchronize`, `reopened`
|
|
876
|
+
- Can be called as reusable workflow (`workflow_call`)
|
|
877
|
+
|
|
878
|
+
**Jobs:**
|
|
879
|
+
- `validate` - Uses `reusable-verify.yml` for hygiene checks
|
|
880
|
+
- `summarize` - Posts validation summary comment on PR
|
|
881
|
+
|
|
882
|
+
**What it checks:**
|
|
883
|
+
- ✅ TypeScript compilation
|
|
884
|
+
- ✅ Release validation (with `--allow-dirty`)
|
|
885
|
+
- ✅ CHANGELOG.md updates (or `[skip-changelog]` marker)
|
|
886
|
+
- ✅ Conventional commits format
|
|
887
|
+
- ✅ Commit messages analysis
|
|
888
|
+
|
|
889
|
+
**Permissions required:**
|
|
890
|
+
```yaml
|
|
891
|
+
permissions:
|
|
892
|
+
contents: read
|
|
893
|
+
pull-requests: write # For posting comments
|
|
894
|
+
```
|
|
689
895
|
|
|
690
|
-
**
|
|
691
|
-
- Ensuring PRs follow best practices
|
|
692
|
-
- Catching issues before merge
|
|
693
|
-
- Promoting conventional commits usage
|
|
896
|
+
**No secrets required** (uses `GITHUB_TOKEN` automatically)
|
|
694
897
|
|
|
695
|
-
#### 3. **Hotfix Release** (`.github/workflows/hotfix.yml`)
|
|
898
|
+
#### 3. 🚨 **Hotfix Release** (`.github/workflows/hotfix.yml`)
|
|
696
899
|
|
|
697
|
-
**Trigger:** Manual (workflow_dispatch)
|
|
900
|
+
**Trigger:** Manual (`workflow_dispatch`)
|
|
698
901
|
|
|
699
902
|
**Inputs:**
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
903
|
+
|
|
904
|
+
| Input | Type | Required | Default | Description |
|
|
905
|
+
|-------|------|----------|---------|-------------|
|
|
906
|
+
| `increment` | choice | ✅ | `patch` | Version bump: `patch` or `minor` |
|
|
907
|
+
| `commit` | string | ❌ | latest | Specific commit SHA to release |
|
|
908
|
+
| `dry_run` | boolean | ❌ | `false` | Test without actual publishing |
|
|
909
|
+
|
|
910
|
+
**Jobs:**
|
|
911
|
+
- `validate` - Validates TypeScript compilation and builds
|
|
912
|
+
- `hotfix` - Creates emergency hotfix release using `release-it-preset hotfix`
|
|
703
913
|
|
|
704
914
|
**What it does:**
|
|
705
|
-
|
|
706
|
-
-
|
|
707
|
-
|
|
708
|
-
|
|
915
|
+
1. Validates code at specified commit
|
|
916
|
+
2. Auto-generates changelog from recent commits
|
|
917
|
+
3. Creates hotfix release (patch/minor bump)
|
|
918
|
+
4. Pushes git tag (GitHub release + npm publish via `publish.yml`)
|
|
709
919
|
|
|
710
|
-
**When to use:**
|
|
711
|
-
Critical bugs that need immediate patch release.
|
|
920
|
+
**When to use:** Critical bugs needing immediate patch release
|
|
712
921
|
|
|
713
|
-
|
|
922
|
+
**Permissions required:**
|
|
923
|
+
```yaml
|
|
924
|
+
permissions:
|
|
925
|
+
contents: write # For git operations
|
|
926
|
+
id-token: write # For npm provenance
|
|
927
|
+
```
|
|
714
928
|
|
|
715
|
-
**
|
|
929
|
+
**Secrets required:**
|
|
930
|
+
- `NPM_TOKEN` - npm automation token
|
|
931
|
+
- `GITHUB_TOKEN` - Provided automatically
|
|
932
|
+
|
|
933
|
+
#### 4. 🔄 **Retry Publish** (`.github/workflows/retry-publish.yml`)
|
|
934
|
+
|
|
935
|
+
**Trigger:** Manual (`workflow_dispatch`)
|
|
716
936
|
|
|
717
937
|
**Inputs:**
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
938
|
+
|
|
939
|
+
| Input | Type | Required | Default | Description |
|
|
940
|
+
|-------|------|----------|---------|-------------|
|
|
941
|
+
| `tag_name` | string | ❌ | latest tag | Git tag to republish |
|
|
942
|
+
| `npm_only` | boolean | ❌ | `false` | Publish to npm only (skip GitHub Release) |
|
|
943
|
+
| `github_only` | boolean | ❌ | `false` | Create GitHub Release only (skip npm) |
|
|
944
|
+
|
|
945
|
+
**Jobs:**
|
|
946
|
+
- `determine-tag` - Validates and determines which tag to publish
|
|
947
|
+
- `build-dist` - Builds distribution using reusable workflow
|
|
948
|
+
- `retry-publish` - Republishes to npm and/or GitHub
|
|
721
949
|
|
|
722
950
|
**What it does:**
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
951
|
+
1. Verifies git tag exists
|
|
952
|
+
2. Runs pre-flight checks (`retry-publish.js` script)
|
|
953
|
+
3. Republishes to selected destination(s)
|
|
954
|
+
4. Uses existing changelog for release notes
|
|
726
955
|
|
|
727
|
-
**When to use:**
|
|
728
|
-
When previous publish failed (network issue, auth problem, etc.)
|
|
956
|
+
**When to use:** Previous publish failed (network issue, auth problem, etc.)
|
|
729
957
|
|
|
730
|
-
|
|
958
|
+
**Permissions required:**
|
|
959
|
+
```yaml
|
|
960
|
+
permissions:
|
|
961
|
+
contents: write # For GitHub releases
|
|
962
|
+
id-token: write # For npm provenance
|
|
963
|
+
```
|
|
964
|
+
|
|
965
|
+
**Secrets required:**
|
|
966
|
+
- `NPM_TOKEN` - npm automation token (if npm publish enabled)
|
|
967
|
+
- `GITHUB_TOKEN` - Provided automatically
|
|
968
|
+
|
|
969
|
+
#### 5. ⚠️ **Republish (EXCEPTIONAL)** (`.github/workflows/republish.yml`)
|
|
731
970
|
|
|
732
|
-
**Trigger:** Manual (workflow_dispatch)
|
|
971
|
+
**Trigger:** Manual (`workflow_dispatch`)
|
|
972
|
+
|
|
973
|
+
**⚠️ DANGER:** Moves existing git tag (breaks semver immutability)
|
|
733
974
|
|
|
734
975
|
**Inputs:**
|
|
735
|
-
|
|
736
|
-
|
|
976
|
+
|
|
977
|
+
| Input | Type | Required | Description |
|
|
978
|
+
|-------|------|----------|-------------|
|
|
979
|
+
| `version` | string | ✅ | Version to republish (e.g., `1.2.3`) |
|
|
980
|
+
| `confirmation` | string | ✅ | Must type exactly `"I understand the risks"` |
|
|
981
|
+
|
|
982
|
+
**Jobs:**
|
|
983
|
+
- `pre-flight-checks` - Validates confirmation, version format, and tag existence
|
|
984
|
+
- `build-dist` - Builds distribution using reusable workflow
|
|
985
|
+
- `validate` - Validates TypeScript compilation
|
|
986
|
+
- `republish` - Moves git tag and republishes
|
|
737
987
|
|
|
738
988
|
**What it does:**
|
|
739
|
-
|
|
740
|
-
-
|
|
741
|
-
-
|
|
742
|
-
-
|
|
743
|
-
-
|
|
744
|
-
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
989
|
+
1. **Pre-flight safety checks:**
|
|
990
|
+
- Validates confirmation phrase
|
|
991
|
+
- Checks version format
|
|
992
|
+
- Verifies tag exists
|
|
993
|
+
- Displays warning message
|
|
994
|
+
- **10-second safety delay** ⏰
|
|
995
|
+
2. Validates code compilation
|
|
996
|
+
3. **Moves git tag to current commit** (⚠️ breaks immutability)
|
|
997
|
+
4. Updates changelog for current version
|
|
998
|
+
5. Republishes to npm with provenance
|
|
999
|
+
6. Updates GitHub Release
|
|
1000
|
+
7. Creates audit trail document
|
|
1001
|
+
|
|
1002
|
+
**When to use:** ONLY for exceptional emergencies where a published version has critical security issues
|
|
1003
|
+
|
|
1004
|
+
**Permissions required:**
|
|
1005
|
+
```yaml
|
|
1006
|
+
permissions:
|
|
1007
|
+
contents: write # For git tag operations
|
|
1008
|
+
id-token: write # For npm provenance
|
|
1009
|
+
```
|
|
1010
|
+
|
|
1011
|
+
**Secrets required:**
|
|
1012
|
+
- `NPM_TOKEN` - npm automation token
|
|
1013
|
+
- `GITHUB_TOKEN` - Provided automatically
|
|
1014
|
+
|
|
1015
|
+
**Concurrency:** Prevents parallel republish operations for same version
|
|
1016
|
+
|
|
1017
|
+
#### 6. 📦 **Publish** (`.github/workflows/publish.yml`)
|
|
748
1018
|
|
|
749
|
-
**
|
|
750
|
-
|
|
1019
|
+
**Triggers:**
|
|
1020
|
+
- Tag push matching `v*` pattern
|
|
1021
|
+
- Can be called as reusable workflow (`workflow_call`)
|
|
751
1022
|
|
|
752
|
-
|
|
1023
|
+
**Inputs (for `workflow_call`):**
|
|
753
1024
|
|
|
754
|
-
|
|
1025
|
+
| Input | Type | Required | Description |
|
|
1026
|
+
|-------|------|----------|-------------|
|
|
1027
|
+
| `tag` | string | ❌ | Override tag (auto-detected from `github.ref_name`) |
|
|
1028
|
+
|
|
1029
|
+
**Jobs:**
|
|
1030
|
+
- `build-dist` - Builds distribution using reusable workflow
|
|
1031
|
+
- `publish` - Updates GitHub release and publishes to npm
|
|
755
1032
|
|
|
756
1033
|
**What it does:**
|
|
757
|
-
|
|
758
|
-
|
|
1034
|
+
1. Builds compiled distribution
|
|
1035
|
+
2. Runs `release-it-preset retry-publish --ci`
|
|
1036
|
+
3. Creates/updates GitHub Release with changelog
|
|
1037
|
+
4. Publishes to npm with provenance attestation
|
|
1038
|
+
|
|
1039
|
+
**When it runs:** Automatically triggered when a tag is pushed (e.g., by `default` or `hotfix` workflows)
|
|
1040
|
+
|
|
1041
|
+
**Permissions required:**
|
|
1042
|
+
```yaml
|
|
1043
|
+
permissions:
|
|
1044
|
+
contents: write # For GitHub releases
|
|
1045
|
+
id-token: write # For npm provenance attestation
|
|
1046
|
+
```
|
|
759
1047
|
|
|
760
|
-
**
|
|
1048
|
+
**Secrets required (for `workflow_call`):**
|
|
1049
|
+
- `NPM_TOKEN` - npm automation token (must be passed explicitly)
|
|
1050
|
+
|
|
1051
|
+
**Secrets required (for tag push):**
|
|
1052
|
+
- `NPM_TOKEN` - npm automation token (repository secret)
|
|
1053
|
+
- `GITHUB_TOKEN` - Provided automatically
|
|
1054
|
+
|
|
1055
|
+
**Environment variables set:**
|
|
1056
|
+
- `GITHUB_RELEASE=true` - Enables GitHub release creation
|
|
1057
|
+
- `NPM_PUBLISH=true` - Enables npm publishing
|
|
1058
|
+
|
|
1059
|
+
---
|
|
1060
|
+
|
|
1061
|
+
### Workflows Summary Diagram
|
|
1062
|
+
|
|
1063
|
+
```mermaid
|
|
1064
|
+
graph TB
|
|
1065
|
+
subgraph "Reusable Workflows"
|
|
1066
|
+
RV[🔄 reusable-verify.yml<br/>PR validation & hygiene]
|
|
1067
|
+
BD[🔄 build-dist.yml<br/>Build TypeScript dist]
|
|
1068
|
+
end
|
|
1069
|
+
|
|
1070
|
+
subgraph "Development Flow"
|
|
1071
|
+
PR[Pull Request] --> VPR[✅ validate-pr.yml]
|
|
1072
|
+
VPR --> RV
|
|
1073
|
+
VPR --> Comment[Post PR comment]
|
|
1074
|
+
end
|
|
1075
|
+
|
|
1076
|
+
subgraph "Release Flow"
|
|
1077
|
+
Manual[Manual Trigger] --> CI[⚙️ ci.yml]
|
|
1078
|
+
CI --> BD
|
|
1079
|
+
CI --> Tag[Create Tag]
|
|
1080
|
+
Tag --> PUB[📦 publish.yml]
|
|
1081
|
+
PUB --> BD
|
|
1082
|
+
PUB --> NPM[npm publish]
|
|
1083
|
+
PUB --> GH[GitHub Release]
|
|
1084
|
+
end
|
|
1085
|
+
|
|
1086
|
+
subgraph "Emergency Flow"
|
|
1087
|
+
Critical[Critical Bug] --> HF[🚨 hotfix.yml]
|
|
1088
|
+
HF --> BD
|
|
1089
|
+
HF --> Tag
|
|
1090
|
+
end
|
|
1091
|
+
|
|
1092
|
+
subgraph "Recovery Flow"
|
|
1093
|
+
Failed[Failed Publish] --> RP[🔄 retry-publish.yml]
|
|
1094
|
+
RP --> BD
|
|
1095
|
+
RP --> Decision{Retry What?}
|
|
1096
|
+
Decision -->|npm only| NPM
|
|
1097
|
+
Decision -->|GitHub only| GH
|
|
1098
|
+
Decision -->|Both| Both[npm + GitHub]
|
|
1099
|
+
end
|
|
1100
|
+
|
|
1101
|
+
style RV fill:#e1f5fe
|
|
1102
|
+
style BD fill:#e1f5fe
|
|
1103
|
+
style VPR fill:#c8e6c9
|
|
1104
|
+
style CI fill:#fff9c4
|
|
1105
|
+
style HF fill:#ffccbc
|
|
1106
|
+
style RP fill:#b2ebf2
|
|
1107
|
+
style PUB fill:#d1c4e9
|
|
1108
|
+
```
|
|
761
1109
|
|
|
762
1110
|
## Best Practices
|
|
763
1111
|
|
package/config/default.js
CHANGED
|
@@ -17,10 +17,11 @@
|
|
|
17
17
|
* ```
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
import { createReleaseNotesGenerator, runScriptCommand } from './helpers.js';
|
|
20
|
+
import { createReleaseNotesGenerator, getGitChangelogCommand, runScriptCommand } from './helpers.js';
|
|
21
21
|
|
|
22
22
|
const config = {
|
|
23
23
|
git: {
|
|
24
|
+
changelog: getGitChangelogCommand(),
|
|
24
25
|
commitMessage: process.env.GIT_COMMIT_MESSAGE || 'release: bump v${version}',
|
|
25
26
|
tagName: process.env.GIT_TAG_NAME || 'v${version}',
|
|
26
27
|
requireBranch: process.env.GIT_REQUIRE_BRANCH || 'main',
|
package/config/helpers.js
CHANGED
|
@@ -5,6 +5,20 @@ import { fileURLToPath } from 'node:url';
|
|
|
5
5
|
const __filename = fileURLToPath(import.meta.url);
|
|
6
6
|
const __dirname = dirname(__filename);
|
|
7
7
|
const RUN_SCRIPT_PATH = join(__dirname, '..', 'bin', 'run-script.js');
|
|
8
|
+
const DEFAULT_CHANGELOG_COMMAND = [
|
|
9
|
+
'git log',
|
|
10
|
+
'--pretty=format:"* %s (%h)"',
|
|
11
|
+
'${from}..${to}',
|
|
12
|
+
'--grep="^release"',
|
|
13
|
+
'--grep="^Release"',
|
|
14
|
+
'--grep="^release-"',
|
|
15
|
+
'--grep="^Release-"',
|
|
16
|
+
'--grep="^hotfix"',
|
|
17
|
+
'--grep="^Hotfix"',
|
|
18
|
+
'--grep="^ci"',
|
|
19
|
+
'--grep="^CI"',
|
|
20
|
+
'--invert-grep',
|
|
21
|
+
].join(' ');
|
|
8
22
|
|
|
9
23
|
const DOUBLE_QUOTE = /["\\]/g;
|
|
10
24
|
|
|
@@ -50,3 +64,7 @@ export function createReleaseNotesGenerator() {
|
|
|
50
64
|
return output ? `${output}\n` : fallbackReleaseNotes(version);
|
|
51
65
|
};
|
|
52
66
|
}
|
|
67
|
+
|
|
68
|
+
export function getGitChangelogCommand() {
|
|
69
|
+
return process.env.GIT_CHANGELOG_COMMAND || DEFAULT_CHANGELOG_COMMAND;
|
|
70
|
+
}
|
package/config/hotfix.js
CHANGED
|
@@ -14,12 +14,12 @@
|
|
|
14
14
|
* ```
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import { createReleaseNotesGenerator, runScriptCommand } from './helpers.js';
|
|
17
|
+
import { createReleaseNotesGenerator, getGitChangelogCommand, runScriptCommand } from './helpers.js';
|
|
18
18
|
|
|
19
19
|
const config = {
|
|
20
20
|
increment: process.env.HOTFIX_INCREMENT || 'patch',
|
|
21
21
|
git: {
|
|
22
|
-
changelog:
|
|
22
|
+
changelog: getGitChangelogCommand(),
|
|
23
23
|
commitMessage: process.env.GIT_COMMIT_MESSAGE || 'hotfix: bump v${version}',
|
|
24
24
|
tagName: process.env.GIT_TAG_NAME || 'v${version}',
|
|
25
25
|
requireBranch: process.env.GIT_REQUIRE_BRANCH || 'main',
|
|
@@ -29,10 +29,11 @@
|
|
|
29
29
|
* ```
|
|
30
30
|
*/
|
|
31
31
|
|
|
32
|
-
import { createReleaseNotesGenerator, runScriptCommand } from './helpers.js';
|
|
32
|
+
import { createReleaseNotesGenerator, getGitChangelogCommand, runScriptCommand } from './helpers.js';
|
|
33
33
|
|
|
34
34
|
const config = {
|
|
35
35
|
git: {
|
|
36
|
+
changelog: getGitChangelogCommand(),
|
|
36
37
|
commitMessage: process.env.GIT_COMMIT_MESSAGE || 'release: bump v${version}',
|
|
37
38
|
tagName: process.env.GIT_TAG_NAME || 'v${version}',
|
|
38
39
|
requireBranch: process.env.GIT_REQUIRE_BRANCH || 'main',
|
package/config/republish.js
CHANGED
|
@@ -18,11 +18,12 @@
|
|
|
18
18
|
* ```
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
|
-
import { createReleaseNotesGenerator, runScriptCommand } from './helpers.js';
|
|
21
|
+
import { createReleaseNotesGenerator, getGitChangelogCommand, runScriptCommand } from './helpers.js';
|
|
22
22
|
|
|
23
23
|
const config = {
|
|
24
24
|
increment: false,
|
|
25
25
|
git: {
|
|
26
|
+
changelog: getGitChangelogCommand(),
|
|
26
27
|
commitMessage: process.env.GIT_COMMIT_MESSAGE || 'chore: republish v${version}',
|
|
27
28
|
tagName: process.env.GIT_TAG_NAME || 'v${version}',
|
|
28
29
|
tagAnnotation: 'Release ${version} (republished)',
|
|
@@ -97,6 +97,12 @@ export function parseCommitsWithMultiplePrefixes(gitOutput, repoUrl) {
|
|
|
97
97
|
if (parts.length === 0) {
|
|
98
98
|
const firstLine = body.split('\n')[0].trim();
|
|
99
99
|
if (firstLine) {
|
|
100
|
+
const lowerFirstLine = firstLine.toLowerCase();
|
|
101
|
+
const ignoredPatterns = [/^release\b/, /^hotfix\b/, /^ci\b/];
|
|
102
|
+
const shouldSkip = ignoredPatterns.some((pattern) => pattern.test(lowerFirstLine));
|
|
103
|
+
if (shouldSkip) {
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
100
106
|
allParts.push({
|
|
101
107
|
type: 'misc',
|
|
102
108
|
description: firstLine,
|
|
@@ -157,7 +157,7 @@ export function validateNpmAuth(deps) {
|
|
|
157
157
|
};
|
|
158
158
|
}
|
|
159
159
|
catch (error) {
|
|
160
|
-
const tokenEnvVars = ['NPM_TOKEN', '
|
|
160
|
+
const tokenEnvVars = ['NPM_TOKEN', 'NPM_TOKEN', 'NPM_CONFIG__AUTH', 'NPM_CONFIG_TOKEN'];
|
|
161
161
|
const hasAutomationToken = tokenEnvVars.some((name) => {
|
|
162
162
|
const value = deps.getEnv(name);
|
|
163
163
|
return typeof value === 'string' && value.trim().length > 0;
|