Skip to content

Commit

Permalink
refactor: improve fetching repositories with custom properties
Browse files Browse the repository at this point in the history
  • Loading branch information
PendaGTP committed Jan 20, 2025
1 parent 774b2e5 commit a178f47
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 18 deletions.
68 changes: 52 additions & 16 deletions lib/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -768,16 +768,10 @@ ${this.results.reduce((x, y) => {
})
}
if (data.suborgproperties) {
const promises = data.suborgproperties.map((customProperty) => {
return this.getReposForCustomProperty(customProperty)
})
await Promise.all(promises).then(res => {
res.forEach(r => {
r.forEach(e => {
this.storeSubOrgConfigIfNoConflicts(subOrgConfigs, override.path, e.repository_name, data)
})
})
})
const subOrgRepositories = await this.getSubOrgRepositories(data.suborgproperties)
subOrgRepositories.forEach(repo =>
this.storeSubOrgConfigIfNoConflicts(subOrgConfigs, override.path, repo.repository_name, data)
)
}
}

Expand Down Expand Up @@ -876,12 +870,54 @@ ${this.results.reduce((x, y) => {
return this.github.paginate(options)
}

async getReposForCustomProperty (customPropertyTuple) {
const name = Object.keys(customPropertyTuple)[0]
let q = `props.${name}:${customPropertyTuple[name]}`
q = encodeURIComponent(q)
const options = this.github.request.endpoint((`/orgs/${this.repo.owner}/properties/values?repository_query=${q}`))
return this.github.paginate(options)
async getRepositoriesByProperty (organizationName, propertyFilter) {
if (!organizationName || !propertyFilter) {
throw new Error('Organization name and property filter are required')
}

const [name] = Object.keys(propertyFilter)
const value = propertyFilter[name]

try {
const query = `props.${name}.${value}`
const encodedQuery = encodeURIComponent(query)

return this.github.paginate(
this.github.repos.getCustomPropertiesValues,
{
org: organizationName,
repository_query: encodedQuery,
per_page: 100
}
)
} catch (error) {
throw new Error(`Failed to filter repositories for property ${name}: ${error.message}`)
}
}

async getSubOrgRepositories (subOrgProperties) {
const organizationName = this.repo.owner
try {
const repositories = await Promise.all(
subOrgProperties.map(property =>
this.getRepositoriesByProperty(organizationName, property)
)
)

// Deduplicate repositories based on repository_name
const uniqueRepos = repositories
.flat()
.reduce((unique, repo) => {
unique.set(repo.repository_name, repo)
return unique
}, new Map())

const result = Array.from(uniqueRepos.values())

return result
} catch (error) {
throw new Error(`Failed to fetch suborg repositories: ${error.message}`)
}
}

isObject (item) {
Expand Down
4 changes: 2 additions & 2 deletions test/unit/lib/settings.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ repository:
jest.spyOn(settings, 'loadConfigMap').mockImplementation(() => [{ name: "frontend", path: ".github/suborgs/frontend.yml" }])
jest.spyOn(settings, 'loadYaml').mockImplementation(() => subOrgConfig)
jest.spyOn(settings, 'getReposForTeam').mockImplementation(() => [{ name: 'repo-test' }])
jest.spyOn(settings, 'getReposForCustomProperty').mockImplementation(() => [{ repository_name: 'repo-for-property' }])
jest.spyOn(settings, 'getSubOrgRepositories').mockImplementation(() => [{ repository_name: 'repo-for-property' }])

const subOrgConfigs = await settings.getSubOrgConfigs()
expect(settings.loadConfigMap).toHaveBeenCalledTimes(1)
Expand All @@ -251,7 +251,7 @@ repository:
jest.spyOn(settings, 'loadConfigMap').mockImplementation(() => [{ name: "frontend", path: ".github/suborgs/frontend.yml" }, { name: "backend", path: ".github/suborgs/backend.yml" }])
jest.spyOn(settings, 'loadYaml').mockImplementation(() => subOrgConfig)
jest.spyOn(settings, 'getReposForTeam').mockImplementation(() => [{ name: 'repo-test' }])
jest.spyOn(settings, 'getReposForCustomProperty').mockImplementation(() => [{ repository_name: 'repo-for-property' }])
jest.spyOn(settings, 'getSubOrgRepositories').mockImplementation(() => [{ repository_name: 'repo-for-property' }])

expect(async () => await settings.getSubOrgConfigs()).rejects.toThrow('Multiple suborg configs for new-repo in .github/suborgs/backend.yml and .github/suborgs/frontend.yml')
// try {
Expand Down

0 comments on commit a178f47

Please sign in to comment.