@oorabona/release-it-preset 1.2.0 → 1.3.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 +58 -1601
- package/bin/cli.js +2 -0
- package/dist/scripts/annotate-changelog.js +546 -0
- package/dist/scripts/check-pr-status.js +29 -1
- package/dist/scripts/doctor.js +963 -28
- package/dist/scripts/init-project.js +6 -14
- package/dist/scripts/lib/semver-utils.js +127 -0
- package/dist/scripts/lib/workflow-template.js +34 -0
- package/dist/types/annotate-changelog.d.ts +86 -0
- package/dist/types/check-pr-status.d.ts +3 -0
- package/dist/types/doctor.d.ts +7 -1
- package/dist/types/lib/semver-utils.d.ts +15 -0
- package/dist/types/lib/workflow-template.d.ts +14 -0
- package/package.json +10 -3
- package/scripts/templates/workflows/release.yml.template +4 -2
|
@@ -15,11 +15,11 @@
|
|
|
15
15
|
*/
|
|
16
16
|
import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
17
17
|
import { createInterface } from 'node:readline';
|
|
18
|
-
import {
|
|
19
|
-
import { fileURLToPath } from 'node:url';
|
|
18
|
+
import { join } from 'node:path';
|
|
20
19
|
import { runScript } from './lib/run-script.js';
|
|
21
20
|
import { parsePnpmWorkspaceYaml, parseWorkspacesFromPackageJson, resolvePackagePaths, } from './lib/workspace-detect.js';
|
|
22
21
|
import { ValidationError } from './lib/errors.js';
|
|
22
|
+
import { readWorkflowTemplate } from './lib/workflow-template.js';
|
|
23
23
|
// Single source of truth for workflow name validation within this file.
|
|
24
24
|
// NOTE: bin/validators.js cannot be imported here — TypeScript compiles scripts/ to
|
|
25
25
|
// dist/scripts/ so a relative '../bin/' import resolves to 'dist/bin/' at runtime
|
|
@@ -173,22 +173,14 @@ export async function writeWorkflow(options, deps) {
|
|
|
173
173
|
deps.log(` To integrate manually, review the template and merge into your existing workflow.`);
|
|
174
174
|
return false;
|
|
175
175
|
}
|
|
176
|
-
// Resolve template path: try compiled position first, fall back to source position.
|
|
177
|
-
// compiled: dist/scripts/init-project.js → ../../scripts/templates/... (2 hops up)
|
|
178
|
-
// source: scripts/init-project.ts → ./templates/... (sibling dir)
|
|
179
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
180
|
-
const __dirname = dirname(__filename);
|
|
181
|
-
const compiledPath = join(__dirname, '..', '..', 'scripts', 'templates', 'workflows', 'release.yml.template');
|
|
182
|
-
const sourcePath = join(__dirname, 'templates', 'workflows', 'release.yml.template');
|
|
183
|
-
const templatePath = deps.existsSync(compiledPath) ? compiledPath : sourcePath;
|
|
184
176
|
let templateContent;
|
|
185
177
|
try {
|
|
186
|
-
templateContent = deps.
|
|
178
|
+
templateContent = readWorkflowTemplate(deps).content;
|
|
187
179
|
}
|
|
188
180
|
catch (error) {
|
|
189
|
-
throw new ValidationError(
|
|
190
|
-
|
|
191
|
-
|
|
181
|
+
throw new ValidationError(error instanceof Error
|
|
182
|
+
? error.message
|
|
183
|
+
: 'Failed to read workflow template. The template ships in scripts/templates/.');
|
|
192
184
|
}
|
|
193
185
|
// Ensure .github/workflows/ exists
|
|
194
186
|
if (!deps.existsSync(workflowDir)) {
|
|
@@ -1,6 +1,100 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Semantic versioning utility functions
|
|
3
3
|
*/
|
|
4
|
+
const SEMVER_PATTERN = String.raw `v?\d+\.\d+\.\d+(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?`;
|
|
5
|
+
const exactRangeRegex = new RegExp(String.raw `^=?${SEMVER_PATTERN}$`);
|
|
6
|
+
const caretRangeRegex = new RegExp(String.raw `^\^\s*(${SEMVER_PATTERN})$`);
|
|
7
|
+
const tildeRangeRegex = new RegExp(String.raw `^~\s*(${SEMVER_PATTERN})$`);
|
|
8
|
+
const greaterThanOrEqualRangeRegex = new RegExp(String.raw `^>=\s*(${SEMVER_PATTERN})$`);
|
|
9
|
+
const workspaceProtocolPassthroughRanges = new Set(['*', '^', '~']);
|
|
10
|
+
function hasPrereleaseOrBuildMetadata(version) {
|
|
11
|
+
const normalized = version.replace(/^v/, '');
|
|
12
|
+
return normalized.includes('-') || normalized.includes('+');
|
|
13
|
+
}
|
|
14
|
+
function parseVersion(version) {
|
|
15
|
+
if (!isValidSemver(version)) {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
const normalized = version.replace(/^v/, '');
|
|
19
|
+
const [major, minor, patch] = normalized.split(/[+-]/)[0].split('.').map(Number);
|
|
20
|
+
return { major, minor, patch, normalized };
|
|
21
|
+
}
|
|
22
|
+
function compareVersions(a, b) {
|
|
23
|
+
if (a.major !== b.major)
|
|
24
|
+
return a.major - b.major;
|
|
25
|
+
if (a.minor !== b.minor)
|
|
26
|
+
return a.minor - b.minor;
|
|
27
|
+
return a.patch - b.patch;
|
|
28
|
+
}
|
|
29
|
+
function includesCaretRange(version, base) {
|
|
30
|
+
if (compareVersions(version, base) < 0) {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
if (base.major > 0) {
|
|
34
|
+
return version.major === base.major;
|
|
35
|
+
}
|
|
36
|
+
if (base.minor > 0) {
|
|
37
|
+
return version.major === 0 && version.minor === base.minor;
|
|
38
|
+
}
|
|
39
|
+
return version.major === 0 && version.minor === 0 && version.patch === base.patch;
|
|
40
|
+
}
|
|
41
|
+
function includesTildeRange(version, base) {
|
|
42
|
+
return compareVersions(version, base) >= 0 && version.major === base.major && version.minor === base.minor;
|
|
43
|
+
}
|
|
44
|
+
function normalizeWorkspaceProtocolRange(trimmed) {
|
|
45
|
+
if (!trimmed.startsWith('workspace:')) {
|
|
46
|
+
return trimmed;
|
|
47
|
+
}
|
|
48
|
+
const workspaceRange = trimmed.slice('workspace:'.length).trim();
|
|
49
|
+
if (workspaceProtocolPassthroughRanges.has(workspaceRange)) {
|
|
50
|
+
return '*';
|
|
51
|
+
}
|
|
52
|
+
if (exactRangeRegex.test(workspaceRange) ||
|
|
53
|
+
caretRangeRegex.test(workspaceRange) ||
|
|
54
|
+
tildeRangeRegex.test(workspaceRange) ||
|
|
55
|
+
greaterThanOrEqualRangeRegex.test(workspaceRange)) {
|
|
56
|
+
return workspaceRange;
|
|
57
|
+
}
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
function evaluateRangePart(range, version) {
|
|
61
|
+
const trimmed = range.trim();
|
|
62
|
+
if (!trimmed) {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
const normalizedRange = normalizeWorkspaceProtocolRange(trimmed);
|
|
66
|
+
if (normalizedRange === null) {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
if (normalizedRange === '*') {
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
const semverOperand = normalizedRange.replace(/^(?:=|\^|~|>=)\s*/, '');
|
|
73
|
+
if (isValidSemver(semverOperand) && hasPrereleaseOrBuildMetadata(semverOperand)) {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
const exactMatch = normalizedRange.match(exactRangeRegex);
|
|
77
|
+
if (exactMatch) {
|
|
78
|
+
const exact = parseVersion(normalizedRange.replace(/^=/, ''));
|
|
79
|
+
return exact ? exact.normalized === version.normalized : null;
|
|
80
|
+
}
|
|
81
|
+
const caretMatch = normalizedRange.match(caretRangeRegex);
|
|
82
|
+
if (caretMatch) {
|
|
83
|
+
const base = parseVersion(caretMatch[1]);
|
|
84
|
+
return base ? includesCaretRange(version, base) : null;
|
|
85
|
+
}
|
|
86
|
+
const tildeMatch = normalizedRange.match(tildeRangeRegex);
|
|
87
|
+
if (tildeMatch) {
|
|
88
|
+
const base = parseVersion(tildeMatch[1]);
|
|
89
|
+
return base ? includesTildeRange(version, base) : null;
|
|
90
|
+
}
|
|
91
|
+
const greaterThanOrEqualMatch = normalizedRange.match(greaterThanOrEqualRangeRegex);
|
|
92
|
+
if (greaterThanOrEqualMatch) {
|
|
93
|
+
const base = parseVersion(greaterThanOrEqualMatch[1]);
|
|
94
|
+
return base ? compareVersions(version, base) >= 0 : null;
|
|
95
|
+
}
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
4
98
|
/**
|
|
5
99
|
* Validate if a string is a valid semantic version
|
|
6
100
|
*
|
|
@@ -24,3 +118,36 @@ export function validateAndNormalizeSemver(version) {
|
|
|
24
118
|
}
|
|
25
119
|
return version.replace(/^v/, '');
|
|
26
120
|
}
|
|
121
|
+
/**
|
|
122
|
+
* Check whether a dependency range includes a concrete workspace package version.
|
|
123
|
+
*
|
|
124
|
+
* This intentionally supports only the small zero-dependency subset doctor needs:
|
|
125
|
+
* workspace: protocol ranges, exact versions, ^, ~, >=, and OR-joined (`||`)
|
|
126
|
+
* combinations of those forms. Unknown syntax returns null so advisory checks can
|
|
127
|
+
* skip it without producing false warnings.
|
|
128
|
+
*
|
|
129
|
+
* @param range Dependency range string from package.json
|
|
130
|
+
* @param version Concrete workspace package version
|
|
131
|
+
* @returns true/false when evaluated, null when the syntax is outside the supported subset
|
|
132
|
+
*/
|
|
133
|
+
export function rangeIncludesVersion(range, version) {
|
|
134
|
+
const parsedVersion = parseVersion(version);
|
|
135
|
+
if (!parsedVersion) {
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
if (hasPrereleaseOrBuildMetadata(version)) {
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
const parts = range.split(/\s*\|\|\s*/);
|
|
142
|
+
let sawUnknown = false;
|
|
143
|
+
for (const part of parts) {
|
|
144
|
+
const result = evaluateRangePart(part, parsedVersion);
|
|
145
|
+
if (result === true) {
|
|
146
|
+
return true;
|
|
147
|
+
}
|
|
148
|
+
if (result === null) {
|
|
149
|
+
sawUnknown = true;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return sawUnknown ? null : false;
|
|
153
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { dirname, join } from 'node:path';
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
3
|
+
export const GENERATED_WORKFLOW_MARKER = '# Generated by: release-it-preset init --with-workflows';
|
|
4
|
+
const WORKFLOW_TEMPLATE_RELATIVE_PATH = ['workflows', 'release.yml.template'];
|
|
5
|
+
export function getWorkflowTemplateCandidates(moduleUrl = import.meta.url) {
|
|
6
|
+
const moduleDir = dirname(fileURLToPath(moduleUrl));
|
|
7
|
+
return [
|
|
8
|
+
join(moduleDir, '..', 'templates', ...WORKFLOW_TEMPLATE_RELATIVE_PATH),
|
|
9
|
+
join(moduleDir, '..', '..', '..', 'scripts', 'templates', ...WORKFLOW_TEMPLATE_RELATIVE_PATH),
|
|
10
|
+
];
|
|
11
|
+
}
|
|
12
|
+
export function readWorkflowTemplate(deps, moduleUrl = import.meta.url) {
|
|
13
|
+
const candidates = getWorkflowTemplateCandidates(moduleUrl);
|
|
14
|
+
const templatePath = candidates.find((candidate) => deps.existsSync(candidate)) ?? candidates[0];
|
|
15
|
+
try {
|
|
16
|
+
return {
|
|
17
|
+
path: templatePath,
|
|
18
|
+
content: deps.readFileSync(templatePath, 'utf8'),
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
throw new Error([
|
|
23
|
+
`Failed to read workflow template at "${templatePath}".`,
|
|
24
|
+
'The template ships in scripts/templates/ — if it is missing, reinstall the package.',
|
|
25
|
+
`Original error: ${error}`,
|
|
26
|
+
].join('\n'));
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
export function hasGeneratedWorkflowMarker(content) {
|
|
30
|
+
return content.includes(GENERATED_WORKFLOW_MARKER);
|
|
31
|
+
}
|
|
32
|
+
export function normalizeWorkflowContent(content) {
|
|
33
|
+
return content.replace(/\r\n/g, '\n').replace(/\r/g, '\n').replace(/\n*$/, '\n');
|
|
34
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
/**
|
|
3
|
+
* Annotate [Unreleased] entries from typed pull request changelog blocks.
|
|
4
|
+
*/
|
|
5
|
+
import type { ExecSyncOptions } from 'node:child_process';
|
|
6
|
+
import { readFileSync, writeFileSync } from 'node:fs';
|
|
7
|
+
export interface AnnotateChangelogDeps {
|
|
8
|
+
execSync: (command: string, options?: ExecSyncOptions) => Buffer | string;
|
|
9
|
+
readFileSync: typeof readFileSync;
|
|
10
|
+
writeFileSync: typeof writeFileSync;
|
|
11
|
+
getEnv: (key: string) => string | undefined;
|
|
12
|
+
log: (message: string) => void;
|
|
13
|
+
warn: (message: string) => void;
|
|
14
|
+
}
|
|
15
|
+
export interface PullRequestInfo {
|
|
16
|
+
number: number;
|
|
17
|
+
body?: string | null;
|
|
18
|
+
merged_at?: string | null;
|
|
19
|
+
}
|
|
20
|
+
export interface ChangelogEntry {
|
|
21
|
+
section: string;
|
|
22
|
+
text: string;
|
|
23
|
+
rawLine: string;
|
|
24
|
+
shaList: string[];
|
|
25
|
+
prNumber: number | null;
|
|
26
|
+
order: number;
|
|
27
|
+
}
|
|
28
|
+
export interface ChangelogNote {
|
|
29
|
+
section: string;
|
|
30
|
+
text: string;
|
|
31
|
+
}
|
|
32
|
+
interface UnreleasedBlock {
|
|
33
|
+
prefix: string;
|
|
34
|
+
body: string;
|
|
35
|
+
suffix: string;
|
|
36
|
+
}
|
|
37
|
+
type SectionItem = {
|
|
38
|
+
kind: 'note';
|
|
39
|
+
line: string;
|
|
40
|
+
} | {
|
|
41
|
+
kind: 'entry';
|
|
42
|
+
entry: ChangelogEntry;
|
|
43
|
+
};
|
|
44
|
+
interface ParsedSection {
|
|
45
|
+
heading: string | null;
|
|
46
|
+
items: SectionItem[];
|
|
47
|
+
}
|
|
48
|
+
interface ParsedUnreleased {
|
|
49
|
+
entries: ChangelogEntry[];
|
|
50
|
+
sections: ParsedSection[];
|
|
51
|
+
}
|
|
52
|
+
interface CandidateGroup {
|
|
53
|
+
key: string;
|
|
54
|
+
kind: 'pr' | 'sha';
|
|
55
|
+
ref: string;
|
|
56
|
+
entries: ChangelogEntry[];
|
|
57
|
+
primarySha: string | null;
|
|
58
|
+
}
|
|
59
|
+
interface ResolvedGroup {
|
|
60
|
+
pr: PullRequestInfo;
|
|
61
|
+
entries: ChangelogEntry[];
|
|
62
|
+
primarySha: string | null;
|
|
63
|
+
}
|
|
64
|
+
export declare function extractUnreleasedBlock(changelog: string, changelogPath?: string): UnreleasedBlock;
|
|
65
|
+
export declare function normalizeSectionHeading(rawHeading: string): string;
|
|
66
|
+
export declare function extractCommitShas(value: string): string[];
|
|
67
|
+
export declare function extractPrNumber(value: string): number | null;
|
|
68
|
+
export declare function choosePrimarySha(values: Array<string | null | undefined>): string | null;
|
|
69
|
+
export declare function parseUnreleasedEntries(body: string): ParsedUnreleased;
|
|
70
|
+
export declare function groupEntriesForLookup(entries: ChangelogEntry[]): {
|
|
71
|
+
groups: CandidateGroup[];
|
|
72
|
+
passthrough: ChangelogEntry[];
|
|
73
|
+
};
|
|
74
|
+
export declare function fetchPullRequestByNumber(prNumber: number, ownerRepo: string, deps: AnnotateChangelogDeps): PullRequestInfo | null;
|
|
75
|
+
export declare function fetchPullRequestBySha(sha: string, ownerRepo: string, deps: AnnotateChangelogDeps): PullRequestInfo | null;
|
|
76
|
+
export declare function resolvePullRequestGroups(groups: CandidateGroup[], ownerRepo: string, deps: AnnotateChangelogDeps): {
|
|
77
|
+
resolved: ResolvedGroup[];
|
|
78
|
+
unresolved: ChangelogEntry[];
|
|
79
|
+
};
|
|
80
|
+
export declare function extractStructuredChangelogNotes(body: string | null | undefined, options?: {
|
|
81
|
+
prNumber?: number;
|
|
82
|
+
warn?: (message: string) => void;
|
|
83
|
+
}): ChangelogNote[];
|
|
84
|
+
export declare function renderAnnotatedBody(parsed: ParsedUnreleased, resolvedGroups: ResolvedGroup[], repoUrl: string, deps: AnnotateChangelogDeps): string | null;
|
|
85
|
+
export declare function annotateChangelog(deps: AnnotateChangelogDeps): void;
|
|
86
|
+
export {};
|
|
@@ -12,12 +12,14 @@
|
|
|
12
12
|
*/
|
|
13
13
|
import type { ExecSyncOptions } from 'node:child_process';
|
|
14
14
|
export type ChangelogStatus = 'updated' | 'skipped' | 'missing';
|
|
15
|
+
export type ChangelogBlockStatus = 'present' | 'absent' | 'unknown';
|
|
15
16
|
export interface PrCheckResult {
|
|
16
17
|
baseRef: string | null;
|
|
17
18
|
headRef: string;
|
|
18
19
|
changedFiles: string[];
|
|
19
20
|
commits: string[];
|
|
20
21
|
changelogStatus: ChangelogStatus;
|
|
22
|
+
changelogBlock: ChangelogBlockStatus;
|
|
21
23
|
skipChangelogMarker: boolean;
|
|
22
24
|
hasConventionalCommits: boolean;
|
|
23
25
|
}
|
|
@@ -41,6 +43,7 @@ export declare function evaluateChangelogStatus(changedFiles: string[], changelo
|
|
|
41
43
|
status: ChangelogStatus;
|
|
42
44
|
skipMarker: boolean;
|
|
43
45
|
};
|
|
46
|
+
export declare function evaluateChangelogBlockStatus(deps: PrCheckDeps): ChangelogBlockStatus;
|
|
44
47
|
export declare function getDiffRange(baseRef: string | null, headRef: string): string;
|
|
45
48
|
export declare function runPrCheck(args: {
|
|
46
49
|
base?: string | null;
|
package/dist/types/doctor.d.ts
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* node dist/scripts/doctor.js --json
|
|
14
14
|
*/
|
|
15
15
|
import type { ExecSyncOptions } from 'node:child_process';
|
|
16
|
-
import { existsSync, readFileSync } from 'node:fs';
|
|
16
|
+
import { existsSync, readdirSync, readFileSync } from 'node:fs';
|
|
17
17
|
export type CheckStatus = 'PASS' | 'WARN' | 'FAIL';
|
|
18
18
|
export interface CheckResult {
|
|
19
19
|
name: string;
|
|
@@ -58,12 +58,18 @@ export interface DoctorReport {
|
|
|
58
58
|
export interface DoctorDeps {
|
|
59
59
|
execSync: (command: string, options?: ExecSyncOptions) => Buffer | string;
|
|
60
60
|
existsSync: typeof existsSync;
|
|
61
|
+
readdirSync: typeof readdirSync;
|
|
61
62
|
readFileSync: typeof readFileSync;
|
|
62
63
|
getEnv: (key: string) => string | undefined;
|
|
64
|
+
cwd: () => string;
|
|
63
65
|
}
|
|
64
66
|
export declare function safeExec(command: string, deps: DoctorDeps): string | null;
|
|
65
67
|
export declare function collectEnvironment(deps: DoctorDeps): EnvironmentSection;
|
|
66
68
|
export declare function inspectRepository(deps: DoctorDeps): RepositorySection;
|
|
69
|
+
export declare function validatePublishWorkflowFreshness(deps: DoctorDeps): CheckResult | null;
|
|
70
|
+
export declare function workflowHasIdTokenWritePermission(content: string): boolean;
|
|
71
|
+
export declare function validateNpmProvenanceReadiness(deps: DoctorDeps): CheckResult | null;
|
|
72
|
+
export declare function validateWorkspaceDependencyRanges(deps: DoctorDeps): CheckResult | null;
|
|
67
73
|
export declare function validateConfiguration(deps: DoctorDeps): ConfigurationSection;
|
|
68
74
|
/**
|
|
69
75
|
* Runs Check A (peer range satisfaction) and Check B (major version advisor).
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Semantic versioning utility functions
|
|
3
3
|
*/
|
|
4
|
+
type RangeEvaluation = boolean | null;
|
|
4
5
|
/**
|
|
5
6
|
* Validate if a string is a valid semantic version
|
|
6
7
|
*
|
|
@@ -16,3 +17,17 @@ export declare function isValidSemver(version: string): boolean;
|
|
|
16
17
|
* @returns Normalized version without 'v' prefix
|
|
17
18
|
*/
|
|
18
19
|
export declare function validateAndNormalizeSemver(version: string): string;
|
|
20
|
+
/**
|
|
21
|
+
* Check whether a dependency range includes a concrete workspace package version.
|
|
22
|
+
*
|
|
23
|
+
* This intentionally supports only the small zero-dependency subset doctor needs:
|
|
24
|
+
* workspace: protocol ranges, exact versions, ^, ~, >=, and OR-joined (`||`)
|
|
25
|
+
* combinations of those forms. Unknown syntax returns null so advisory checks can
|
|
26
|
+
* skip it without producing false warnings.
|
|
27
|
+
*
|
|
28
|
+
* @param range Dependency range string from package.json
|
|
29
|
+
* @param version Concrete workspace package version
|
|
30
|
+
* @returns true/false when evaluated, null when the syntax is outside the supported subset
|
|
31
|
+
*/
|
|
32
|
+
export declare function rangeIncludesVersion(range: string, version: string): RangeEvaluation;
|
|
33
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { PathLike } from 'node:fs';
|
|
2
|
+
export declare const GENERATED_WORKFLOW_MARKER = "# Generated by: release-it-preset init --with-workflows";
|
|
3
|
+
export interface WorkflowTemplateDeps {
|
|
4
|
+
existsSync: (path: PathLike) => boolean;
|
|
5
|
+
readFileSync: (path: PathLike, encoding: BufferEncoding) => string | Buffer;
|
|
6
|
+
}
|
|
7
|
+
export interface WorkflowTemplateReadResult {
|
|
8
|
+
path: string;
|
|
9
|
+
content: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function getWorkflowTemplateCandidates(moduleUrl?: string): string[];
|
|
12
|
+
export declare function readWorkflowTemplate(deps: WorkflowTemplateDeps, moduleUrl?: string): WorkflowTemplateReadResult;
|
|
13
|
+
export declare function hasGeneratedWorkflowMarker(content: string): boolean;
|
|
14
|
+
export declare function normalizeWorkflowContent(content: string): string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oorabona/release-it-preset",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "Release tooling for solo and small-team JS maintainers: human-curated changelogs, OIDC zero-config publishing, recovery presets, monorepo support, pre-release diagnostics.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
@@ -97,10 +97,12 @@
|
|
|
97
97
|
},
|
|
98
98
|
"devDependencies": {
|
|
99
99
|
"@biomejs/biome": "^2.4.13",
|
|
100
|
-
"@
|
|
100
|
+
"@release-it-plugins/workspaces": "^5.0.3",
|
|
101
|
+
"@types/node": "^25.9.2",
|
|
101
102
|
"@vitest/coverage-v8": "^4.1.5",
|
|
102
103
|
"nano-staged": "^1.0.2",
|
|
103
104
|
"release-it": "^20.0.1",
|
|
105
|
+
"release-it19": "npm:release-it@^19.2.4",
|
|
104
106
|
"rimraf": "^6.1.3",
|
|
105
107
|
"tsx": "^4.21.0",
|
|
106
108
|
"typescript": "^6.0.3",
|
|
@@ -110,5 +112,10 @@
|
|
|
110
112
|
"engines": {
|
|
111
113
|
"node": ">=20.19.0"
|
|
112
114
|
},
|
|
113
|
-
"packageManager": "pnpm@10.17.1"
|
|
115
|
+
"packageManager": "pnpm@10.17.1",
|
|
116
|
+
"pnpm": {
|
|
117
|
+
"overrides": {
|
|
118
|
+
"undici@<6.24.0": ">=6.24.0 <7"
|
|
119
|
+
}
|
|
120
|
+
}
|
|
114
121
|
}
|
|
@@ -21,8 +21,7 @@ on:
|
|
|
21
21
|
required: false
|
|
22
22
|
|
|
23
23
|
permissions:
|
|
24
|
-
contents:
|
|
25
|
-
id-token: write # Required for npm OIDC trusted publishing
|
|
24
|
+
contents: read
|
|
26
25
|
|
|
27
26
|
env:
|
|
28
27
|
NODE_VERSION: '24' # npm >= 11.5.1 ships with Node 24, required for OIDC trusted publishing
|
|
@@ -30,6 +29,9 @@ env:
|
|
|
30
29
|
jobs:
|
|
31
30
|
publish:
|
|
32
31
|
runs-on: ubuntu-latest
|
|
32
|
+
permissions:
|
|
33
|
+
contents: write
|
|
34
|
+
id-token: write # Required for npm OIDC trusted publishing
|
|
33
35
|
steps:
|
|
34
36
|
- name: Checkout code
|
|
35
37
|
uses: actions/checkout@v6
|