Skip to content

Commit

Permalink
Merge pull request #855 from repository-settings/beta
Browse files Browse the repository at this point in the history
  • Loading branch information
travi committed Feb 26, 2024
2 parents fbaf96d + 561cfeb commit 8e5e727
Show file tree
Hide file tree
Showing 42 changed files with 4,527 additions and 3,008 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/node-ci.yml
Expand Up @@ -3,6 +3,7 @@ name: Node.js CI
push:
branches:
- master
- beta
- renovate/**
pull_request:
types:
Expand All @@ -14,9 +15,8 @@ jobs:
strategy:
matrix:
node:
- 16.0.0
- 18
- 20
- 18.17.0
- 20.6.1
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- name: Setup node
Expand Down
21 changes: 21 additions & 0 deletions cucumber.mjs
@@ -0,0 +1,21 @@
const base = {
formatOptions: { snippetInterface: 'async-await' },
import: ['test/integration/features/**/*.mjs']
}

export default base

export const wip = {
...base,
tags: '@wip and not @skip'
}

export const noWip = {
...base,
tags: 'not @skip and not @wip'
}

export const focus = {
...base,
tags: '@focus'
}
6 changes: 5 additions & 1 deletion docs/configuration.md
Expand Up @@ -103,7 +103,11 @@ collaborators:
# * `triage` - Recommended for contributors who need to proactively manage issues and pull requests without write access.

# See https://docs.github.com/en/rest/deployments/environments#create-or-update-an-environment for available options
# Note: deployment_branch_policy differs from the API for ease of use. Either protected_branches (boolean) OR custom_branches (array of strings) can be provided; this will manage the API requirements under the hood. See https://docs.github.com/en/rest/deployments/branch-policies for documentation of custom_branches. If both are provided in an unexpected manner, protected_branches will be used.
# Note: deployment_branch_policy differs from the API for ease of use.
# Either protected_branches (boolean) OR custom_branches (array of strings) can be provided;
# this will manage the API requirements under the hood.
# See https://docs.github.com/en/rest/deployments/branch-policies for documentation of custom_branches.
# If both are provided in an unexpected manner, protected_branches will be used.
# Either removing or simply not setting deployment_branch_policy will restore the default 'All branches' setting.
environments:
- name: production
Expand Down
117 changes: 69 additions & 48 deletions lib/plugins/environments.js
Expand Up @@ -2,6 +2,62 @@ const Diffable = require('./diffable')

const environmentRepoEndpoint = '/repos/:org/:repo/environments/:environment_name'

function shouldUseProtectedBranches (protectedBranches, customBranchPolicies) {
return !!(protectedBranches || customBranchPolicies === undefined || customBranchPolicies === null)
}

function attributeSorter (a, b) {
if (a.id < b.id) return -1
if (a.id > b.id) return 1
if (a.type < b.type) return -1
if (a.type > b.type) return 1
return 0
}

function reviewersToString (reviewers) {
if (reviewers === null || reviewers === undefined) {
return ''
} else {
reviewers.sort(attributeSorter)

return JSON.stringify(
reviewers.map(reviewer => {
return {
id: reviewer.id,
type: reviewer.type
}
})
)
}
}

function deploymentBranchPolicyToString (attrs) {
if (attrs === null || attrs === undefined) {
return ''
} else {
return JSON.stringify(
shouldUseProtectedBranches(attrs.protected_branches, attrs.custom_branches)
? { protected_branches: true }
: { custom_branches: attrs.custom_branches.sort() }
)
}
}

function waitTimerHasChanged (existing, attrs) {
return (existing.wait_timer || 0) !== attrs.wait_timer
}

function reviewersHasChanged (existing, attrs) {
return reviewersToString(existing.reviewers) !== reviewersToString(attrs.reviewers)
}

function deploymentBranchPolicyHasChanged (existing, attrs) {
return (
deploymentBranchPolicyToString(existing.deployment_branch_policy) !==
deploymentBranchPolicyToString(attrs.deployment_branch_policy)
)
}

module.exports = class Environments extends Diffable {
constructor (...args) {
super(...args)
Expand All @@ -21,6 +77,7 @@ module.exports = class Environments extends Diffable {
org: this.repo.owner,
repo: this.repo.repo
})

return Promise.all(
environments.map(async environment => {
if (environment.deployment_branch_policy) {
Expand All @@ -39,6 +96,7 @@ module.exports = class Environments extends Diffable {
}
}
}

return {
...environment,
// Force all names to lowercase to avoid comparison issues.
Expand All @@ -54,17 +112,18 @@ module.exports = class Environments extends Diffable {

changed (existing, attrs) {
if (!attrs.wait_timer) attrs.wait_timer = 0

return (
(existing.wait_timer || 0) !== attrs.wait_timer ||
this.reviewersToString(existing.reviewers) !== this.reviewersToString(attrs.reviewers) ||
this.deploymentBranchPolicyToString(existing.deployment_branch_policy) !==
this.deploymentBranchPolicyToString(attrs.deployment_branch_policy)
waitTimerHasChanged(existing, attrs) ||
reviewersHasChanged(existing, attrs) ||
deploymentBranchPolicyHasChanged(existing, attrs)
)
}

async update (existing, attrs) {
if (existing.deployment_branch_policy && existing.deployment_branch_policy.custom_branches) {
const branchPolicies = await this.getDeploymentBranchPolicies(this.repo.owner, this.repo.repo, existing.name)

await Promise.all(
branchPolicies.map(branchPolicy =>
this.github.request(
Expand All @@ -79,15 +138,17 @@ module.exports = class Environments extends Diffable {
)
)
}

return this.add(attrs)
}

async add (attrs) {
await this.github.request(`PUT ${environmentRepoEndpoint}`, this.toParams({ name: attrs.name }, attrs))

if (attrs.deployment_branch_policy && attrs.deployment_branch_policy.custom_branches) {
await Promise.all(
attrs.deployment_branch_policy.custom_branches.map(name =>
this.github.request(`POST /repos/:org/:repo/environments/:environment_name/deployment-branch-policies`, {
this.github.request('POST /repos/:org/:repo/environments/:environment_name/deployment-branch-policies', {
org: this.repo.owner,
repo: this.repo.repo,
environment_name: attrs.name,
Expand All @@ -106,40 +167,6 @@ module.exports = class Environments extends Diffable {
})
}

reviewersToString (attrs) {
if (attrs === null || attrs === undefined) {
return ''
} else {
attrs.sort((a, b) => {
if (a.id < b.id) return -1
if (a.id > b.id) return 1
if (a.type < b.type) return -1
if (a.type > b.type) return 1
return 0
})
return JSON.stringify(
attrs.map(reviewer => {
return {
id: reviewer.id,
type: reviewer.type
}
})
)
}
}

deploymentBranchPolicyToString (attrs) {
if (attrs === null || attrs === undefined) {
return ''
} else {
return JSON.stringify(
this.shouldUseProtectedBranches(attrs.protected_branches, attrs.custom_branches)
? { protected_branches: true }
: { custom_branches: attrs.custom_branches.sort() }
)
}
}

async getDeploymentBranchPolicies (owner, repo, environmentName) {
const {
data: { branch_policies: branchPolicies }
Expand All @@ -148,18 +175,20 @@ module.exports = class Environments extends Diffable {
repo,
environment_name: environmentName
})

return branchPolicies
}

toParams (existing, attrs) {
const deploymentBranchPolicy = attrs.deployment_branch_policy
? this.shouldUseProtectedBranches(
? shouldUseProtectedBranches(
attrs.deployment_branch_policy.protected_branches,
attrs.deployment_branch_policy.custom_branches
)
? { protected_branches: true, custom_branch_policies: false }
: { protected_branches: false, custom_branch_policies: true }
: null

return {
environment_name: existing.name,
repo: this.repo.repo,
Expand All @@ -169,12 +198,4 @@ module.exports = class Environments extends Diffable {
deployment_branch_policy: deploymentBranchPolicy
}
}

shouldUseProtectedBranches (protectedBranches, customBranchPolicies) {
if (protectedBranches || customBranchPolicies === undefined || customBranchPolicies === null) {
return true // Returning booleans like this to avoid unexpected datatypes that result in truthy values
} else {
return false
}
}
}

0 comments on commit 8e5e727

Please sign in to comment.