Skip to content

Commit

Permalink
Merge pull request #20 from amacado/feature/12-enhance-configuration
Browse files Browse the repository at this point in the history
enhance configuration (#12, #15)
  • Loading branch information
TimonVS committed Oct 27, 2019
2 parents c38da8d + ff9b1f1 commit 8803b71
Show file tree
Hide file tree
Showing 9 changed files with 110 additions and 28 deletions.
6 changes: 4 additions & 2 deletions .vscode/settings.json
@@ -1,3 +1,5 @@
{
"editor.formatOnSave": true
}
"editor.formatOnSave": true,
"createTests.defaultLocationForTestFiles": "project root",
"createTests.testDirectoryName": "__tests__"
}
12 changes: 12 additions & 0 deletions README.md
Expand Up @@ -20,6 +20,8 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: TimonVS/pr-labeler-action@v3
with:
configuration-path: .github/pr-labeler.yml # optional, .github/pr-labeler.yml is the default value
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
```
Expand All @@ -43,6 +45,16 @@ Then if a pull request is opened with the branch name `feature/218-add-emoji-sup

You can use `*` as a wildcard for matching multiple branch names. See https://www.npmjs.com/package/matcher for more information about wildcard options.

### Default configuration

When no configuration is provided, the following defaults will be used:

```yml
feature: ['feature/*', 'feat/*'],
fix: 'fix/*',
chore: 'chore/*'
```

## Contributors ✨

Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
Expand Down
26 changes: 25 additions & 1 deletion __tests__/action.test.ts
Expand Up @@ -6,6 +6,12 @@ import action from '../src/action'
nock.disableNetConnect()

describe('pr-labeler-action', () => {
beforeEach(() => {
// configuration-path parameter is required
// parameters are exposed as environment variables: https://help.github.com/en/github/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions#jobsjob_idstepswith
process.env['INPUT_CONFIGURATION-PATH'] = '.github/pr-labeler.yml'
})

it('adds the "fix" label for "fix/510-logging" branch', async () => {
nock('https://api.github.com')
.get('/repos/Codertocat/Hello-World/contents/.github/pr-labeler.yml?ref=fix%2F510-logging')
Expand All @@ -30,7 +36,7 @@ describe('pr-labeler-action', () => {
.reply(200, configFixture())
.post('/repos/Codertocat/Hello-World/issues/1/labels', body => {
expect(body).toMatchObject({
labels: ['feature']
labels: ['🎉 feature']
})
return true
})
Expand All @@ -42,6 +48,24 @@ describe('pr-labeler-action', () => {
expect.assertions(1)
})

it('adds the "release" label for "release/2.0" branch', async () => {
nock('https://api.github.com')
.get('/repos/Codertocat/Hello-World/contents/.github/pr-labeler.yml?ref=release%2F2.0')
.reply(200, configFixture())
.post('/repos/Codertocat/Hello-World/issues/1/labels', body => {
expect(body).toMatchObject({
labels: ['release']
})
return true
})
.reply(200)

await action({
payload: pullRequestOpenedFixture({ ref: 'release/2.0' })
})
expect.assertions(1)
})

it('uses the default config when no config was provided', async () => {
nock('https://api.github.com')
.get('/repos/Codertocat/Hello-World/contents/.github/pr-labeler.yml?ref=fix%2F510-logging')
Expand Down
3 changes: 2 additions & 1 deletion __tests__/fixtures/config.yml
@@ -1,3 +1,4 @@
feature: ['feature/*', 'feat/*']
'🎉 feature': ['feature/*', 'feat/*']
fix: fix/*
chore: chore/*
release: release/*
31 changes: 31 additions & 0 deletions __tests__/utils/config.test.ts
@@ -0,0 +1,31 @@
import getConfig from '../../src/utils/config'

describe('getConfig', () => {
it('returns default config when GitHub returns a 404 for given path', async () => {
const defaultConfig = {
foo: 'bar'
}

const githubMock = {
repos: {
getContents() {
throw new HTTPError(404)
}
}
}

const config = await getConfig(
githubMock as any,
'path/to/config',
{ owner: 'repo-owner', repo: 'repo-name' },
'ref',
defaultConfig
)

expect(config).toBe(defaultConfig)
})
})

class HTTPError {
constructor(public status: number) {}
}
4 changes: 4 additions & 0 deletions action.yml
@@ -1,6 +1,10 @@
name: 'PR Labeler'
description: 'Automatically labels your PRs based on branch name patterns like feature/* or fix/*.'
author: 'Timon van Spronsen'
inputs:
configuration-path:
description: 'The path for the label configurations'
default: '.github/pr-labeler.yml'
branding:
icon: 'tag'
color: 'white'
Expand Down
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 16 additions & 16 deletions src/action.ts
Expand Up @@ -5,8 +5,7 @@ import matcher from 'matcher'
import getConfig from './utils/config'
import { RepoInfo } from './utils/config'

const CONFIG_FILENAME = 'pr-labeler.yml'
const defaults = {
const defaultConfig = {
feature: ['feature/*', 'feat/*'],
fix: 'fix/*',
chore: 'chore/*'
Expand All @@ -20,6 +19,7 @@ async function action(context: Pick<Context, 'payload'> = github.context) {
owner: context.payload.repository!.owner.login,
repo: context.payload.repository!.name
}
const configPath = core.getInput('configuration-path', { required: true })

if (!context.payload.pull_request) {
throw new Error(
Expand All @@ -28,22 +28,22 @@ async function action(context: Pick<Context, 'payload'> = github.context) {
}

const ref: string = context.payload.pull_request.head.ref
const config = {
...defaults,
...(await getConfig(octokit, CONFIG_FILENAME, repoInfo, ref))
}
const config = await getConfig(octokit, configPath, repoInfo, ref, defaultConfig)

const labelsToAdd = Object.entries(config).reduce((labels: string[], [label, patterns]) => {
if (
Array.isArray(patterns)
? patterns.some(pattern => matcher.isMatch(ref, pattern))
: matcher.isMatch(ref, patterns)
) {
labels.push(label)
}
const labelsToAdd = Object.entries(config).reduce(
(labels, [label, patterns]) => {
if (
Array.isArray(patterns)
? patterns.some(pattern => matcher.isMatch(ref, pattern))
: matcher.isMatch(ref, patterns)
) {
labels.push(label)
}

return labels
}, [])
return labels
},
[] as string[]
)

if (labelsToAdd.length > 0) {
await octokit.issues.addLabels({
Expand Down
18 changes: 13 additions & 5 deletions src/utils/config.ts
@@ -1,26 +1,34 @@
import path from 'path'
import yaml from 'js-yaml'
import { GitHub } from '@actions/github'
const CONFIG_PATH = '.github'

export interface RepoInfo {
owner: string
repo: string
}

export default async function getConfig(github: GitHub, fileName: string, { owner, repo }: RepoInfo, ref: string) {
interface Config {
[k: string]: string | string[]
}

export default async function getConfig(
github: GitHub,
path: string,
{ owner, repo }: RepoInfo,
ref: string,
defaultConfig: Config
): Promise<Config> {
try {
const response = await github.repos.getContents({
owner,
repo,
path: path.posix.join(CONFIG_PATH, fileName),
path,
ref
})

return parseConfig(response.data.content)
} catch (error) {
if (error.status === 404) {
return null
return defaultConfig
}

throw error
Expand Down

0 comments on commit 8803b71

Please sign in to comment.