(config: BumpyConfig)
| 25 | * versionPr.branch = "<base-branch>-<name>". |
| 26 | */ |
| 27 | export function resolveChannels(config: BumpyConfig): Map<string, ResolvedChannel> { |
| 28 | const channels = new Map<string, ResolvedChannel>(); |
| 29 | const seenBranches = new Map<string, string>(); |
| 30 | |
| 31 | for (const [name, raw] of Object.entries(config.channels || {})) { |
| 32 | if (!/^[a-zA-Z0-9][a-zA-Z0-9._-]*$/.test(name) || name.startsWith('_') || RESERVED_CHANNEL_NAMES.has(name)) { |
| 33 | throw new Error( |
| 34 | `Invalid channel name "${name}" — channel names become .bumpy/ subdirectories and must be ` + |
| 35 | 'alphanumeric (plus ".", "-", "_"), not start with "_", and not collide with reserved entries.', |
| 36 | ); |
| 37 | } |
| 38 | if (!raw.branch || typeof raw.branch !== 'string') { |
| 39 | throw new Error(`Channel "${name}" is missing required "branch" field`); |
| 40 | } |
| 41 | if (raw.branch === config.baseBranch) { |
| 42 | throw new Error(`Channel "${name}" cannot use the base branch ("${config.baseBranch}") as its channel branch`); |
| 43 | } |
| 44 | const existing = seenBranches.get(raw.branch); |
| 45 | if (existing) { |
| 46 | throw new Error(`Channels "${existing}" and "${name}" both use branch "${raw.branch}"`); |
| 47 | } |
| 48 | seenBranches.set(raw.branch, name); |
| 49 | |
| 50 | channels.set(name, { |
| 51 | name, |
| 52 | branch: raw.branch, |
| 53 | preid: raw.preid ?? name, |
| 54 | tag: raw.tag ?? name, |
| 55 | versionPr: { |
| 56 | title: raw.versionPr?.title ?? `${config.versionPr.title} (${name})`, |
| 57 | branch: raw.versionPr?.branch ?? `${config.versionPr.branch}-${name}`, |
| 58 | automerge: raw.versionPr?.automerge ?? false, |
| 59 | }, |
| 60 | }); |
| 61 | } |
| 62 | |
| 63 | return channels; |
| 64 | } |
| 65 | |
| 66 | /** Names of all configured channels (used as `.bumpy/` subdirectory names) */ |
| 67 | export function channelNames(config: BumpyConfig): string[] { |
no outgoing calls
no test coverage detected
searching dependent graphs…