diff --git a/README.md b/README.md index 126cbdfc2..0af5d997a 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,15 @@ Automatically label new pull requests based on the paths of files being changed or the branch name. +## Breaking changes in V5 +1) The ability to apply labels based on the names of base and/or head branches was added ([#186](https://github.com/actions/labeler/issues/186) and [#54](https://github.com/actions/labeler/issues/54)). The match object for changed files was expanded with new combinations in order to make it more intuitive and flexible ([#423](https://github.com/actions/labeler/issues/423) and [#101](https://github.com/actions/labeler/issues/101)). As a result, the configuration file structure was significantly redesigned and is not compatible with the structure of the previous version. Please read the documentation below to find out how to adapt your configuration files for use with the new action version. + +2) The bug related to the `sync-labels` input was fixed ([#112](https://github.com/actions/labeler/issues/112)). Now the input value is read correctly. + +3) By default, `dot` input is set to `true`. Now, paths starting with a dot (e.g. `.github`) are matched by default. + +4) Version 5 of this action updated the [runtime to Node.js 20](https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions#runs-for-javascript-actions). All scripts are now run with Node.js 20 instead of Node.js 16 and are affected by any breaking changes between Node.js 16 and 20. + ## Usage ### Create `.github/labeler.yml` @@ -14,108 +23,106 @@ The key is the name of the label in your repository that you want to add (eg: "m #### Match Object -The match object allows control over the matching options, you can specify the label to be applied based on the files that have changed or the name of either the base branch or the head branch. For the changed files options you provide a [path glob](https://github.com/isaacs/minimatch#minimatch), and for the branches you provide a regexp to match against the branch name. +The match object allows control over the matching options. You can specify the label to be applied based on the files that have changed or the name of either the base branch or the head branch. For the changed files options you provide a [path glob](https://github.com/isaacs/minimatch#minimatch), and for the branches you provide a regexp to match against the branch name. The base match object is defined as: ```yml -- changed-files: ['list', 'of', 'globs'] +- 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'] + - all-globs-to-all-files: ['list', 'of', 'globs'] - base-branch: ['list', 'of', 'regexps'] - head-branch: ['list', 'of', 'regexps'] ``` -There are two top level keys of `any` and `all`, which both accept the same config options: +There are two top-level keys, `any` and `all`, which both accept the same configuration options: ```yml - any: - - changed-files: ['list', 'of', 'globs'] + - 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'] + - all-globs-to-all-files: ['list', 'of', 'globs'] - base-branch: ['list', 'of', 'regexps'] - head-branch: ['list', 'of', 'regexps'] - all: - - changed-files: ['list', 'of', 'globs'] + - 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'] + - all-globs-to-all-files: ['list', 'of', 'globs'] - base-branch: ['list', 'of', 'regexps'] - head-branch: ['list', 'of', 'regexps'] ``` +From a boolean logic perspective, top-level match objects, and options within `all` are `AND`-ed together and individual match rules within the `any` object are `OR`-ed. + One or all fields can be provided for fine-grained matching. The fields are defined as follows: -* `all`: all of the provided options must match in order for the label to be applied -* `any`: if any of the provided options match then a label will be applied -* `base-branch`: match regexps against the base branch name -* `changed-files`: match glob patterns against the changed paths -* `head-branch`: match regexps against the head branch name - -If a base option is provided without a top-level key then it will default to `any`. More specifically, the following two configurations are equivalent: +- `all`: ALL of the provided options must match for the label to be applied +- `any`: if ANY of the provided options match then the label will be applied + - `base-branch`: match regexps against the base branch name + - `head-branch`: match regexps against the head branch name + - `changed-files`: match glob patterns against the changed paths + - `any-glob-to-any-file`: ANY glob must match against ANY changed file + - `any-glob-to-all-files`: ANY glob must match against ALL changed files + - `all-globs-to-any-file`: ALL globs must match against ANY changed file + - `all-globs-to-all-files`: ALL globs must match against ALL changed files + +If a base option is provided without a top-level key, then it will default to `any`. More specifically, the following two configurations are equivalent: ```yml -label1: -- changed-files: example1/* +Documentation: +- changed-files: + - any-glob-to-any-file: 'docs/*' ``` and ```yml -label1: +Documentation: - any: - - changed-files: ['example1/*'] + - changed-files: + - any-glob-to-any-file: 'docs/*' ``` -From a boolean logic perspective, top-level match objects, and options within `all` are `AND`-ed together and individual match rules within the `any` object are `OR`-ed. If path globs are combined with `!` negation, you can write complex matching rules. - -> ⚠️ This action uses [minimatch](https://www.npmjs.com/package/minimatch) to apply glob patterns. -> For historical reasons, paths starting with dot (e.g. `.github`) are not matched by default. -> You need to set `dot: true` to change this behavior. -> See [Inputs](#inputs) table below for details. + If path globs are combined with `!` negation, you can write complex matching rules. See the examples below for more information. #### Basic Examples ```yml -# Add 'label1' to any changes within 'example' folder or any subfolders -label1: -- changed-files: example/**/* - -# Add 'label2' to any file changes within 'example2' folder -label2: -- changed-files: example2/* - -# Add label3 to any change to .txt files within the entire repository. Quotation marks are required for the leading asterisk -label3: -- changed-files: '**/*.txt' - -# Add 'label4' to any PR where the head branch name starts with 'example4' -label4: -- head-branch: '^example4' - -# Add 'label5' to any PR where the base branch name starts with 'example5' -label5: -- base-branch: '^example5' -``` +# Add 'root' label to any root file changes +# Quotation marks are required for the leading asterisk +root: +- changed-files: + - any-glob-to-any-file: '*' -#### Common Examples +# Add 'AnyChange' label to any changes within the entire repository +AnyChange: +- changed-files: + - any-glob-to-any-file: '**' -```yml -# Add 'repo' label to any root file changes -repo: -- changed-files: '*' +# Add 'Documentation' label to any changes within 'docs' folder or any subfolders +Documentation: +- changed-files: + - any-glob-to-any-file: docs/** -# Add '@domain/core' label to any change within the 'core' package -'@domain/core': +# Add 'Documentation' label to any file changes within 'docs' folder +Documentation: - changed-files: - - package/core/* - - package/core/**/* + - any-glob-to-any-file: docs/* -# Add 'test' label to any change to *.spec.js files within the source dir -test: -- changed-files: src/**/*.spec.js +# Add 'Documentation' label to any change to .md files within the entire repository +Documentation: +- changed-files: + - any-glob-to-any-file: '**/*.md' # Add 'source' label to any change to src files within the source dir EXCEPT for the docs sub-folder source: -- changed-files: - - any: ['src/**/*', '!src/docs/*'] - -# Add 'frontend` label to any change to *.js files as long as the `main.js` hasn't changed -frontend: -- any: - - changed-files: ['src/**/*.js'] - all: - - changed-files: ['!src/main.js'] + - changed-files: + - any-glob-to-any-file: 'src/**/*' + - all-globs-to-all-files: '!src/docs/*' - # Add 'feature' label to any PR where the head branch name starts with `feature` or has a `feature` section in the name +# Add 'feature' label to any PR where the head branch name starts with `feature` or has a `feature` section in the name feature: - head-branch: ['^feature', 'feature'] @@ -134,7 +141,7 @@ on: - pull_request_target jobs: - triage: + labeler: permissions: contents: read pull-requests: write @@ -152,7 +159,7 @@ Various inputs are defined in [`action.yml`](action.yml) to let you configure th | `repo-token` | Token to use to authorize label changes. Typically the GITHUB_TOKEN secret | `github.token` | | `configuration-path` | The path to the label configuration file. If the file doesn't exist at the specified path on the runner, action will read from the source repository via the Github API. | `.github/labeler.yml` | | `sync-labels` | Whether or not to remove labels when matching files are reverted or no longer changed by the PR | `false` | -| `dot` | Whether or not to auto-include paths starting with dot (e.g. `.github`) | `false` | +| `dot` | Whether or not to auto-include paths starting with dot (e.g. `.github`) | `true` | | `pr-number` | The number(s) of pull request to update, rather than detecting from the workflow context | N/A | ##### Using `configuration-path` input together with the `@actions/checkout` action @@ -163,27 +170,13 @@ You might want to use action called [@actions/checkout](https://github.com/actio - uses: actions/checkout@v4 # Uploads repository content to the runner with: repository: "owner/repositoryName" # The one of the available inputs, visit https://github.com/actions/checkout#readme to find more - - uses: actions/labeler@v4 -``` - -##### Peculiarities of using the `dot` input - -When `dot` is disabled, and you want to include _all_ files in a folder: - -```yml -label1: -- path/to/folder/**/* -- path/to/folder/**/.* -``` - -If `dot` is enabled: + - uses: actions/labeler@v5 + with: + configuration-path: 'path/to/the/uploaded/configuration/file' -```yml -label1: -- path/to/folder/** ``` -##### Example workflow specifying Pull request numbers +##### Example workflow specifying pull request numbers ```yml name: "Label Previous Pull Requests" @@ -192,7 +185,7 @@ on: - cron: "0 1 * * 1" jobs: - triage: + labeler: permissions: contents: read pull-requests: write @@ -200,7 +193,7 @@ jobs: steps: # Label PRs 1, 2, and 3 - - uses: actions/labeler@v4 + - uses: actions/labeler@v5 with: pr-number: | 1 @@ -221,19 +214,19 @@ Labeler provides the following outputs: The following example performs steps based on the output of labeler: ```yml -name: "My workflow" +name: "Pull Request Labeler" on: - pull_request_target jobs: - triage: + labeler: permissions: contents: read pull-requests: write runs-on: ubuntu-latest steps: - id: label-the-PR - uses: actions/labeler@v4 + uses: actions/labeler@v5 - id: run-frontend-tests if: contains(steps.label-the-PR.outputs.all-labels, 'frontend') diff --git a/__tests__/changedFiles.test.ts b/__tests__/changedFiles.test.ts index 0014c5193..07e0b7575 100644 --- a/__tests__/changedFiles.test.ts +++ b/__tests__/changedFiles.test.ts @@ -17,9 +17,9 @@ describe('checkAllChangedFiles', () => { describe('when all given glob pattern configs matched', () => { const globPatternsConfigs = [ - {AnyGlobToAnyFile: ['foo.txt']}, - {AnyGlobToAllFiles: ['*.txt']}, - {AllGlobsToAllFiles: ['**']} + {anyGlobToAnyFile: ['foo.txt']}, + {anyGlobToAllFiles: ['*.txt']}, + {allGlobsToAllFiles: ['**']} ]; it('returns true', () => { @@ -34,9 +34,9 @@ describe('checkAllChangedFiles', () => { describe(`when some given glob pattern config did not match`, () => { const globPatternsConfigs = [ - {AnyGlobToAnyFile: ['*.md']}, - {AnyGlobToAllFiles: ['*.txt']}, - {AllGlobsToAllFiles: ['**']} + {anyGlobToAnyFile: ['*.md']}, + {anyGlobToAllFiles: ['*.txt']}, + {allGlobsToAllFiles: ['**']} ]; it('returns false', () => { @@ -55,8 +55,8 @@ describe('checkAnyChangedFiles', () => { describe('when any given glob pattern config matched', () => { const globPatternsConfigs = [ - {AnyGlobToAnyFile: ['*.md']}, - {AnyGlobToAllFiles: ['*.txt']} + {anyGlobToAnyFile: ['*.md']}, + {anyGlobToAllFiles: ['*.txt']} ]; it('returns true', () => { @@ -71,8 +71,8 @@ describe('checkAnyChangedFiles', () => { describe('when none of the given glob pattern configs matched', () => { const globPatternsConfigs = [ - {AnyGlobToAnyFile: ['*.md']}, - {AnyGlobToAllFiles: ['!*.txt']} + {anyGlobToAnyFile: ['*.md']}, + {anyGlobToAllFiles: ['!*.txt']} ]; it('returns false', () => { @@ -123,23 +123,25 @@ describe('toChangedFilesMatchConfig', () => { describe('and the glob pattern config key is provided', () => { describe('and the value is an array of strings', () => { - const config = {'changed-files': [{AnyGlobToAnyFile: ['testing']}]}; + const config = { + 'changed-files': [{'any-glob-to-any-file': ['testing']}] + }; it('sets the value in the config object', () => { const result = toChangedFilesMatchConfig(config); expect(result).toEqual({ - changedFiles: [{AnyGlobToAnyFile: ['testing']}] + changedFiles: [{anyGlobToAnyFile: ['testing']}] }); }); }); describe('and the value is a string', () => { - const config = {'changed-files': [{AnyGlobToAnyFile: 'testing'}]}; + const config = {'changed-files': [{'any-glob-to-any-file': 'testing'}]}; it(`sets the string as an array in the config object`, () => { const result = toChangedFilesMatchConfig(config); expect(result).toEqual({ - changedFiles: [{AnyGlobToAnyFile: ['testing']}] + changedFiles: [{anyGlobToAnyFile: ['testing']}] }); }); }); diff --git a/__tests__/fixtures/all_options.yml b/__tests__/fixtures/all_options.yml index 51f515017..9417d13ce 100644 --- a/__tests__/fixtures/all_options.yml +++ b/__tests__/fixtures/all_options.yml @@ -1,17 +1,17 @@ label1: - any: - changed-files: - - AnyGlobToAnyFile: ['glob'] + - any-glob-to-any-file: ['glob'] - head-branch: ['regexp'] - base-branch: ['regexp'] - all: - changed-files: - - AllGlobsToAllFiles: ['glob'] + - all-globs-to-all-files: ['glob'] - head-branch: ['regexp'] - base-branch: ['regexp'] label2: - changed-files: - - AnyGlobToAnyFile: ['glob'] + - any-glob-to-any-file: ['glob'] - head-branch: ['regexp'] - base-branch: ['regexp'] diff --git a/__tests__/fixtures/any_and_all.yml b/__tests__/fixtures/any_and_all.yml index 3ad0bcd9c..10e68b6f7 100644 --- a/__tests__/fixtures/any_and_all.yml +++ b/__tests__/fixtures/any_and_all.yml @@ -2,7 +2,7 @@ tests: - any: - head-branch: ['^tests/', '^test/'] - changed-files: - - AnyGlobToAnyFile: ['tests/**/*'] + - any-glob-to-any-file: ['tests/**/*'] - all: - changed-files: - - AllGlobsToAllFiles: ['!tests/requirements.txt'] + - all-globs-to-all-files: ['!tests/requirements.txt'] diff --git a/__tests__/fixtures/only_pdfs.yml b/__tests__/fixtures/only_pdfs.yml index 72c2eca16..10143494f 100644 --- a/__tests__/fixtures/only_pdfs.yml +++ b/__tests__/fixtures/only_pdfs.yml @@ -1,3 +1,3 @@ touched-a-pdf-file: - changed-files: - - AnyGlobToAnyFile: ['*.pdf'] + - any-glob-to-any-file: ['*.pdf'] diff --git a/__tests__/labeler.test.ts b/__tests__/labeler.test.ts index 84adea241..b780c82ff 100644 --- a/__tests__/labeler.test.ts +++ b/__tests__/labeler.test.ts @@ -29,14 +29,14 @@ describe('getLabelConfigMapFromObject', () => { expected.set('label1', [ { any: [ - {changedFiles: [{AnyGlobToAnyFile: ['glob']}]}, + {changedFiles: [{anyGlobToAnyFile: ['glob']}]}, {baseBranch: undefined, headBranch: ['regexp']}, {baseBranch: ['regexp'], headBranch: undefined} ] }, { all: [ - {changedFiles: [{AllGlobsToAllFiles: ['glob']}]}, + {changedFiles: [{allGlobsToAllFiles: ['glob']}]}, {baseBranch: undefined, headBranch: ['regexp']}, {baseBranch: ['regexp'], headBranch: undefined} ] @@ -45,7 +45,7 @@ describe('getLabelConfigMapFromObject', () => { expected.set('label2', [ { any: [ - {changedFiles: [{AnyGlobToAnyFile: ['glob']}]}, + {changedFiles: [{anyGlobToAnyFile: ['glob']}]}, {baseBranch: undefined, headBranch: ['regexp']}, {baseBranch: ['regexp'], headBranch: undefined} ] @@ -61,12 +61,12 @@ describe('getLabelConfigMapFromObject', () => { describe('toMatchConfig', () => { describe('when all expected config options are present', () => { const config = { - 'changed-files': [{AnyGlobToAnyFile: ['testing-files']}], + 'changed-files': [{'any-glob-to-any-file': ['testing-files']}], 'head-branch': ['testing-head'], 'base-branch': ['testing-base'] }; const expected: BaseMatchConfig = { - changedFiles: [{AnyGlobToAnyFile: ['testing-files']}], + changedFiles: [{anyGlobToAnyFile: ['testing-files']}], headBranch: ['testing-head'], baseBranch: ['testing-base'] }; @@ -90,7 +90,7 @@ describe('toMatchConfig', () => { describe('checkMatchConfigs', () => { describe('when a single match config is provided', () => { const matchConfig: MatchConfig[] = [ - {any: [{changedFiles: [{AnyGlobToAnyFile: ['*.txt']}]}]} + {any: [{changedFiles: [{anyGlobToAnyFile: ['*.txt']}]}]} ]; it('returns true when our pattern does match changed files', () => { @@ -111,7 +111,7 @@ describe('checkMatchConfigs', () => { const matchConfig: MatchConfig[] = [ { any: [ - {changedFiles: [{AnyGlobToAnyFile: ['*.txt']}]}, + {changedFiles: [{anyGlobToAnyFile: ['*.txt']}]}, {headBranch: ['some-branch']} ] } @@ -139,7 +139,7 @@ describe('checkMatchConfigs', () => { describe('when multiple MatchConfigs are supplied', () => { const matchConfig: MatchConfig[] = [ - {any: [{changedFiles: [{AnyGlobToAnyFile: ['*.txt']}]}]}, + {any: [{changedFiles: [{anyGlobToAnyFile: ['*.txt']}]}]}, {any: [{headBranch: ['some-branch']}]} ]; const changedFiles = ['foo.txt', 'bar.md']; @@ -151,7 +151,7 @@ describe('checkMatchConfigs', () => { it('returns true when only both config matches', () => { const matchConfig: MatchConfig[] = [ - {any: [{changedFiles: [{AnyGlobToAnyFile: ['*.txt']}]}]}, + {any: [{changedFiles: [{anyGlobToAnyFile: ['*.txt']}]}]}, {any: [{headBranch: ['head-branch']}]} ]; const result = checkMatchConfigs(changedFiles, matchConfig, false); diff --git a/action.yml b/action.yml index 503d42dd6..846049cc9 100644 --- a/action.yml +++ b/action.yml @@ -16,7 +16,7 @@ inputs: required: false dot: description: 'Whether or not to auto-include paths starting with dot (e.g. `.github`)' - default: false + default: true required: false pr-number: description: 'The pull request number(s)' diff --git a/dist/index.js b/dist/index.js index 949c56579..947c61fa4 100644 --- a/dist/index.js +++ b/dist/index.js @@ -564,11 +564,12 @@ exports.checkIfAllGlobsMatchAllFiles = exports.checkIfAnyGlobMatchesAllFiles = e const core = __importStar(__nccwpck_require__(2186)); const github = __importStar(__nccwpck_require__(5438)); const minimatch_1 = __nccwpck_require__(1953); +const utils_1 = __nccwpck_require__(918); const ALLOWED_FILES_CONFIG_KEYS = [ - 'AnyGlobToAnyFile', - 'AnyGlobToAllFiles', - 'AllGlobsToAnyFile', - 'AllGlobsToAllFiles' + 'any-glob-to-any-file', + 'any-glob-to-all-files', + 'all-globs-to-any-file', + 'all-globs-to-all-files' ]; function getChangedFiles(client, prNumber) { return __awaiter(this, void 0, void 0, function* () { @@ -596,7 +597,7 @@ function toChangedFilesMatchConfig(config) { : [config['changed-files']]; const validChangedFilesConfigs = []; changedFilesConfigs.forEach(changedFilesConfig => { - if (!isObject(changedFilesConfig)) { + 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`); } const changedFilesConfigKeys = Object.keys(changedFilesConfig); @@ -606,7 +607,7 @@ function toChangedFilesMatchConfig(config) { } changedFilesConfigKeys.forEach(key => { validChangedFilesConfigs.push({ - [key]: Array.isArray(changedFilesConfig[key]) + [(0, utils_1.kebabToCamel)(key)]: Array.isArray(changedFilesConfig[key]) ? changedFilesConfig[key] : [changedFilesConfig[key]] }); @@ -617,35 +618,29 @@ function toChangedFilesMatchConfig(config) { }; } exports.toChangedFilesMatchConfig = toChangedFilesMatchConfig; -function isObject(obj) { - return obj !== null && typeof obj === 'object' && !Array.isArray(obj); -} -function printPattern(matcher) { - return (matcher.negate ? '!' : '') + matcher.pattern; -} function checkAnyChangedFiles(changedFiles, globPatternsConfigs, dot) { core.debug(` checking "changed-files" patterns`); for (const globPatternsConfig of globPatternsConfigs) { - if (globPatternsConfig.AnyGlobToAnyFile) { - if (checkIfAnyGlobMatchesAnyFile(changedFiles, globPatternsConfig.AnyGlobToAnyFile, dot)) { + if (globPatternsConfig.anyGlobToAnyFile) { + if (checkIfAnyGlobMatchesAnyFile(changedFiles, globPatternsConfig.anyGlobToAnyFile, dot)) { core.debug(` "changed-files" matched`); return true; } } - if (globPatternsConfig.AnyGlobToAllFiles) { - if (checkIfAnyGlobMatchesAllFiles(changedFiles, globPatternsConfig.AnyGlobToAllFiles, dot)) { + if (globPatternsConfig.anyGlobToAllFiles) { + if (checkIfAnyGlobMatchesAllFiles(changedFiles, globPatternsConfig.anyGlobToAllFiles, dot)) { core.debug(` "changed-files" matched`); return true; } } - if (globPatternsConfig.AllGlobsToAnyFile) { - if (checkIfAllGlobsMatchAnyFile(changedFiles, globPatternsConfig.AllGlobsToAnyFile, dot)) { + if (globPatternsConfig.allGlobsToAnyFile) { + if (checkIfAllGlobsMatchAnyFile(changedFiles, globPatternsConfig.allGlobsToAnyFile, dot)) { core.debug(` "changed-files" matched`); return true; } } - if (globPatternsConfig.AllGlobsToAllFiles) { - if (checkIfAllGlobsMatchAllFiles(changedFiles, globPatternsConfig.AllGlobsToAllFiles, dot)) { + if (globPatternsConfig.allGlobsToAllFiles) { + if (checkIfAllGlobsMatchAllFiles(changedFiles, globPatternsConfig.allGlobsToAllFiles, dot)) { core.debug(` "changed-files" matched`); return true; } @@ -658,26 +653,26 @@ exports.checkAnyChangedFiles = checkAnyChangedFiles; function checkAllChangedFiles(changedFiles, globPatternsConfigs, dot) { core.debug(` checking "changed-files" patterns`); for (const globPatternsConfig of globPatternsConfigs) { - if (globPatternsConfig.AnyGlobToAnyFile) { - if (!checkIfAnyGlobMatchesAnyFile(changedFiles, globPatternsConfig.AnyGlobToAnyFile, dot)) { + if (globPatternsConfig.anyGlobToAnyFile) { + if (!checkIfAnyGlobMatchesAnyFile(changedFiles, globPatternsConfig.anyGlobToAnyFile, dot)) { core.debug(` "changed-files" did not match`); return false; } } - if (globPatternsConfig.AnyGlobToAllFiles) { - if (!checkIfAnyGlobMatchesAllFiles(changedFiles, globPatternsConfig.AnyGlobToAllFiles, dot)) { + if (globPatternsConfig.anyGlobToAllFiles) { + if (!checkIfAnyGlobMatchesAllFiles(changedFiles, globPatternsConfig.anyGlobToAllFiles, dot)) { core.debug(` "changed-files" did not match`); return false; } } - if (globPatternsConfig.AllGlobsToAnyFile) { - if (!checkIfAllGlobsMatchAnyFile(changedFiles, globPatternsConfig.AllGlobsToAnyFile, dot)) { + if (globPatternsConfig.allGlobsToAnyFile) { + if (!checkIfAllGlobsMatchAnyFile(changedFiles, globPatternsConfig.allGlobsToAnyFile, dot)) { core.debug(` "changed-files" did not match`); return false; } } - if (globPatternsConfig.AllGlobsToAllFiles) { - if (!checkIfAllGlobsMatchAllFiles(changedFiles, globPatternsConfig.AllGlobsToAllFiles, dot)) { + if (globPatternsConfig.allGlobsToAllFiles) { + if (!checkIfAllGlobsMatchAllFiles(changedFiles, globPatternsConfig.allGlobsToAllFiles, dot)) { core.debug(` "changed-files" did not match`); return false; } @@ -688,15 +683,15 @@ function checkAllChangedFiles(changedFiles, globPatternsConfigs, dot) { } exports.checkAllChangedFiles = checkAllChangedFiles; function checkIfAnyGlobMatchesAnyFile(changedFiles, globs, dot) { - core.debug(` checking "AnyGlobToAnyFile" config patterns`); + core.debug(` checking "anyGlobToAnyFile" config patterns`); const matchers = globs.map(g => new minimatch_1.Minimatch(g, { dot })); for (const matcher of matchers) { const matchedFile = changedFiles.find(changedFile => { - core.debug(` checking "${printPattern(matcher)}" pattern against ${changedFile}`); + core.debug(` checking "${(0, utils_1.printPattern)(matcher)}" pattern against ${changedFile}`); return matcher.match(changedFile); }); if (matchedFile) { - core.debug(` "${printPattern(matcher)}" pattern matched ${matchedFile}`); + core.debug(` "${(0, utils_1.printPattern)(matcher)}" pattern matched ${matchedFile}`); return true; } } @@ -705,15 +700,15 @@ function checkIfAnyGlobMatchesAnyFile(changedFiles, globs, dot) { } exports.checkIfAnyGlobMatchesAnyFile = checkIfAnyGlobMatchesAnyFile; function checkIfAllGlobsMatchAnyFile(changedFiles, globs, dot) { - core.debug(` checking "AllGlobsToAnyFile" config patterns`); + core.debug(` checking "allGlobsToAnyFile" config patterns`); const matchers = globs.map(g => new minimatch_1.Minimatch(g, { dot })); for (const changedFile of changedFiles) { const mismatchedGlob = matchers.find(matcher => { - core.debug(` checking "${printPattern(matcher)}" pattern against ${changedFile}`); + core.debug(` checking "${(0, utils_1.printPattern)(matcher)}" pattern against ${changedFile}`); return !matcher.match(changedFile); }); if (mismatchedGlob) { - core.debug(` "${printPattern(mismatchedGlob)}" pattern did not match ${changedFile}`); + core.debug(` "${(0, utils_1.printPattern)(mismatchedGlob)}" pattern did not match ${changedFile}`); continue; } core.debug(` all patterns matched ${changedFile}`); @@ -724,18 +719,18 @@ function checkIfAllGlobsMatchAnyFile(changedFiles, globs, dot) { } exports.checkIfAllGlobsMatchAnyFile = checkIfAllGlobsMatchAnyFile; function checkIfAnyGlobMatchesAllFiles(changedFiles, globs, dot) { - core.debug(` checking "AnyGlobToAllFiles" config patterns`); + core.debug(` checking "anyGlobToAllFiles" config patterns`); const matchers = globs.map(g => new minimatch_1.Minimatch(g, { dot })); for (const matcher of matchers) { const mismatchedFile = changedFiles.find(changedFile => { - core.debug(` checking "${printPattern(matcher)}" pattern against ${changedFile}`); + core.debug(` checking "${(0, utils_1.printPattern)(matcher)}" pattern against ${changedFile}`); return !matcher.match(changedFile); }); if (mismatchedFile) { - core.debug(` "${printPattern(matcher)}" pattern did not match ${mismatchedFile}`); + core.debug(` "${(0, utils_1.printPattern)(matcher)}" pattern did not match ${mismatchedFile}`); continue; } - core.debug(` "${printPattern(matcher)}" pattern matched all files`); + core.debug(` "${(0, utils_1.printPattern)(matcher)}" pattern matched all files`); return true; } core.debug(` none of the patterns matched all files`); @@ -743,15 +738,15 @@ function checkIfAnyGlobMatchesAllFiles(changedFiles, globs, dot) { } exports.checkIfAnyGlobMatchesAllFiles = checkIfAnyGlobMatchesAllFiles; function checkIfAllGlobsMatchAllFiles(changedFiles, globs, dot) { - core.debug(` checking "AllGlobsToAllFiles" config patterns`); + core.debug(` checking "allGlobsToAllFiles" config patterns`); const matchers = globs.map(g => new minimatch_1.Minimatch(g, { dot })); for (const changedFile of changedFiles) { const mismatchedGlob = matchers.find(matcher => { - core.debug(` checking "${printPattern(matcher)}" pattern against ${changedFile}`); + core.debug(` checking "${(0, utils_1.printPattern)(matcher)}" pattern against ${changedFile}`); return !matcher.match(changedFile); }); if (mismatchedGlob) { - core.debug(` "${printPattern(mismatchedGlob)}" pattern did not match ${changedFile}`); + core.debug(` "${(0, utils_1.printPattern)(mismatchedGlob)}" pattern did not match ${changedFile}`); return false; } } @@ -1110,6 +1105,29 @@ function checkAll(matchConfigs, changedFiles, dot) { exports.checkAll = checkAll; +/***/ }), + +/***/ 918: +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.isObject = exports.kebabToCamel = exports.printPattern = void 0; +const printPattern = (matcher) => { + return (matcher.negate ? '!' : '') + matcher.pattern; +}; +exports.printPattern = printPattern; +const kebabToCamel = (str) => { + return str.replace(/-./g, m => m.toUpperCase()[1]); +}; +exports.kebabToCamel = kebabToCamel; +function isObject(obj) { + return obj !== null && typeof obj === 'object' && !Array.isArray(obj); +} +exports.isObject = isObject; + + /***/ }), /***/ 7351: diff --git a/src/changedFiles.ts b/src/changedFiles.ts index 862575c95..a5038f96a 100644 --- a/src/changedFiles.ts +++ b/src/changedFiles.ts @@ -1,25 +1,26 @@ import * as core from '@actions/core'; import * as github from '@actions/github'; import {Minimatch} from 'minimatch'; +import {printPattern, isObject, kebabToCamel} from './utils'; export interface ChangedFilesMatchConfig { changedFiles?: ChangedFilesGlobPatternsConfig[]; } interface ChangedFilesGlobPatternsConfig { - AnyGlobToAnyFile?: string[]; - AnyGlobToAllFiles?: string[]; - AllGlobsToAnyFile?: string[]; - AllGlobsToAllFiles?: string[]; + anyGlobToAnyFile?: string[]; + anyGlobToAllFiles?: string[]; + allGlobsToAnyFile?: string[]; + allGlobsToAllFiles?: string[]; } type ClientType = ReturnType; const ALLOWED_FILES_CONFIG_KEYS = [ - 'AnyGlobToAnyFile', - 'AnyGlobToAllFiles', - 'AllGlobsToAnyFile', - 'AllGlobsToAllFiles' + 'any-glob-to-any-file', + 'any-glob-to-all-files', + 'all-globs-to-any-file', + 'all-globs-to-all-files' ]; export async function getChangedFiles( @@ -77,7 +78,7 @@ export function toChangedFilesMatchConfig( changedFilesConfigKeys.forEach(key => { validChangedFilesConfigs.push({ - [key]: Array.isArray(changedFilesConfig[key]) + [kebabToCamel(key)]: Array.isArray(changedFilesConfig[key]) ? changedFilesConfig[key] : [changedFilesConfig[key]] }); @@ -89,14 +90,6 @@ export function toChangedFilesMatchConfig( }; } -function isObject(obj: unknown): obj is object { - return obj !== null && typeof obj === 'object' && !Array.isArray(obj); -} - -function printPattern(matcher: Minimatch): string { - return (matcher.negate ? '!' : '') + matcher.pattern; -} - export function checkAnyChangedFiles( changedFiles: string[], globPatternsConfigs: ChangedFilesGlobPatternsConfig[], @@ -105,11 +98,11 @@ export function checkAnyChangedFiles( core.debug(` checking "changed-files" patterns`); for (const globPatternsConfig of globPatternsConfigs) { - if (globPatternsConfig.AnyGlobToAnyFile) { + if (globPatternsConfig.anyGlobToAnyFile) { if ( checkIfAnyGlobMatchesAnyFile( changedFiles, - globPatternsConfig.AnyGlobToAnyFile, + globPatternsConfig.anyGlobToAnyFile, dot ) ) { @@ -118,11 +111,11 @@ export function checkAnyChangedFiles( } } - if (globPatternsConfig.AnyGlobToAllFiles) { + if (globPatternsConfig.anyGlobToAllFiles) { if ( checkIfAnyGlobMatchesAllFiles( changedFiles, - globPatternsConfig.AnyGlobToAllFiles, + globPatternsConfig.anyGlobToAllFiles, dot ) ) { @@ -131,11 +124,11 @@ export function checkAnyChangedFiles( } } - if (globPatternsConfig.AllGlobsToAnyFile) { + if (globPatternsConfig.allGlobsToAnyFile) { if ( checkIfAllGlobsMatchAnyFile( changedFiles, - globPatternsConfig.AllGlobsToAnyFile, + globPatternsConfig.allGlobsToAnyFile, dot ) ) { @@ -144,11 +137,11 @@ export function checkAnyChangedFiles( } } - if (globPatternsConfig.AllGlobsToAllFiles) { + if (globPatternsConfig.allGlobsToAllFiles) { if ( checkIfAllGlobsMatchAllFiles( changedFiles, - globPatternsConfig.AllGlobsToAllFiles, + globPatternsConfig.allGlobsToAllFiles, dot ) ) { @@ -170,11 +163,11 @@ export function checkAllChangedFiles( core.debug(` checking "changed-files" patterns`); for (const globPatternsConfig of globPatternsConfigs) { - if (globPatternsConfig.AnyGlobToAnyFile) { + if (globPatternsConfig.anyGlobToAnyFile) { if ( !checkIfAnyGlobMatchesAnyFile( changedFiles, - globPatternsConfig.AnyGlobToAnyFile, + globPatternsConfig.anyGlobToAnyFile, dot ) ) { @@ -183,11 +176,11 @@ export function checkAllChangedFiles( } } - if (globPatternsConfig.AnyGlobToAllFiles) { + if (globPatternsConfig.anyGlobToAllFiles) { if ( !checkIfAnyGlobMatchesAllFiles( changedFiles, - globPatternsConfig.AnyGlobToAllFiles, + globPatternsConfig.anyGlobToAllFiles, dot ) ) { @@ -196,11 +189,11 @@ export function checkAllChangedFiles( } } - if (globPatternsConfig.AllGlobsToAnyFile) { + if (globPatternsConfig.allGlobsToAnyFile) { if ( !checkIfAllGlobsMatchAnyFile( changedFiles, - globPatternsConfig.AllGlobsToAnyFile, + globPatternsConfig.allGlobsToAnyFile, dot ) ) { @@ -209,11 +202,11 @@ export function checkAllChangedFiles( } } - if (globPatternsConfig.AllGlobsToAllFiles) { + if (globPatternsConfig.allGlobsToAllFiles) { if ( !checkIfAllGlobsMatchAllFiles( changedFiles, - globPatternsConfig.AllGlobsToAllFiles, + globPatternsConfig.allGlobsToAllFiles, dot ) ) { @@ -232,7 +225,7 @@ export function checkIfAnyGlobMatchesAnyFile( globs: string[], dot: boolean ): boolean { - core.debug(` checking "AnyGlobToAnyFile" config patterns`); + core.debug(` checking "any-glob-to-any-file" config patterns`); const matchers = globs.map(g => new Minimatch(g, {dot})); for (const matcher of matchers) { @@ -263,7 +256,7 @@ export function checkIfAllGlobsMatchAnyFile( globs: string[], dot: boolean ): boolean { - core.debug(` checking "AllGlobsToAnyFile" config patterns`); + core.debug(` checking "all-globs-to-any-file" config patterns`); const matchers = globs.map(g => new Minimatch(g, {dot})); for (const changedFile of changedFiles) { @@ -300,7 +293,7 @@ export function checkIfAnyGlobMatchesAllFiles( globs: string[], dot: boolean ): boolean { - core.debug(` checking "AnyGlobToAllFiles" config patterns`); + core.debug(` checking "any-glob-to-all-files" config patterns`); const matchers = globs.map(g => new Minimatch(g, {dot})); for (const matcher of matchers) { @@ -337,7 +330,7 @@ export function checkIfAllGlobsMatchAllFiles( globs: string[], dot: boolean ): boolean { - core.debug(` checking "AllGlobsToAllFiles" config patterns`); + core.debug(` checking "all-globs-to-all-files" config patterns`); const matchers = globs.map(g => new Minimatch(g, {dot})); for (const changedFile of changedFiles) { diff --git a/src/utils.ts b/src/utils.ts new file mode 100644 index 000000000..18bcc8063 --- /dev/null +++ b/src/utils.ts @@ -0,0 +1,13 @@ +import {Minimatch} from 'minimatch'; + +export const printPattern = (matcher: Minimatch): string => { + return (matcher.negate ? '!' : '') + matcher.pattern; +}; + +export const kebabToCamel = (str: string): string => { + return str.replace(/-./g, m => m.toUpperCase()[1]); +}; + +export function isObject(obj: unknown): obj is object { + return obj !== null && typeof obj === 'object' && !Array.isArray(obj); +} diff --git a/src/utils/index.ts b/src/utils/index.ts deleted file mode 100644 index e60b76ad9..000000000 --- a/src/utils/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './print-pattern'; diff --git a/src/utils/print-pattern.ts b/src/utils/print-pattern.ts deleted file mode 100644 index ab4975302..000000000 --- a/src/utils/print-pattern.ts +++ /dev/null @@ -1,5 +0,0 @@ -import {Minimatch} from 'minimatch'; - -export const printPattern = (matcher: Minimatch): string => { - return (matcher.negate ? '!' : '') + matcher.pattern; -};