Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
42 changes: 35 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ The match object allows control over the matching options. You can specify the l

The base match object is defined as:
```yml
- changed-files:
- changed-files:
- any-glob-to-any-file: ['list', 'of', 'globs']
- any-glob-to-all-files: ['list', 'of', 'globs']
- all-globs-to-any-file: ['list', 'of', 'globs']
Expand Down Expand Up @@ -87,7 +87,35 @@ Documentation:
- any-glob-to-any-file: 'docs/*'
```

If path globs are combined with `!` negation, you can write complex matching rules. See the examples below for more information.
If path globs are combined with `!` negation, you can write complex matching rules. See the examples below for more information.

Furthermore, if a top-level key is omitted, or is `any` then a `changed-files` key without any further options will default to `any-glob-to-any-file`, though if an `all` key is provided it will default to `all-globs-to-all-files`.

For example the following would be the same:
```yml
Documentation:
- changed-files: 'docs/*'
```
and
```yml
Documentation:
- any
- changed-files:
- any-glob-to-any-file: 'docs/*'
```
along with
```yml
Documentation:
- all:
- changed-files: 'docs/*'
```
and
```yml
Documentation:
- all:
- changed-files:
- all-globs-to-all-files: 'docs/*'
```

#### Basic Examples

Expand Down Expand Up @@ -125,7 +153,7 @@ Documentation:
- changed-files:
- any-glob-to-any-file: ['docs/*', 'guides/*']

# Add 'Documentation' label to any change to .md files within the entire repository
# Add 'Documentation' label to any change to .md files within the entire repository
Documentation:
- changed-files:
- any-glob-to-any-file: '**/*.md'
Expand Down Expand Up @@ -206,7 +234,7 @@ jobs:
pull-requests: write
runs-on: ubuntu-latest
steps:

# Label PRs 1, 2, and 3
- uses: actions/labeler@v6
with:
Expand All @@ -218,9 +246,9 @@ jobs:

**Note:** in normal usage the `pr-number` input is not required as the action will detect the PR number from the workflow context.

#### Outputs
#### Outputs

Labeler provides the following outputs:
Labeler provides the following outputs:

| Name | Description |
|--------------|-----------------------------------------------------------|
Expand Down Expand Up @@ -248,7 +276,7 @@ jobs:
run: |
echo "Running frontend tests..."
# Put your commands for running frontend tests here

- id: run-backend-tests
if: contains(steps.label-the-PR.outputs.all-labels, 'backend')
run: |
Expand Down
20 changes: 14 additions & 6 deletions __tests__/changedFiles.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,20 @@ describe('toChangedFilesMatchConfig', () => {
describe('but the glob pattern config key is not provided', () => {
const config = {'changed-files': ['bar']};

it('throws the error', () => {
expect(() => {
toChangedFilesMatchConfig(config);
}).toThrow(
`The "changed-files" section must have a valid config structure. Please read the action documentation for more information`
);
it('defaults to anyGlobToAnyFile', () => {
const result = toChangedFilesMatchConfig(config);
expect(result).toEqual<ChangedFilesMatchConfig>({
changedFiles: [{anyGlobToAnyFile: ['bar']}]
});
});

describe('and the defaultToAll option is passed', () => {
it('defaults to allGlobToAllFiles', () => {
const result = toChangedFilesMatchConfig(config, true);
expect(result).toEqual<ChangedFilesMatchConfig>({
changedFiles: [{allGlobsToAllFiles: ['bar']}]
});
});
});
});

Expand Down
6 changes: 6 additions & 0 deletions __tests__/fixtures/default_any_and_all.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
default_any:
- changed-files: ['glob']

default_all:
- all:
- changed-files: ['glob']
80 changes: 49 additions & 31 deletions __tests__/labeler.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,37 +24,55 @@ const loadYaml = (filepath: string) => {
};

describe('getLabelConfigMapFromObject', () => {
const yamlObject = loadYaml('__tests__/fixtures/all_options.yml');
const expected = new Map<string, MatchConfig[]>();
expected.set('label1', [
{
any: [
{changedFiles: [{anyGlobToAnyFile: ['glob']}]},
{baseBranch: undefined, headBranch: ['regexp']},
{baseBranch: ['regexp'], headBranch: undefined}
]
},
{
all: [
{changedFiles: [{allGlobsToAllFiles: ['glob']}]},
{baseBranch: undefined, headBranch: ['regexp']},
{baseBranch: ['regexp'], headBranch: undefined}
]
}
]);
expected.set('label2', [
{
any: [
{changedFiles: [{anyGlobToAnyFile: ['glob']}]},
{baseBranch: undefined, headBranch: ['regexp']},
{baseBranch: ['regexp'], headBranch: undefined}
]
}
]);

it('returns a MatchConfig', () => {
const result = getLabelConfigMapFromObject(yamlObject);
expect(result).toEqual(expected);
describe('when all options are present', () => {
const yamlObject = loadYaml('__tests__/fixtures/all_options.yml');
const expected = new Map<string, MatchConfig[]>();
expected.set('label1', [
{
any: [
{changedFiles: [{anyGlobToAnyFile: ['glob']}]},
{baseBranch: undefined, headBranch: ['regexp']},
{baseBranch: ['regexp'], headBranch: undefined}
]
},
{
all: [
{changedFiles: [{allGlobsToAllFiles: ['glob']}]},
{baseBranch: undefined, headBranch: ['regexp']},
{baseBranch: ['regexp'], headBranch: undefined}
]
}
]);
expected.set('label2', [
{
any: [
{changedFiles: [{anyGlobToAnyFile: ['glob']}]},
{baseBranch: undefined, headBranch: ['regexp']},
{baseBranch: ['regexp'], headBranch: undefined}
]
}
]);

it('returns a MatchConfig', () => {
const result = getLabelConfigMapFromObject(yamlObject);
expect(result).toEqual(expected);
});
});

describe('when no any or all key are present', () => {
const yamlObject = loadYaml('__tests__/fixtures/default_any_and_all.yml');
const expected = new Map<string, MatchConfig[]>();
expected.set('default_any', [
{any: [{changedFiles: [{anyGlobToAnyFile: ['glob']}]}]}
]);
expected.set('default_all', [
{all: [{changedFiles: [{allGlobsToAllFiles: ['glob']}]}]}
]);

it('returns a MatchConfig', () => {
const result = getLabelConfigMapFromObject(yamlObject);
expect(result).toEqual(expected);
});
});
});

Expand Down
5 changes: 4 additions & 1 deletion __tests__/main.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@ const yamlFixtures = {
'branches.yml': fs.readFileSync('__tests__/fixtures/branches.yml'),
'only_pdfs.yml': fs.readFileSync('__tests__/fixtures/only_pdfs.yml'),
'not_supported.yml': fs.readFileSync('__tests__/fixtures/not_supported.yml'),
'any_and_all.yml': fs.readFileSync('__tests__/fixtures/any_and_all.yml')
'any_and_all.yml': fs.readFileSync('__tests__/fixtures/any_and_all.yml'),
'default_any_and_all.yml': fs.readFileSync(
'__tests__/fixtures/default_any_and_all.yml'
)
};

const configureInput = (
Expand Down
18 changes: 14 additions & 4 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ function getLabelConfigMapFromObject(configObject) {
// our config objects.
if (key === 'any' || key === 'all') {
if (Array.isArray(value)) {
const newConfigs = value.map(toMatchConfig);
const newConfigs = value.map(config => toMatchConfig(config, key === 'all'));
updatedConfig.push({ [key]: newConfigs });
}
}
Expand Down Expand Up @@ -349,8 +349,8 @@ function getLabelConfigMapFromObject(configObject) {
}
return labelMap;
}
function toMatchConfig(config) {
const changedFilesConfig = (0, changedFiles_1.toChangedFilesMatchConfig)(config);
function toMatchConfig(config, defaultToAll = false) {
const changedFilesConfig = (0, changedFiles_1.toChangedFilesMatchConfig)(config, defaultToAll);
const branchConfig = (0, branch_1.toBranchMatchConfig)(config);
return Object.assign(Object.assign({}, changedFilesConfig), branchConfig);
}
Expand Down Expand Up @@ -663,7 +663,7 @@ function getChangedFiles(client, prNumber) {
return changedFiles;
});
}
function toChangedFilesMatchConfig(config) {
function toChangedFilesMatchConfig(config, defaultToAll = false) {
if (!config['changed-files'] || !config['changed-files'].length) {
return {};
}
Expand All @@ -672,6 +672,16 @@ function toChangedFilesMatchConfig(config) {
: [config['changed-files']];
const validChangedFilesConfigs = [];
changedFilesConfigs.forEach(changedFilesConfig => {
if (typeof changedFilesConfig === 'string' ||
(Array.isArray(changedFilesConfig) &&
changedFilesConfig.every(config => typeof config === 'string'))) {
const key = defaultToAll ? 'allGlobsToAllFiles' : 'anyGlobToAnyFile';
const value = typeof changedFilesConfig === 'string'
? [changedFilesConfig]
: changedFilesConfig;
validChangedFilesConfigs.push({ [key]: value });
return;
}
if (!(0, utils_1.isObject)(changedFilesConfig)) {
throw new Error(`The "changed-files" section must have a valid config structure. Please read the action documentation for more information`);
}
Expand Down
11 changes: 8 additions & 3 deletions src/api/get-label-configs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,9 @@ export function getLabelConfigMapFromObject(
// our config objects.
if (key === 'any' || key === 'all') {
if (Array.isArray(value)) {
const newConfigs = value.map(toMatchConfig);
const newConfigs = value.map(config =>
toMatchConfig(config, key === 'all')
);
updatedConfig.push({[key]: newConfigs});
}
} else if (ALLOWED_CONFIG_KEYS.includes(key)) {
Expand Down Expand Up @@ -115,8 +117,11 @@ export function getLabelConfigMapFromObject(
return labelMap;
}

export function toMatchConfig(config: any): BaseMatchConfig {
const changedFilesConfig = toChangedFilesMatchConfig(config);
export function toMatchConfig(
config: any,
defaultToAll = false
): BaseMatchConfig {
const changedFilesConfig = toChangedFilesMatchConfig(config, defaultToAll);
const branchConfig = toBranchMatchConfig(config);

return {
Expand Down
17 changes: 16 additions & 1 deletion src/changedFiles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ export async function getChangedFiles(
}

export function toChangedFilesMatchConfig(
config: any
config: any,
defaultToAll = false
): ChangedFilesMatchConfig {
if (!config['changed-files'] || !config['changed-files'].length) {
return {};
Expand All @@ -57,6 +58,20 @@ export function toChangedFilesMatchConfig(
const validChangedFilesConfigs: ChangedFilesGlobPatternsConfig[] = [];

changedFilesConfigs.forEach(changedFilesConfig => {
if (
typeof changedFilesConfig === 'string' ||
(Array.isArray(changedFilesConfig) &&
changedFilesConfig.every(config => typeof config === 'string'))
) {
const key = defaultToAll ? 'allGlobsToAllFiles' : 'anyGlobToAnyFile';
const value =
typeof changedFilesConfig === 'string'
? [changedFilesConfig]
: changedFilesConfig;
validChangedFilesConfigs.push({[key]: value});
return;
}

if (!isObject(changedFilesConfig)) {
throw new Error(
`The "changed-files" section must have a valid config structure. Please read the action documentation for more information`
Expand Down