* Close lingering channel release PRs whose cycles were promoted: once a channel's * bump files are pending on this branch (via a promotion or graduation merge), the * source channel's own release PR is obsolete — merging it would re-publish a cycle * that's already moving to its next stage. A fr
( rootDir: string, config: BumpyConfig, bumpFiles: BumpFile[], /** The channel whose release PR is being maintained right now (never close our own) */ currentChannel?: ResolvedChannel, )
| 875 | let diffRange: string; |
| 876 | if (range) { |
| 877 | diffRange = `${range.before}..${range.after}`; |
| 878 | } else { |
| 879 | if (!tryRunArgs(['git', 'rev-parse', '--verify', 'HEAD^'], { cwd: rootDir })) return new Set(); |
| 880 | diffRange = 'HEAD^..HEAD'; |
| 881 | } |
| 882 | // --no-renames so file moves into channel dirs show up as additions |
| 883 | const out = tryRunArgs( |
| 884 | ['git', 'diff', '--name-only', '--diff-filter=A', '--no-renames', diffRange, '--', '.bumpy/'], |
| 885 | { cwd: rootDir }, |
| 886 | ); |
| 887 | if (!out) return new Set(); |
| 888 | const knownChannels = new Set(channelNames(config)); |
| 889 | const arrived = new Set<string>(); |
| 890 | for (const f of out.split('\n')) { |
| 891 | if (!f.endsWith('.md') || f.endsWith('README.md')) continue; |
| 892 | const parts = f.split('/'); // .bumpy/<channel>/<id>.md |
| 893 | if (parts.length === 3 && knownChannels.has(parts[1]!)) arrived.add(parts[1]!); |
| 894 | } |
| 895 | return arrived; |
| 896 | } |
| 897 | |
| 898 | /** |
| 899 | * Close lingering channel release PRs whose cycles were promoted: once a channel's |
| 900 | * bump files are pending on this branch (via a promotion or graduation merge), the |
| 901 | * source channel's own release PR is obsolete — merging it would re-publish a cycle |
| 902 | * that's already moving to its next stage. A fresh release PR is created automatically |
| 903 | * if new work lands on the channel branch. |
| 904 | * |
| 905 | * Only channels whose files arrived in the TRIGGERING push are considered: the files |
| 906 | * stay pending here until our version/release PR merges, and re-closing on every |
| 907 | * later push in that window would kill the release PR of a newly restarted cycle. |
| 908 | */ |
| 909 | async function closePromotedChannelReleasePrs( |
| 910 | rootDir: string, |
| 911 | config: BumpyConfig, |
| 912 | bumpFiles: BumpFile[], |
| 913 | /** The channel whose release PR is being maintained right now (never close our own) */ |
| 914 | currentChannel?: ResolvedChannel, |
| 915 | ): Promise<void> { |
| 916 | const arrived = detectArrivedChannelFiles(rootDir, config); |
| 917 | const promoted = [...new Set(bumpFiles.map((bf) => bf.channel))].filter( |
| 918 | (name): name is string => name != null && name !== currentChannel?.name && arrived.has(name), |
| 919 | ); |
| 920 | if (promoted.length === 0) return; |
| 921 | |
| 922 | const channels = resolveChannels(config); |
| 923 | for (const name of promoted) { |
| 924 | const channel = channels.get(name); |
no test coverage detected
searching dependent graphs…