Skip to content

Commit

Permalink
Merge pull request #72 from GrantBirki/feat/non-existing-exclude-file
Browse files Browse the repository at this point in the history
Feature: Allow non-existing exclude file
  • Loading branch information
GrantBirki committed Aug 15, 2024
2 parents 5074bb1 + bdfd2f8 commit fcb9d1a
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 5 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ Here is a quick example of how to install this action in any workflow:
| `yaml_exclude_regex` | `false` | `""` | A regex to exclude files from validation (e.g. `".*\.schema\.yaml$"` to exclude all files ending with `.schema.yaml`) - Default is `""` which doesn't exclude any files |
| `yaml_as_json` | `false` | `"false"` | Whether or not to treat and validate YAML files as JSON files - `"true"` or `"false"` - Default is `"false"`. If this is true, the JSON schema will be used to validate YAML files. Any YAML schemas will be ignored. For this context, a YAML file is any file which matches the yaml_extension or yaml_extension_short inputs. See the [docs](docs/yaml_as_json.md) for more details |
| `exclude_file` | `false` | `""` | The full path to a file in the repository where this Action is running that contains a list of '.gitignore'-style patterns to exclude files from validation (e.g. ./exclude.txt) |
| `exclude_file_required` | `true` | `"true"` | Whether or not the `exclude_file` must exist if it is used. If this is `true` and the `exclude_file` does not exist, the Action will fail. Set this to `"false"` if you do not care when the `exclude_file` exists or not |
| `use_gitignore` | `true` | `"true"` | Whether or not to use the .gitignore file in the root of the repository to exclude files from validation - `"true"` or `"false"` - Default is `"true"` |
| `git_ignore_path` | `false` | `".gitignore"` | The full path to the .gitignore file to use if use_gitignore is set to "true" (e.g. ./src/.gitignore) - Default is ".gitignore" which uses the .gitignore file in the root of the repository |
| `allow_multiple_documents` | `false` | `"false"` | Whether or not to allow multiple documents in a single YAML file - `"true"` or `"false"` - Default is `"false"`. Useful for k8s documents. |
Expand Down
40 changes: 40 additions & 0 deletions __tests__/functions/exclude.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,20 @@ import * as core from '@actions/core'
import {Exclude} from '../../src/functions/exclude'

const warningMock = jest.spyOn(core, 'warning').mockImplementation(() => {})
const setFailedMock = jest.spyOn(core, 'setFailed').mockImplementation(() => {})
const infoMock = jest.spyOn(core, 'info').mockImplementation(() => {})
const debugMock = jest.spyOn(core, 'debug').mockImplementation(() => {})

var exclude
beforeEach(() => {
jest.clearAllMocks()
jest.spyOn(core, 'debug').mockImplementation(() => {})
jest.spyOn(core, 'setFailed').mockImplementation(() => {})
jest.spyOn(core, 'info').mockImplementation(() => {})
process.env.INPUT_EXCLUDE_FILE = '__tests__/fixtures/exclude/exclude.txt'
process.env.INPUT_GIT_IGNORE_PATH = '.gitignore'
process.env.INPUT_USE_GITIGNORE = 'true'
process.env.INPUT_EXCLUDE_FILE_REQUIRED = 'true'
exclude = new Exclude()
})

Expand Down Expand Up @@ -44,6 +50,40 @@ test('does not exclude any files when no exclude file is used', () => {
expect(exclude.isExcluded('exclude-me.json')).toBe(false)
})

test('raises an exception when no exclude file is found', () => {
process.env.INPUT_EXCLUDE_FILE = 'oh_no_i_dont_exist.txt'
process.env.INPUT_EXCLUDE_FILE_REQUIRED = 'true'

expect(() => {
new Exclude()
}).toThrow(
`Error: ENOENT: no such file or directory, open 'oh_no_i_dont_exist.txt'`
)
expect(setFailedMock).toHaveBeenCalledWith(
`error reading exclude_file: oh_no_i_dont_exist.txt`
)
})

test('does not raise an exception when no exclude file is found and it is not required', () => {
process.env.INPUT_EXCLUDE_FILE = 'oh_no_i_dont_exist.txt'
process.env.INPUT_EXCLUDE_FILE_REQUIRED = 'false'

const exclude = new Exclude()
expect(exclude.isExcluded('exclude-me.json')).toBe(false)
expect(infoMock).toHaveBeenCalledWith(
`exclude_file was not found, but it is not required - OK`
)
})

test('does not raise an exception when no exclude file is found and it is required', () => {
process.env.INPUT_EXCLUDE_FILE = ''
process.env.INPUT_EXCLUDE_FILE_REQUIRED = 'true'

const exclude = new Exclude()
expect(exclude.isExcluded('exclude-me.json')).toBe(false)
expect(debugMock).toHaveBeenCalledWith(`exclude_file was not provided - OK`)
})

test('excludes a file that is not tracked by git', () => {
process.env.INPUT_EXCLUDE_FILE = ''
const exclude = new Exclude()
Expand Down
3 changes: 3 additions & 0 deletions __tests__/main.test.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import * as core from '@actions/core'
import {run} from '../src/main'
import * as jsonValidator from '../src/functions/json-validator'
import * as yamlValidator from '../src/functions/yaml-validator'
import * as processResults from '../src/functions/process-results'

beforeEach(() => {
jest.clearAllMocks()
jest.spyOn(core, 'debug').mockImplementation(() => {})
jest.spyOn(jsonValidator, 'jsonValidator').mockImplementation(() => {
return {success: true, failed: 0, passed: 8, skipped: 0, violations: []}
})
Expand All @@ -16,6 +18,7 @@ beforeEach(() => {
})

process.env.INPUT_USE_GITIGNORE = 'false'
process.env.INPUT_EXCLUDE_FILE_REQUIRED = 'true'
})

test('successfully runs the action', async () => {
Expand Down
4 changes: 4 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ inputs:
description: The full path to a file in the repository where this Action is running that contains a list of '.gitignore'-style patterns to exclude files from validation (e.g. ./exclude.txt)
required: false
default: ""
exclude_file_required:
description: Whether or not the exclude_file must exist if it is used. If this is true and the exclude_file does not exist, the Action will fail - "true" or "false" - Default is "true"
required: false
default: "true"
use_gitignore:
description: Whether or not to use the .gitignore file in the root of the repository to exclude files from validation - "true" or "false" - Default is "true"
required: true
Expand Down
16 changes: 14 additions & 2 deletions dist/index.js

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

2 changes: 1 addition & 1 deletion dist/index.js.map

Large diffs are not rendered by default.

16 changes: 14 additions & 2 deletions src/functions/exclude.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import ignore from 'ignore'
export class Exclude {
constructor() {
this.path = core.getInput('exclude_file')
this.required = core.getBooleanInput('exclude_file_required')
this.gitTrackedOnly = core.getBooleanInput('use_gitignore')

// initialize the exclude array
Expand All @@ -13,8 +14,19 @@ export class Exclude {
// read the exclude file if it was used
if (this.path && this.path !== '') {
core.debug(`loading exclude_file: ${this.path}`)
this.ignore.add(readFileSync(this.path, 'utf8').toString())
core.debug(`loaded custom exclude patterns`)
try {
this.ignore.add(readFileSync(this.path, 'utf8').toString())
core.debug(`loaded custom exclude patterns`)
} catch (error) {
if (this.required === true) {
core.setFailed(`error reading exclude_file: ${this.path}`)
throw new Error(error)
}

core.info(`exclude_file was not found, but it is not required - OK`)
}
} else {
core.debug(`exclude_file was not provided - OK`)
}

// if gitTrackOnly is true, add the git exclude patterns from the .gitignore file if it exists
Expand Down

0 comments on commit fcb9d1a

Please sign in to comment.