1+ export const AUTO_RELEASE_START = '<!-- auto-release:start -->' ;
2+ export const AUTO_RELEASE_END = '<!-- auto-release:end -->' ;
3+
4+ const checkboxText = 'Auto release' ;
5+ const blockPattern = new RegExp (
6+ `${ escapeRegExp ( AUTO_RELEASE_START ) } [\\s\\S]*?${ escapeRegExp ( AUTO_RELEASE_END ) } \\n*` ,
7+ 'm'
8+ ) ;
19const checkedAutoReleasePattern = / - \s * \[ [ x X ] \] \s * A u t o r e l e a s e / ;
10+ const changesetFrontmatterPattern = / ^ - - - \r ? \n ( [ \s \S ] * ?) \r ? \n - - - / ;
11+ const changesetReleaseTypePattern = / : \s * ( m a j o r | m i n o r | p a t c h ) \b / g;
12+ const versionPackagesTitlePattern = / \b V e r s i o n P a c k a g e s \b / i;
213
314export function hasChangesetFile ( files ) {
415 return files . some ( ( file ) => {
@@ -12,6 +23,92 @@ export function hasChangesetFile(files) {
1223 } ) ;
1324}
1425
26+ export function getChangesetReleaseType ( files ) {
27+ const releaseTypes = files
28+ . filter ( isChangesetFile )
29+ . flatMap ( ( file ) => parseChangesetReleaseTypes ( getChangesetContent ( file ) ) ) ;
30+
31+ if ( releaseTypes . includes ( 'major' ) ) return 'major' ;
32+ if ( releaseTypes . includes ( 'minor' ) ) return 'minor' ;
33+ if ( releaseTypes . includes ( 'patch' ) ) return 'patch' ;
34+
35+ return null ;
36+ }
37+
1538export function isAutoReleaseChecked ( body = '' ) {
16- return checkedAutoReleasePattern . test ( body ) ;
39+ const block = getAutoReleaseBlock ( body ) ;
40+
41+ return checkedAutoReleasePattern . test ( block ) ;
42+ }
43+
44+ export function isVersionPackagesTitle ( title = '' ) {
45+ return versionPackagesTitlePattern . test ( title ) ;
46+ }
47+
48+ export function shouldManageAutoReleaseBlock ( { files, title } ) {
49+ return ! isVersionPackagesTitle ( title ) && hasChangesetFile ( files ) ;
50+ }
51+
52+ export function upsertAutoReleaseBlock (
53+ body ,
54+ { defaultChecked = false , hasChangeset }
55+ ) {
56+ const bodyWithoutBlock = body . replace ( blockPattern , '' ) . trimEnd ( ) ;
57+
58+ if ( ! hasChangeset ) {
59+ return bodyWithoutBlock ;
60+ }
61+
62+ const checked = getAutoReleaseBlock ( body )
63+ ? isAutoReleaseChecked ( body )
64+ : defaultChecked ;
65+ const checkbox = `- [${ checked ? 'x' : ' ' } ] ${ checkboxText } ` ;
66+ const block = `${ AUTO_RELEASE_START }
67+ ${ checkbox }
68+ ${ AUTO_RELEASE_END } `;
69+
70+ return `${ block } ${ bodyWithoutBlock ? `\n\n${ bodyWithoutBlock } ` : '' } \n` ;
71+ }
72+
73+ function getAutoReleaseBlock ( body ) {
74+ return body . match ( blockPattern ) ?. [ 0 ] ?? '' ;
75+ }
76+
77+ function getChangesetContent ( file ) {
78+ if ( typeof file === 'string' ) return '' ;
79+ if ( typeof file . contents === 'string' ) return file . contents ;
80+ if ( typeof file . content === 'string' ) return file . content ;
81+ if ( typeof file . patch === 'string' ) return getAddedPatchContent ( file . patch ) ;
82+
83+ return '' ;
84+ }
85+
86+ function getAddedPatchContent ( patch ) {
87+ return patch
88+ . split ( '\n' )
89+ . filter ( ( line ) => line . startsWith ( '+' ) && ! line . startsWith ( '+++' ) )
90+ . map ( ( line ) => line . slice ( 1 ) )
91+ . join ( '\n' ) ;
92+ }
93+
94+ function isChangesetFile ( file ) {
95+ const filename = typeof file === 'string' ? file : file . filename ;
96+
97+ return (
98+ filename ?. startsWith ( '.changeset/' ) &&
99+ filename . endsWith ( '.md' ) &&
100+ filename !== '.changeset/README.md'
101+ ) ;
102+ }
103+
104+ function parseChangesetReleaseTypes ( content ) {
105+ const frontmatter = content . match ( changesetFrontmatterPattern ) ?. [ 1 ] ;
106+
107+ return [ ...( frontmatter ?? '' ) . matchAll ( changesetReleaseTypePattern ) ] . map (
108+ ( match ) => match [ 1 ]
109+ ) ;
110+ }
111+
112+ function escapeRegExp ( value ) {
113+ return value . replace ( / [ . * + ? ^ $ { } ( ) | [ \] \\ ] / g, '\\$&' ) ;
17114}
0 commit comments