Skip to content

Commit

Permalink
feat: repository custom properties plugin (#626)
Browse files Browse the repository at this point in the history
* feat: repository custom properties plugin

* docs: custom properties
  • Loading branch information
Simon-Boyer authored May 15, 2024
1 parent b6afb1a commit 678b02e
Show file tree
Hide file tree
Showing 6 changed files with 211 additions and 2 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,12 @@ branches:
users: []
teams: []

# Custom properties
# See https://docs.github.com/en/rest/repos/custom-properties?apiVersion=2022-11-28
custom_properties:
- name: test
value: test

# See the docs (https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/managing-repository-settings/configuring-autolinks-to-reference-external-resources) for a description of autolinks and replacement values.
autolinks:
- key_prefix: 'JIRA-'
Expand Down
1 change: 1 addition & 0 deletions app.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ default_events:
# the value (for example, write).
# Valid values are `read`, `write`, and `none`
default_permissions:
repository_custom_properties: write
organization_custom_properties: admin

# Repository creation, deletion, settings, teams, and collaborators.
Expand Down
8 changes: 7 additions & 1 deletion docs/sample-settings/repo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,13 @@ branches:
apps: []
users: []
teams: []


# Custom properties
# See https://docs.github.com/en/rest/repos/custom-properties?apiVersion=2022-11-28
custom_properties:
- name: test
value: test

validator:
pattern: '[a-zA-Z0-9_-]+_[a-zA-Z0-9_-]+.*'

Expand Down
67 changes: 67 additions & 0 deletions lib/plugins/custom_properties.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
const Diffable = require('./diffable')

module.exports = class CustomProperties extends Diffable {
constructor (...args) {
super(...args)

if (this.entries) {
// Force all names to lowercase to avoid comparison issues.
this.entries.forEach(prop => {
prop.name = prop.name.toLowerCase()
})
}
}

async find () {
const data = await this.github.request('GET /repos/:org/:repo/properties/values', {
org: this.repo.owner,
repo: this.repo.repo
})

const properties = data.data.map(d => { return { name: d.property_name, value: d.value } })
return properties
}

comparator (existing, attrs) {
return existing.name === attrs.name
}

changed (existing, attrs) {
return attrs.value !== existing.value
}

async update (existing, attrs) {
await this.github.request('PATCH /repos/:org/:repo/properties/values', {
org: this.repo.owner,
repo: this.repo.repo,
properties: [{
property_name: attrs.name,
value: attrs.value
}]
})
}

async add (attrs) {
await this.github.request('PATCH /repos/:org/:repo/properties/values', {
org: this.repo.owner,
repo: this.repo.repo,
properties: [{
property_name: attrs.name,
value: attrs.value
}]
})
}

async remove (existing) {
await this.github.request('PATCH /repos/:org/:repo/properties/values', {
org: this.repo.owner,
repo: this.repo.repo,
properties: [
{
property_name: existing.name,
value: null
}
]
})
}
}
3 changes: 2 additions & 1 deletion lib/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -836,7 +836,8 @@ Settings.PLUGINS = {
autolinks: require('./plugins/autolinks'),
validator: require('./plugins/validator'),
rulesets: require('./plugins/rulesets'),
environments: require('./plugins/environments')
environments: require('./plugins/environments'),
custom_properties: require('./plugins/custom_properties.js')
}

module.exports = Settings
128 changes: 128 additions & 0 deletions test/unit/lib/plugins/custom_properties.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
const CustomProperties = require('../../../../lib/plugins/custom_properties')

describe('CustomProperties', () => {
let github
const repo = { owner: 'owner', repo: 'repo' }
let log

function configure (config) {
const nop = false;
const errors = []
return new CustomProperties(nop, github, { owner: 'bkeepers', repo: 'test' }, config, log, errors)
}

beforeEach(() => {
github = {
request: jest.fn()
// .mockResolvedValue({
// data: [
// { property_name: 'test', value: 'test' }
// ]
// })
}
log = { debug: jest.fn(), error: console.error }
})

describe('sync', () => {
it('syncs custom properties', async () => {
const plugin = configure([
{ name: 'test', value: 'test' }
])

github.request.mockResolvedValue({
data: [
{ property_name: 'test', value: 'test' }
]
})

return plugin.sync().then(() => {
expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/properties/values', {
org: 'bkeepers',
repo: 'test'
})
})
})
})
describe('sync', () => {
it('add custom properties', async () => {
const plugin = configure([
{ name: 'test', value: 'test' }
])

github.request.mockResolvedValue({
data: []
})

return plugin.sync().then(() => {
expect(github.request).toHaveBeenNthCalledWith(1, 'GET /repos/:org/:repo/properties/values', {
org: 'bkeepers',
repo: 'test'
})
expect(github.request).toHaveBeenNthCalledWith(2, 'PATCH /repos/:org/:repo/properties/values', {
org: 'bkeepers',
repo: 'test',
properties: [
{
property_name: 'test',
value: 'test'
}
]
})
})
})
})
describe('sync', () => {
it('remove custom properties', async () => {
const plugin = configure([])

github.request.mockResolvedValue({
data: [{ property_name: 'test', value: 'test' }]
})

return plugin.sync().then(() => {
expect(github.request).toHaveBeenNthCalledWith(1, 'GET /repos/:org/:repo/properties/values', {
org: 'bkeepers',
repo: 'test'
})
expect(github.request).toHaveBeenNthCalledWith(2, 'PATCH /repos/:org/:repo/properties/values', {
org: 'bkeepers',
repo: 'test',
properties: [
{
property_name: 'test',
value: null
}
]
})
})
})
})
describe('sync', () => {
it('update custom properties', async () => {
const plugin = configure([
{ name: 'test', value: 'foobar' }
])

github.request.mockResolvedValue({
data: [{ property_name: 'test', value: 'test' }]
})

return plugin.sync().then(() => {
expect(github.request).toHaveBeenNthCalledWith(1, 'GET /repos/:org/:repo/properties/values', {
org: 'bkeepers',
repo: 'test'
})
expect(github.request).toHaveBeenNthCalledWith(2, 'PATCH /repos/:org/:repo/properties/values', {
org: 'bkeepers',
repo: 'test',
properties: [
{
property_name: 'test',
value: 'foobar'
}
]
})
})
})
})
})

0 comments on commit 678b02e

Please sign in to comment.