Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 17 additions & 35 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,15 @@ module.exports = (robot, { getRouter }, Settings = require('./lib/settings')) =>
}
}

async function syncSubOrgSettings (nop, context, suborg, repo = context.repo(), ref) {
async function syncSettings (nop, context, repo = context.repo(), ref) {
try {
deploymentConfig = await loadYamlFileSystem()
robot.log.debug(`deploymentConfig is ${JSON.stringify(deploymentConfig)}`)
const configManager = new ConfigManager(context, ref)
const runtimeConfig = await configManager.loadGlobalSettingsYaml()
const config = Object.assign({}, deploymentConfig, runtimeConfig)
robot.log.debug(`config for ref ${ref} is ${JSON.stringify(config)}`)
return Settings.syncSubOrgs(nop, context, suborg, repo, config, ref)
return Settings.sync(nop, context, repo, config, ref)
} catch (e) {
if (nop) {
let filename = env.SETTINGS_FILE_PATH
Expand All @@ -65,25 +65,25 @@ module.exports = (robot, { getRouter }, Settings = require('./lib/settings')) =>
}
}

async function syncSettings (nop, context, repo = context.repo(), ref) {
async function syncSelectedSettings (nop, context, repos, subOrgs, ref) {
try {
deploymentConfig = await loadYamlFileSystem()
robot.log.debug(`deploymentConfig is ${JSON.stringify(deploymentConfig)}`)
const configManager = new ConfigManager(context, ref)
const runtimeConfig = await configManager.loadGlobalSettingsYaml()
const config = Object.assign({}, deploymentConfig, runtimeConfig)
robot.log.debug(`config for ref ${ref} is ${JSON.stringify(config)}`)
return Settings.sync(nop, context, repo, config, ref)
return Settings.syncSelectedRepos(nop, context, repos, subOrgs, config, ref)
} catch (e) {
if (nop) {
let filename = env.SETTINGS_FILE_PATH
if (!deploymentConfig) {
filename = env.DEPLOYMENT_CONFIG_FILE_PATH
deploymentConfig = {}
}
const nopcommand = new NopCommand(filename, repo, null, e, 'ERROR')
const nopcommand = new NopCommand(filename, context.repo(), null, e, 'ERROR')
robot.log.error(`NOPCOMMAND ${JSON.stringify(nopcommand)}`)
Settings.handleError(nop, context, repo, deploymentConfig, ref, nopcommand)
Settings.handleError(nop, context, context.repo(), deploymentConfig, ref, nopcommand)
} else {
throw e
}
Expand Down Expand Up @@ -264,17 +264,11 @@ module.exports = (robot, { getRouter }, Settings = require('./lib/settings')) =>
}

const repoChanges = getAllChangedRepoConfigs(payload, context.repo().owner)
if (repoChanges.length > 0) {
return Promise.all(repoChanges.map(repo => {
return syncSettings(false, context, repo)
}))
}

const changes = getAllChangedSubOrgConfigs(payload)
if (changes.length) {
return Promise.all(changes.map(suborg => {
return syncSubOrgSettings(false, context, suborg)
}))
const subOrgChanges = getAllChangedSubOrgConfigs(payload)

if (repoChanges.length > 0 || subOrgChanges.length > 0) {
return syncSelectedSettings(false, context, repoChanges, subOrgChanges)
}

robot.log.debug(`No changes in '${Settings.FILE_PATH}' detected, returning...`)
Expand Down Expand Up @@ -572,15 +566,10 @@ module.exports = (robot, { getRouter }, Settings = require('./lib/settings')) =>
robot.log.debug(`Updating check run ${JSON.stringify(params)}`)
await context.octokit.checks.update(params)

// guarding against null value from upstream libary that is
// causing a 404 and the check to stall
// from issue: https://github.com/github/safe-settings/issues/185#issuecomment-1075240374
if (check_suite.before === '0000000000000000000000000000000000000000') {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this seems like it would cause a regression of #185

why remove it?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because we have changed the API call to a different one which does not require the before and after commits.

check_suite.before = check_suite.pull_requests[0].base.sha
}
params = Object.assign(context.repo(), { basehead: `${check_suite.before}...${check_suite.after}` })
const changes = await context.octokit.repos.compareCommitsWithBasehead(params)
const files = changes.data.files.map(f => { return f.filename })
params = Object.assign(context.repo(), { pull_number: pull_request.number })

const changes = await context.octokit.pulls.listFiles(params)
Comment on lines +574 to +576
Copy link

Copilot AI Oct 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The variable params is being reused for different purposes. Consider using a more descriptive variable name like pullRequestParams to improve code clarity and avoid confusion with the previous check run parameters.

Copilot uses AI. Check for mistakes.

const files = changes.data.map(f => { return f.filename })

const settingsModified = files.includes(Settings.FILE_PATH)

Expand All @@ -590,17 +579,10 @@ module.exports = (robot, { getRouter }, Settings = require('./lib/settings')) =>
}

const repoChanges = getChangedRepoConfigName(files, context.repo().owner)
if (repoChanges.length > 0) {
return Promise.all(repoChanges.map(repo => {
return syncSettings(true, context, repo, pull_request.head.ref)
}))
}

const subOrgChanges = getChangedSubOrgConfigName(files)
Copy link

Copilot AI Oct 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inconsistent property naming: getChangedSubOrgConfigName returns objects with name property while getAllChangedSubOrgConfigs returns objects with repo property. This inconsistency will cause issues when both are processed by the same batch method.

Copilot uses AI. Check for mistakes.

if (subOrgChanges.length) {
return Promise.all(subOrgChanges.map(suborg => {
return syncSubOrgSettings(true, context, suborg, context.repo(), pull_request.head.ref)
}))

if (repoChanges.length > 0 || subOrgChanges.length > 0) {
return syncSelectedSettings(true, context, repoChanges, subOrgChanges, pull_request.head.ref)
}

// if no safe-settings changes detected, send a success to the check run
Expand Down
38 changes: 33 additions & 5 deletions lib/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,31 @@ class Settings {
}
}

static async syncSelectedRepos (nop, context, repos, subOrgs, config, ref) {
const settings = new Settings(nop, context, context.repo(), config, ref)

try {
for (const repo of repos) {
settings.repo = repo
await settings.loadConfigs(repo)
if (settings.isRestricted(repo.repo)) {
continue
}
await settings.updateRepos(repo)
}
for (const suborg of subOrgs) {
settings.subOrgConfigMap = [suborg]
settings.suborgChange = !!suborg
await settings.loadConfigs()
await settings.updateAll()
}
await settings.handleResults()
} catch (error) {
settings.logError(error.message)
await settings.handleResults()
}
}

static async sync (nop, context, repo, config, ref) {
const settings = new Settings(nop, context, repo, config, ref)
try {
Expand Down Expand Up @@ -506,17 +531,20 @@ ${this.results.reduce((x, y) => {
log.debug('Fetching repositories')
return github.paginate('GET /installation/repositories').then(repositories => {
return Promise.all(repositories.map(repository => {
if (this.isRestricted(repository.name)) {
return null
}

const { owner, name } = repository
return this.updateRepos({ owner: owner.login, repo: name })
return this.checkAndProcessRepo(owner.login, name)
})
)
})
}

async checkAndProcessRepo (owner, name) {
if (this.isRestricted(name)) {
return null
}
return this.updateRepos({ owner, repo: name })
}

/**
* Loads a file from GitHub
*
Expand Down