|
| 1 | +import type { PluginSimple } from 'markdown-it'; |
| 2 | +import { getReleaseFromPath, tagUnderscored, type Release } from '../data/releases.js'; |
| 3 | + |
| 4 | +const TOKEN_RE = /\{\{\s*release\.([a-zA-Z0-9_.]+)\s*\}\}/g; |
| 5 | + |
| 6 | +export function replaceReleaseTokens(input: string, release: Release): string { |
| 7 | + return input.replace(TOKEN_RE, (match, key) => { |
| 8 | + const value = resolve(release, key); |
| 9 | + return value !== undefined ? value : match; |
| 10 | + }); |
| 11 | +} |
| 12 | + |
| 13 | +function resolve(release: Release, key: string): string | undefined { |
| 14 | + if (key === 'tag') return release.tag; |
| 15 | + if (key === 'tagUnderscored') return tagUnderscored(release.tag); |
| 16 | + if (key === 'previousTag') return release.previousTag; |
| 17 | + if (key === 'previousTagUnderscored') |
| 18 | + return release.previousTag ? tagUnderscored(release.previousTag) : undefined; |
| 19 | + |
| 20 | + const imageMatch = key.match(/^image\.([a-z_]+)$/); |
| 21 | + if (imageMatch) { |
| 22 | + const name = imageMatch[1] as keyof Release['images']; |
| 23 | + if (release.images[name]) return `ghcr.io/datasharingframework/${name}:${release.tag}`; |
| 24 | + } |
| 25 | + const previousImageMatch = key.match(/^previousImage\.([a-z_]+)$/); |
| 26 | + if (previousImageMatch && release.previousTag) { |
| 27 | + const name = previousImageMatch[1] as keyof Release['images']; |
| 28 | + if (release.images[name]) return `ghcr.io/datasharingframework/${name}:${release.previousTag}`; |
| 29 | + } |
| 30 | + const digestMatch = key.match(/^digest\.([a-z_]+)$/); |
| 31 | + if (digestMatch) { |
| 32 | + const name = digestMatch[1] as keyof Release['images']; |
| 33 | + const digest = release.images[name]?.digest; |
| 34 | + if (!digest || /TODO/i.test(digest)) return '<digest>'; |
| 35 | + return digest.replace(/^sha256:/, ''); |
| 36 | + } |
| 37 | + return undefined; |
| 38 | +} |
| 39 | + |
| 40 | +export const releaseVarsPlugin: PluginSimple = (md) => { |
| 41 | + md.core.ruler.before('normalize', 'release-vars', (state) => { |
| 42 | + const env = state.env ?? {}; |
| 43 | + const filePath: string = env.filePathRelative ?? env.filePath ?? ''; |
| 44 | + if (!filePath) return; |
| 45 | + |
| 46 | + const release = getReleaseFromPath('/' + filePath.replace(/^\/+/, '')); |
| 47 | + if (!release) return; |
| 48 | + |
| 49 | + state.src = replaceReleaseTokens(state.src, release); |
| 50 | + }); |
| 51 | +}; |
0 commit comments