Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Allow non-existing exclude file #72

Merged
merged 5 commits into from
Aug 15, 2024
Merged
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
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