Tucker McKnight <tucker@pangolin.lan> | Sun Feb 22 2026
[WIP] get pages un-broken and loading Needs code cleanup here. Tags are not displayed, but pages that expected to have branches available to them now have branches available.
35
+ branchesToPull: ['main', 'develop', 'release/**'],35
+ branches: ['main', 'develop', 'release/**'],1
import {repos, getBranchNames} from './src/repos.ts'1
import {repos, getBranchesAndTags} from './src/repos.ts'26
export function beforeHook(eleventyConfig, reposConfiguration) {26
export function beforeHook(eleventyConfig: any, reposConfiguration: ReposConfiguration) {
const validator = ajv.compile(ConfigSchema)
const valid = validator(reposConfiguration)
if (!valid) {
throw new Error(validator.errors.map(error => `config object at ${error.instancePath.replaceAll("/", ".")}: ${error.message}`).join("\n"))
}
41
const fetchCommands = (await getBranchNames(repoConfig, repoName)).map(branch => `git -C ${location} fetch origin ${branch}:${branch}`).join('; ')41
const {branches, tags} = await getBranchesAndTags(repoConfig, repoName)
const branchNames = branches.map(branch => branch.name)
const tagNames = branches.map(tag => tag.name)
const fetchCommands = branchNames.concat(tagNames).map(ref => `git -C ${location} fetch origin ${ref}:${ref}`).join('; ')109
for (let branch of await getBranchNames(repoConfig, repoName)) {109
const branchesAndTags = await getBranchesAndTags(repoConfig, repoName)
const branchNames = branchesAndTags.branches.map(branch => branch.name)
const tagNames = branchesAndTags.tags.map(tag => tag.name)
for (let branch of branchNames) {119
119
for (let tag of tagNames) {
await exec(`(cd ${tempDirRepoPath} && git checkout ${tag})`)
for (let buildStep of repoConfig.buildSteps) {
// Run the command for each step in each branch
await exec(`(cd ${tempDirRepoPath} && ${buildStep.command})`)
// Copy the specified folders from the "from" to the "to" dir
await exec(`cp -r ${tempDirRepoPath}/${buildStep.copyFrom} ${directories.output}${eleventyConfig.getFilter("slugify")(repoName)}/tags/${eleventyConfig.getFilter("slugify")(tag)}/${buildStep.copyTo}`)
}
}5
"branchesToPull": {5
"branches": {114 115 116 117
"glob": {
"type": "string"
},
"glob",114 115 116 117
},
"pattern": {
"type": "string"
"pattern",135
"branchesToPull"135
"branches"11
* branchesToPull: ['main', 'develop']11
* branches: ['main', 'develop']53 54
branchesToPull: Array<string | {pattern: string, max?: number, compareTo?: string, description?: string}>,
tags?: Array<string | {glob: string, max: number}>,53 54
branches: Array<string | {pattern: string, max?: number, compareTo?: string, description?: string}>,
// todo: make tags optional (and branches, too?) and auto-populate with ** if it's not filled in.
tags: Array<string | {pattern: string, max: number}>,14 15 16 17 18 19 20
const branchesForReposMap: Map<string, Array<{name: string, description?: string, compareTO?: string}>> = new Map()
const getBranches = async (repoConfig: GitConfig, repoName: string): Promise<Array<{name: string, description?: string, compareTo?: string}>> => {
return cachedBranchNames
// Get all branches available in the repository
// Sort the list of branch descriptions from branchesToPull by the length
let branchRules: Array<{pattern: string, matches: Array<string>, rules: RulesObject}> = repoConfig.branchesToPull.map((branchDescription) => {14 15 16 17 18 19 20
const branchesForReposMap: Map<string, Array<{name: string, description?: string, compareTo?: string}>> = new Map()
const tagsForReposMap: Map<string, Array<{name: string}>> = new Map()
const getBranchesAndTags = async (
repoConfig: GitConfig,
repoName: string
): Promise<{
branches: Array<{name: string, description?: string, compareTo?: string}>,
tags: Array<{name: string}>,
}> => {
const cachedTagNames = tagsForReposMap.get(repoName)
return {branches: cachedBranchNames, tags: cachedTagNames}
// Get all branches and tags available in the repository
const allTags = (await exec(`git -C ${repoConfig.location} tag`)).stdout.split("\n").filter(tag => tag !== '')
// Sort the list of branch descriptions from `branches` by the length
let branchRules: Array<{pattern: string, matches: Array<string>, rules: RulesObject}> = repoConfig.branches.map((branchDescription) => {47
47
let tagRules: Array<{pattern: string, matches: Array<string>, rules: RulesObject}> = repoConfig.tags.map((tagDescription) => {
const rules: RulesObject = {}
if (typeof tagDescription !== 'string') {
if (tagDescription.max) { rules.max = tagDescription.max }
}
return {
pattern: (typeof tagDescription === 'string' ? tagDescription : tagDescription.pattern),
matches: [],
rules,
}
})
tagRules.sort((a, b) => b.pattern.length - a.pattern.length)66
66
allTags.forEach((tagName) => {
const matchingPatternIndex = tagRules.findIndex((tagRule) => {
return minimatch(tagName, tagRule.pattern)
})
if (matchingPatternIndex === -1) { return }
const matchedRule = tagRules[matchingPatternIndex]
matchedRule.matches.push(tagName)
if (
matchedRule.rules?.max
&& matchedRule.rules?.max < matchedRule.matches.length
) {
matchedRule.matches.pop()
}
})
79 80 81 82 83 84
return branches
}
const getBranchNames = async (repoConfig, repoName) => {
return (await getBranches(repoConfig, repoName)).map(branch => branch.name)79 80 81 82 83 84
const tags: Array<{ name: string }> = tagRules.map((tagRule) => {
return tagRule.matches.map((match) => {
const result = {name: match}
return result
}).flat()
}).flat()
if (tagsForReposMap.get(repoName) === undefined) {
tagsForReposMap.set(repoName, tags)
}
return { branches, tags }100 101 102
const branchesToAdd = await getBranches(reposConfig.repos[repoName], repoName)
for (const branchName of await getBranchNames(reposConfig.repos[repoName], repoName)) {
const branches = await Promise.all(branchesToAdd.map(async (branch) => {100 101 102
const branchesAndTags = await getBranchesAndTags(reposConfig.repos[repoName], repoName)
const branchNames = branchesAndTags.branches.map(branch => branch.name)
for (const branchName of branchNames) {
const branches = await Promise.all(branchesAndTags.branches.map(async (branch) => {122
const branchDescription = branchesToAdd.find(branchToAdd => branchToAdd.name === branch.name)122
const branchDescription = branchesAndTags.branches.find(branchToAdd => branchToAdd.name === branch.name)172
export {repos, getBranchNames}172
export {repos, getBranchesAndTags}