From f73024038bb7352e1ddb950661089cc18edc791f Mon Sep 17 00:00:00 2001 From: Jonathan Morley Date: Thu, 27 Feb 2025 17:58:24 -0500 Subject: [PATCH 1/3] feat: separate runtime and deployment configs --- index.js | 33 +++----- lib/deploymentConfig.js | 53 +++++------- lib/mergeDeep.js | 8 +- lib/settings.js | 41 +++------ test/unit/lib/deploymentConfig.test.js | 62 ++++++++++++++ test/unit/lib/settings.test.js | 112 +++++++++++++++++-------- test/unit/lib/validator.test.js | 20 +++-- 7 files changed, 205 insertions(+), 124 deletions(-) create mode 100644 test/unit/lib/deploymentConfig.test.js diff --git a/index.js b/index.js index 40e05739..f9c9538c 100644 --- a/index.js +++ b/index.js @@ -4,6 +4,7 @@ const fs = require('fs') const cron = require('node-cron') const Glob = require('./lib/glob') const ConfigManager = require('./lib/configManager') +const DeploymentConfig = require('./lib/deploymentConfig') const NopCommand = require('./lib/nopcommand') const env = require('./lib/env') @@ -13,11 +14,11 @@ module.exports = (robot, { getRouter }, Settings = require('./lib/settings')) => let appSlug = 'safe-settings' async function syncAllSettings (nop, context, repo = context.repo(), ref) { try { - deploymentConfig = await loadYamlFileSystem() + deploymentConfig = await loadYamlFileSystem(context) 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) + const config = { deploymentConfig, runtimeConfig } robot.log.debug(`config for ref ${ref} is ${JSON.stringify(config)}`) if (ref) { return Settings.syncAll(nop, context, repo, config, ref) @@ -42,11 +43,11 @@ module.exports = (robot, { getRouter }, Settings = require('./lib/settings')) => async function syncSubOrgSettings (nop, context, suborg, repo = context.repo(), ref) { try { - deploymentConfig = await loadYamlFileSystem() + deploymentConfig = await loadYamlFileSystem(context) 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) + const config = { deploymentConfig, runtimeConfig } robot.log.debug(`config for ref ${ref} is ${JSON.stringify(config)}`) return Settings.syncSubOrgs(nop, context, suborg, repo, config, ref) } catch (e) { @@ -67,11 +68,11 @@ module.exports = (robot, { getRouter }, Settings = require('./lib/settings')) => async function syncSettings (nop, context, repo = context.repo(), ref) { try { - deploymentConfig = await loadYamlFileSystem() + deploymentConfig = await loadYamlFileSystem(context) 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) + const config = { deploymentConfig, runtimeConfig } robot.log.debug(`config for ref ${ref} is ${JSON.stringify(config)}`) return Settings.sync(nop, context, repo, config, ref) } catch (e) { @@ -92,14 +93,14 @@ module.exports = (robot, { getRouter }, Settings = require('./lib/settings')) => async function renameSync (nop, context, repo = context.repo(), rename, ref) { try { - deploymentConfig = await loadYamlFileSystem() + deploymentConfig = await loadYamlFileSystem(context) 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) - const renameConfig = Object.assign({}, config, rename) + const renameConfig = Object.assign({}, runtimeConfig, rename) + const config = { deploymentConfig, runtimeConfig: renameConfig } robot.log.debug(`config for ref ${ref} is ${JSON.stringify(config)}`) - return Settings.sync(nop, context, repo, renameConfig, ref) + return Settings.sync(nop, context, repo, config, ref) } catch (e) { if (nop) { let filename = env.SETTINGS_FILE_PATH @@ -121,16 +122,8 @@ module.exports = (robot, { getRouter }, Settings = require('./lib/settings')) => * * @return The parsed YAML file */ - async function loadYamlFileSystem () { - if (deploymentConfig === undefined) { - const deploymentConfigPath = env.DEPLOYMENT_CONFIG_FILE - if (fs.existsSync(deploymentConfigPath)) { - deploymentConfig = yaml.load(fs.readFileSync(deploymentConfigPath)) - } else { - deploymentConfig = { restrictedRepos: ['admin', '.github', 'safe-settings'] } - } - } - return deploymentConfig + async function loadYamlFileSystem (context) { + return new DeploymentConfig(context) } function getAllChangedSubOrgConfigs (payload) { diff --git a/lib/deploymentConfig.js b/lib/deploymentConfig.js index 7dd8b932..a639de82 100644 --- a/lib/deploymentConfig.js +++ b/lib/deploymentConfig.js @@ -2,54 +2,47 @@ const yaml = require('js-yaml') const fs = require('fs') const env = require('./env') +function isIterable (obj) { + // checks for null and undefined + if (obj == null) { + return false + } + return typeof obj[Symbol.iterator] === 'function' +} + /** * Class representing a deployment config. - * It is a singleton (class object) for the deployment settings. - * The settings are loaded from the deployment-settings.yml file during initialization and stored as static properties. + * The settings are loaded from the deployment-settings.yml file. */ -class DeploymentConfig { - // static config - static configvalidators = {} - static overridevalidators = {} +module.exports = class DeploymentConfig { + constructor (context, configPath) { + const deploymentConfigPath = configPath ?? env.DEPLOYMENT_CONFIG_FILE - static { - const deploymentConfigPath = process.env.DEPLOYMENT_CONFIG_FILE ? process.env.DEPLOYMENT_CONFIG_FILE : 'deployment-settings.yml' + let deploymentConfig = {} if (fs.existsSync(deploymentConfigPath)) { - this.config = yaml.load(fs.readFileSync(deploymentConfigPath)) + deploymentConfig = yaml.load(fs.readFileSync(deploymentConfigPath)) } else { - this.config = { restrictedRepos: ['admin', '.github', 'safe-settings'] } + context.log.info(`No deployment settings found at ${deploymentConfigPath}`) } - const overridevalidators = this.config.overridevalidators - if (this.isIterable(overridevalidators)) { - for (const validator of overridevalidators) { + this.overridevalidators = {} + if (isIterable(deploymentConfig.overridevalidators)) { + for (const validator of deploymentConfig.overridevalidators) { // eslint-disable-next-line no-new-func const f = new Function('baseconfig', 'overrideconfig', 'githubContext', validator.script) this.overridevalidators[validator.plugin] = { canOverride: f, error: validator.error } } } - const configvalidators = this.config.configvalidators - if (this.isIterable(configvalidators)) { - for (const validator of configvalidators) { + + this.configvalidators = {} + if (isIterable(deploymentConfig.configvalidators)) { + for (const validator of deploymentConfig.configvalidators) { // eslint-disable-next-line no-new-func const f = new Function('baseconfig', 'githubContext', validator.script) this.configvalidators[validator.plugin] = { isValid: f, error: validator.error } } } - } - static isIterable (obj) { - // checks for null and undefined - if (obj == null) { - return false - } - return typeof obj[Symbol.iterator] === 'function' - } - - // eslint-disable-next-line no-useless-constructor - constructor (nop, context, repo, config, ref, suborg) { + this.restrictedRepos = deploymentConfig.restrictedRepos ?? ['admin', '.github', 'safe-settings'] } } -DeploymentConfig.FILE_NAME = `${env.CONFIG_PATH}/settings.yml` - -module.exports = DeploymentConfig diff --git a/lib/mergeDeep.js b/lib/mergeDeep.js index ab278e5c..2747b79a 100644 --- a/lib/mergeDeep.js +++ b/lib/mergeDeep.js @@ -6,12 +6,14 @@ const NAME_USERNAME_PROPERTY = item => NAME_FIELDS.find(prop => Object.prototype const GET_NAME_USERNAME_PROPERTY = item => { if (NAME_USERNAME_PROPERTY(item)) return item[NAME_USERNAME_PROPERTY(item)] } class MergeDeep { - constructor (log, github, ignorableFields = [], configvalidators = {}, overridevalidators = {}) { + constructor (log, github, ignorableFields = []) { this.log = log this.github = github this.ignorableFields = ignorableFields - this.configvalidators = DeploymentConfig.configvalidators - this.overridevalidators = DeploymentConfig.overridevalidators + + const deploymentConfig = new DeploymentConfig({ log }) + this.configvalidators = deploymentConfig.configvalidators + this.overridevalidators = deploymentConfig.overridevalidators } isObjectNotArray (item) { diff --git a/lib/settings.js b/lib/settings.js index 9e00c140..9c07f55b 100644 --- a/lib/settings.js +++ b/lib/settings.js @@ -10,6 +10,7 @@ const env = require('./env') const CONFIG_PATH = env.CONFIG_PATH const eta = new Eta({ views: path.join(__dirname) }) const SCOPE = { ORG: 'org', REPO: 'repo' } // Determine if the setting is a org setting or repo setting + class Settings { static async syncAll (nop, context, repo, config, ref) { const settings = new Settings(nop, context, repo, config, ref) @@ -65,7 +66,6 @@ class Settings { this.installation_id = context.payload.installation.id this.github = context.octokit this.repo = repo - this.config = config this.nop = nop this.suborgChange = !!suborg // If suborg config has been updated, do not load the entire suborg config, and only process repos restricted to it. @@ -75,26 +75,15 @@ class Settings { this.log = context.log this.results = [] this.errors = [] - this.configvalidators = {} - this.overridevalidators = {} - const overridevalidators = config.overridevalidators - if (this.isIterable(overridevalidators)) { - for (const validator of overridevalidators) { - // eslint-disable-next-line no-new-func - const f = new Function('baseconfig', 'overrideconfig', 'githubContext', validator.script) - this.overridevalidators[validator.plugin] = { canOverride: f, error: validator.error } - } - } - const configvalidators = config.configvalidators - if (this.isIterable(configvalidators)) { - for (const validator of configvalidators) { - this.log.debug(`Logging each script: ${typeof validator.script}`) - // eslint-disable-next-line no-new-func - const f = new Function('baseconfig', 'githubContext', validator.script) - this.configvalidators[validator.plugin] = { isValid: f, error: validator.error } - } - } - this.mergeDeep = new MergeDeep(this.log, this.github, [], this.configvalidators, this.overridevalidators) + + this.mergeDeep = new MergeDeep(this.log, this.github, []) + + this.config = config.runtimeConfig + + // these can only be defined in the deployment config + this.overridevalidators = config.deploymentConfig.overridevalidators + this.configvalidators = config.deploymentConfig.configvalidators + this.restrictedRepos = config.deploymentConfig.restrictedRepos } // Create a check in the Admin repo for safe-settings. @@ -445,7 +434,7 @@ ${this.results.reduce((x, y) => { } isRestricted(repoName) { - const restrictedRepos = this.config.restrictedRepos + const restrictedRepos = this.restrictedRepos // Skip configuring any restricted repos if (Array.isArray(restrictedRepos)) { // For backward compatibility support the old format @@ -887,14 +876,6 @@ ${this.results.reduce((x, y) => { isObject (item) { return (item && typeof item === 'object' && !Array.isArray(item)) } - - isIterable(obj) { - // checks for null and undefined - if (obj == null) { - return false - } - return typeof obj[Symbol.iterator] === 'function' - } } function prettify (obj) { diff --git a/test/unit/lib/deploymentConfig.test.js b/test/unit/lib/deploymentConfig.test.js new file mode 100644 index 00000000..4da92e82 --- /dev/null +++ b/test/unit/lib/deploymentConfig.test.js @@ -0,0 +1,62 @@ +const DeploymentConfig = require('../../../lib/deploymentConfig') + +const defaultConfig = { + configvalidators: {}, + overridevalidators: {}, + restrictedRepos: ['admin', '.github', 'safe-settings'] +} + +const context = { log: { info: jest.fn() } } + +describe('no deploymentConfig', () => { + const deploymentConfig = new DeploymentConfig(context, 'nonexistent.yml') + + test('matches default config', () => { + expect(deploymentConfig).toMatchObject(defaultConfig) + }) + + test('outputs info message', () => { + expect(context.log.info).toHaveBeenCalledWith('No deployment settings found at nonexistent.yml') + }) +}) + +describe('sample deploymentConfig', () => { + const deploymentConfig = new DeploymentConfig(context, './docs/sample-settings/sample-deployment-settings.yml') + + test('matches snapshot', () => { + expect(deploymentConfig).toMatchInlineSnapshot(` +DeploymentConfig { + "configvalidators": { + "collaborators": { + "error": "\`Admin cannot be assigned to collaborators\` +", + "isValid": [Function], + }, + }, + "overridevalidators": { + "branches": { + "canOverride": [Function], + "error": "\`Branch protection required_approving_review_count cannot be overidden to a lower value\` +", + }, + "labels": { + "canOverride": [Function], + "error": "Some error +", + }, + }, + "restrictedRepos": { + "exclude": [ + "^admin$", + "^\\.github$", + "^safe-settings$", + ".*-test", + ], + "include": [ + "^test$", + ], + }, +} +`) + }) +}) diff --git a/test/unit/lib/settings.test.js b/test/unit/lib/settings.test.js index c91583d3..5a7b424f 100644 --- a/test/unit/lib/settings.test.js +++ b/test/unit/lib/settings.test.js @@ -8,6 +8,7 @@ const yaml = require('js-yaml') // return OriginalSettings // }) +let settings describe('Settings Tests', () => { let stubContext @@ -19,7 +20,7 @@ describe('Settings Tests', () => { function createSettings(config) { const settings = new Settings(false, stubContext, mockRepo, config, mockRef, mockSubOrg) - return settings; + return settings } beforeEach(() => { @@ -52,7 +53,7 @@ repository: # A comma-separated list of topics to set on the repository topics: - frontend - `).toString('base64'); + `).toString('base64') mockOctokit.repos = { getContent: jest.fn().mockResolvedValue({ data: { content } }) } @@ -83,18 +84,17 @@ repository: } } - - mockRepo = { owner: 'test', repo: 'test-repo' } mockRef = 'main' mockSubOrg = 'frontend' }) describe('restrictedRepos', () => { - describe('restrictedRepos not defined', () => { + describe('restrictedRepos is empty object', () => { beforeEach(() => { stubConfig = { - restrictedRepos: { + deploymentConfig: { + restrictedRepos: {} } } }) @@ -113,11 +113,74 @@ repository: }) }) + describe('restrictedRepos is not present', () => { + beforeEach(() => { + stubConfig = { + deploymentConfig: {} + } + }) + + it('throws TypeError', () => { + settings = createSettings(stubConfig) + expect(() => settings.isRestricted('my-repo')).toThrow('Cannot read properties of undefined (reading \'include\')') + }) + }) + + describe('restrictedRepos is null', () => { + beforeEach(() => { + stubConfig = { + deploymentConfig: { + restrictedRepos: null + } + } + }) + + it('throws TypeError', () => { + settings = createSettings(stubConfig) + expect(() => settings.isRestricted('my-repo')).toThrow('Cannot read properties of null (reading \'include\')') + }) + }) + + describe('restrictedRepos is empty array', () => { + beforeEach(() => { + stubConfig = { + deploymentConfig: { + restrictedRepos: [] + } + } + }) + + it('allows all repositories', () => { + settings = createSettings(stubConfig) + expect(settings.isRestricted('my-repo')).toEqual(false) + }) + }) + + describe('restrictedRepos also defined in runtimeConfig', () => { + beforeEach(() => { + stubConfig = { + deploymentConfig: { + restrictedRepos: ['admin', '.github', 'safe-settings'] + }, + runtimeConfig: { + restrictedRepos: ['foo', 'bar'] + } + } + }) + + it('ignores restrictedRepos from runtimeConfig', () => { + settings = createSettings(stubConfig) + expect(settings.restrictedRepos).toMatchObject(['admin', '.github', 'safe-settings']) + }) + }) + describe('restrictedRepos.exclude defined', () => { beforeEach(() => { stubConfig = { - restrictedRepos: { - exclude: ['foo', '.*-test$', '^personal-.*$'] + deploymentConfig: { + restrictedRepos: { + exclude: ['foo', '.*-test$', '^personal-.*$'] + } } } }) @@ -143,8 +206,10 @@ repository: describe('restrictedRepos.include defined', () => { beforeEach(() => { stubConfig = { - restrictedRepos: { - include: ['foo', '.*-test$', '^personal-.*$'] + deploymentConfig: { + restrictedRepos: { + include: ['foo', '.*-test$', '^personal-.*$'] + } } } }) @@ -166,37 +231,14 @@ repository: expect(settings.isRestricted('personalization-repo')).toEqual(true) }) }) - - describe('restrictedRepos not defined', () => { - it('Throws TypeError if restrictedRepos not defined', () => { - stubConfig = {} - settings = createSettings(stubConfig) - expect(() => settings.isRestricted('my-repo')).toThrow('Cannot read properties of undefined (reading \'include\')') - }) - - it('Throws TypeError if restrictedRepos is null', () => { - stubConfig = { - restrictedRepos: null - } - settings = createSettings(stubConfig) - expect(() => settings.isRestricted('my-repo')).toThrow('Cannot read properties of null (reading \'include\')') - }) - - it('Allowing all repositories if restrictedRepos is empty', () => { - stubConfig = { - restrictedRepos: [] - } - settings = createSettings(stubConfig) - expect(settings.isRestricted('my-repo')).toEqual(false) - }) - }) }) // restrictedRepos describe('loadConfigs', () => { describe('load suborg configs', () => { beforeEach(() => { stubConfig = { - restrictedRepos: { + deploymentConfig: { + restrictedRepos: {} } } subOrgConfig = yaml.load(` diff --git a/test/unit/lib/validator.test.js b/test/unit/lib/validator.test.js index 56a1b87a..abcd699c 100644 --- a/test/unit/lib/validator.test.js +++ b/test/unit/lib/validator.test.js @@ -4,6 +4,8 @@ const MergeDeep = require('../../../lib/mergeDeep') const YAML = require('js-yaml') const log = require('pino')('test.log') +jest.mock('../../../lib/deploymentConfig') + describe('Validator Tests', () => { it('Branch override validator test', () => { const overrideMock = jest.fn((baseconfig, overrideconfig) => { @@ -20,8 +22,10 @@ describe('Validator Tests', () => { console.log(`Branch config validator, baseconfig ${baseconfig}`) return false }) - DeploymentConfig.overridevalidators = { branches: { canOverride: overrideMock, error: 'Branch overrideValidators.error' } } - DeploymentConfig.configvalidators = { branches: { isValid: configMock, error: 'Branch configValidators.error' } } + DeploymentConfig.mockImplementation(() => ({ + overridevalidators: { branches: { canOverride: overrideMock, error: 'Branch overrideValidators.error' } }, + configvalidators: { branches: { isValid: configMock, error: 'Branch configValidators.error' } } + })) const overrideconfig = YAML.load(` branches: @@ -77,8 +81,10 @@ describe('Validator Tests', () => { console.log(`Repo config validator, baseconfig ${baseconfig}`) return false }) - DeploymentConfig.overridevalidators = { repository: { canOverride: overrideMock, error: 'Repo overrideValidators.error' } } - DeploymentConfig.configvalidators = { repository: { isValid: configMock, error: 'Repo configValidators.error' } } + DeploymentConfig.mockImplementation(() => ({ + overridevalidators: { repository: { canOverride: overrideMock, error: 'Repo overrideValidators.error' } }, + configvalidators: { branches: { isValid: configMock, error: 'Branch configValidators.error' } } + })) const overrideconfig = YAML.load(` repository: @@ -132,8 +138,10 @@ describe('Validator Tests', () => { console.log(`Repo config validator, baseconfig ${baseconfig}`) return false }) - DeploymentConfig.overridevalidators = { repository: { canOverride: overrideMock, error: 'Repo overrideValidators.error' } } - DeploymentConfig.configvalidators = { repository: { isValid: configMock, error: 'Repo configValidators.error' } } + DeploymentConfig.mockImplementation(() => ({ + overridevalidators: { repository: { canOverride: overrideMock, error: 'Repo overrideValidators.error' } }, + configvalidators: { repository: { isValid: configMock, error: 'Repo configValidators.error' } } + })) const overrideconfig = YAML.load(` repository: From d837f579b8b5c35a76dfcd9bad54c8d6c0f3e46a Mon Sep 17 00:00:00 2001 From: Jonathan Morley Date: Wed, 5 Mar 2025 12:05:09 -0500 Subject: [PATCH 2/3] test: add log.info to tests --- test/unit/lib/plugins/autolinks.test.js | 2 +- test/unit/lib/plugins/branches.test.js | 1 + test/unit/lib/plugins/collaborators.test.js | 2 +- test/unit/lib/plugins/custom_properties.test.js | 2 +- test/unit/lib/plugins/labels.test.js | 2 +- test/unit/lib/plugins/repository.test.js | 1 + test/unit/lib/plugins/rulesets.test.js | 1 + test/unit/lib/plugins/teams.test.js | 2 +- 8 files changed, 8 insertions(+), 5 deletions(-) diff --git a/test/unit/lib/plugins/autolinks.test.js b/test/unit/lib/plugins/autolinks.test.js index 10413cc1..721a2985 100644 --- a/test/unit/lib/plugins/autolinks.test.js +++ b/test/unit/lib/plugins/autolinks.test.js @@ -5,7 +5,7 @@ describe('Autolinks', () => { let github function configure (config) { - const log = { debug: jest.fn(), error: console.error } + const log = { ...console, debug: jest.fn() } const nop = false const errors = [] return new Autolinks(nop, github, repo, config, log, errors) diff --git a/test/unit/lib/plugins/branches.test.js b/test/unit/lib/plugins/branches.test.js index 62b50cb1..2800daad 100644 --- a/test/unit/lib/plugins/branches.test.js +++ b/test/unit/lib/plugins/branches.test.js @@ -6,6 +6,7 @@ const Branches = require('../../../../lib/plugins/branches') describe('Branches', () => { let github const log = jest.fn() + log.info = jest.fn() log.debug = jest.fn() log.error = jest.fn() diff --git a/test/unit/lib/plugins/collaborators.test.js b/test/unit/lib/plugins/collaborators.test.js index 359dd461..00584cba 100644 --- a/test/unit/lib/plugins/collaborators.test.js +++ b/test/unit/lib/plugins/collaborators.test.js @@ -4,7 +4,7 @@ describe('Collaborators', () => { let github function configure (config) { - const log = { debug: jest.fn(), error: console.error } + const log = { ...console, debug: jest.fn() } return new Collaborators(undefined, github, { owner: 'bkeepers', repo: 'test' }, config, log) } diff --git a/test/unit/lib/plugins/custom_properties.test.js b/test/unit/lib/plugins/custom_properties.test.js index f1148837..e3461bec 100644 --- a/test/unit/lib/plugins/custom_properties.test.js +++ b/test/unit/lib/plugins/custom_properties.test.js @@ -19,7 +19,7 @@ describe('CustomProperties', () => { // ] // }) } - log = { debug: jest.fn(), error: console.error } + log = { ...console, debug: jest.fn() } }) describe('sync', () => { diff --git a/test/unit/lib/plugins/labels.test.js b/test/unit/lib/plugins/labels.test.js index 71eaf2c8..79b50c25 100644 --- a/test/unit/lib/plugins/labels.test.js +++ b/test/unit/lib/plugins/labels.test.js @@ -26,7 +26,7 @@ describe('Labels', () => { updateLabel: jest.fn().mockImplementation(() => Promise.resolve()) } } - log = { debug: jest.fn(), error: console.error } + log = { ...console, debug: jest.fn() } }) describe('sync', () => { diff --git a/test/unit/lib/plugins/repository.test.js b/test/unit/lib/plugins/repository.test.js index b7af3912..aa8d56ac 100644 --- a/test/unit/lib/plugins/repository.test.js +++ b/test/unit/lib/plugins/repository.test.js @@ -13,6 +13,7 @@ describe('Repository', () => { } } const log = jest.fn() + log.info = jest.fn() log.debug = jest.fn() log.error = jest.fn() diff --git a/test/unit/lib/plugins/rulesets.test.js b/test/unit/lib/plugins/rulesets.test.js index f15abd63..c3670556 100644 --- a/test/unit/lib/plugins/rulesets.test.js +++ b/test/unit/lib/plugins/rulesets.test.js @@ -85,6 +85,7 @@ function generateResponseRuleset(id, name, conditions, checks, org=false) { describe('Rulesets', () => { let github const log = jest.fn() + log.info = jest.fn() log.debug = jest.fn() log.error = jest.fn() diff --git a/test/unit/lib/plugins/teams.test.js b/test/unit/lib/plugins/teams.test.js index 60ef23db..108aa28e 100644 --- a/test/unit/lib/plugins/teams.test.js +++ b/test/unit/lib/plugins/teams.test.js @@ -15,7 +15,7 @@ describe('Teams', () => { const org = 'bkeepers' function configure (config) { - const log = { debug: jest.fn(), error: console.error } + const log = { ...console, debug: jest.fn() } const errors = [] return new Teams(undefined, github, { owner: 'bkeepers', repo: 'test' }, config, log, errors) } From ab72c289e1c5581c25aaf1f594607c0f84c5dfb0 Mon Sep 17 00:00:00 2001 From: "mend-5034428[bot]" Date: Thu, 6 Mar 2025 14:47:17 +0000 Subject: [PATCH 3/3] chore(deps): update azure/k8s-create-secret digest to c8caea6 --- .github/workflows/deploy-k8s.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy-k8s.yml b/.github/workflows/deploy-k8s.yml index 4a92db41..8393391d 100644 --- a/.github/workflows/deploy-k8s.yml +++ b/.github/workflows/deploy-k8s.yml @@ -42,14 +42,14 @@ jobs: - run: | kubectl get deployment - name: app-env - uses: azure/k8s-create-secret@6e0ba8047235646753f2a3a3b359b4d0006ff218 + uses: azure/k8s-create-secret@c8caea6b91353c1089ad696c777fd87440e32edd with: namespace: 'default' secret-type: 'generic' arguments: --from-literal=APP_ID=${{ secrets.APP_ID }} --from-literal=PRIVATE_KEY=${{ secrets.PRIVATE_KEY }} --from-literal=WEBHOOK_SECRET=${{ secrets.WEBHOOK_SECRET }} secret-name: app-env - name: Set imagePullSecret - uses: azure/k8s-create-secret@6e0ba8047235646753f2a3a3b359b4d0006ff218 + uses: azure/k8s-create-secret@c8caea6b91353c1089ad696c777fd87440e32edd with: namespace: ${{env.AZURE_AKS_NAMESPACE}} container-registry-url: ${{env.IMAGE_REGISTRY_URL}}