Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve change detection for environments, expand unit tests #646

Closed
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
82 changes: 79 additions & 3 deletions lib/plugins/environments.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const Diffable = require('./diffable')
const MergeDeep = require('../mergeDeep')

module.exports = class Environments extends Diffable {
constructor(...args) {
Expand Down Expand Up @@ -78,7 +79,7 @@ module.exports = class Environments extends Diffable {
const wait_timer = existing.wait_timer !== attrs.wait_timer;
const prevent_self_review = existing.prevent_self_review !== attrs.prevent_self_review;
const reviewers = JSON.stringify(existing.reviewers.sort((x1, x2) => x1.id - x2.id)) !== JSON.stringify(attrs.reviewers.sort((x1, x2) => x1.id - x2.id));

let existing_custom_branch_policies = existing.deployment_branch_policy === null ? null : existing.deployment_branch_policy.custom_branch_policies;
if(typeof(existing_custom_branch_policies) === 'object' && existing_custom_branch_policies !== null) {
existing_custom_branch_policies = existing_custom_branch_policies.sort();
Expand Down Expand Up @@ -243,7 +244,7 @@ module.exports = class Environments extends Diffable {
});
}
}


for(let variable of attrs.variables) {
await this.github.request(`POST /repos/:org/:repo/environments/:environment_name/variables`, {
Expand Down Expand Up @@ -272,4 +273,79 @@ module.exports = class Environments extends Diffable {
environment_name: existing.name
});
}
}

sync () {
const resArray = []
if (this.entries) {
let filteredEntries = this.filterEntries()
return this.find().then(existingRecords => {

// Filter out all empty entries (usually from repo override)
for (const entry of filteredEntries) {
for (const key of Object.keys(entry)) {
if (entry[key] === null || entry[key] === undefined) {
delete entry[key]
}
}
}
filteredEntries = filteredEntries.filter(entry => Object.keys(entry).filter(key => !MergeDeep.NAME_FIELDS.includes(key)).length !== 0)

const changes = []

existingRecords.forEach(x => {
if (!filteredEntries.find(y => this.comparator(x, y))) {
const change = this.remove(x).then(res => {
if (this.nop) {
return resArray.push(res)
}
return res
})
changes.push(change)
}
})

filteredEntries.forEach(attrs => {
const existing = existingRecords.find(record => {
return this.comparator(record, attrs)
})

if (!existing) {
const change = this.add(attrs).then(res => {
if (this.nop) {
return resArray.push(res)
}
return res
})
changes.push(change)
} else if (this.changed(existing, attrs)) {
const change = this.update(existing, attrs).then(res => {
if (this.nop) {
return resArray.push(res)
}
return res
})
changes.push(change)
}
})

if (this.nop) {
return Promise.resolve(resArray)
}
return Promise.all(changes)
}).catch(e => {
if (this.nop) {
if (e.status === 404) {
// Ignore 404s which can happen in dry-run as the repo may not exist.
return Promise.resolve(resArray)
} else {
resArray.push(new NopCommand(this.constructor.name, this.repo, null, `error ${e} in ${this.constructor.name} for repo: ${JSON.stringify(this.repo)} entries ${JSON.stringify(this.entries)}`, 'ERROR'))
Copy link
Contributor

Choose a reason for hiding this comment

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

'NopCommand' is not defined here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks @klutchell . I have added a pair of commits to address this: cf3fa72 and caa7d04
With these additions, the NopCommand is now defined. Additionally, there was an argument missing from the constructor for the environments plugin when instantiated from the unit tests. That has also been corrected.

I appreciate that you're taking a look at the PR. I have more to follow on from this one.

Copy link
Contributor

Choose a reason for hiding this comment

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

Any improvements to the environments plugin at this point is appreciated, as we are struggling to use this project to set environment level variables.

With PR #616 we were able to get it to create the initial set of environments and the respective variables, but now we can't get it to detect changes to those variables in the configuration.

Copy link
Contributor Author

@Brad-Abrams Brad-Abrams Jun 21, 2024

Choose a reason for hiding this comment

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

My experience suggests that this PR #646 is going to help with the detection and setting of environment level variables. That being said, there are remaining quirks in the environments plugin that I'd still like to address. For one, I can say that I appreciate the defensive code that you've added in PR# 616 to only post updates for variables and deployment protection rules if they are defined. My plan has been to see if I can succeed in getting this succinctly scoped PR reviewed and merged before layering in additional improvements. Am I on the right track? Which one of us is going to take a swing at combining 616 and 646? How would you feel about me taking it on? ... or would the resulting PR be too bloated?

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not the project maintainer, but that sounds like the correct approach to me.

WDYT @decyjphr ?

return Promise.resolve(resArray)
}
} else {
this.logError(`Error ${e} in ${this.constructor.name} for repo: ${JSON.stringify(this.repo)} entries ${JSON.stringify(this.entries)}`)
}
})
}
}

}
Loading