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

Allow changed files as input #256

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
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
21 changes: 12 additions & 9 deletions action.yml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
name: 'Paths Changes Filter'
description: 'Execute your workflow steps only if relevant files are modified.'
author: 'Michal Dorner <[email protected]>'
name: "Paths Changes Filter"
description: "Execute your workflow steps only if relevant files are modified."
author: "Michal Dorner <[email protected]>"
inputs:
token:
description: 'GitHub Access Token'
description: "GitHub Access Token"
required: false
default: ${{ github.token }}
working-directory:
description: 'Relative path under $GITHUB_WORKSPACE where the repository was checked out.'
description: "Relative path under $GITHUB_WORKSPACE where the repository was checked out."
required: false
ref:
description: |
Expand All @@ -20,8 +20,11 @@ inputs:
If it references same branch it was pushed to, changes are detected against the most recent commit before the push.
This option is ignored if action is triggered by pull_request event.
required: false
files:
description: "Manual list of files to filter"
required: false
filters:
description: 'Path to the configuration file or YAML string with filters definition'
description: "Path to the configuration file or YAML string with filters definition"
required: true
list-files:
description: |
Expand All @@ -43,13 +46,13 @@ inputs:
until the merge-base is found or there are no more commits in the history.
This option takes effect only when changes are detected using git against different base branch.
required: false
default: '100'
default: "100"
outputs:
changes:
description: JSON array with names of all filters matching any of changed files
runs:
using: 'node20'
main: 'dist/index.js'
using: "node20"
main: "dist/index.js"
branding:
color: blue
icon: filter
14 changes: 11 additions & 3 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -553,9 +553,10 @@ var __importStar = (this && this.__importStar) || function (mod) {
return result;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
const fs = __importStar(__nccwpck_require__(7147));
const core = __importStar(__nccwpck_require__(2186));
const fs = __importStar(__nccwpck_require__(7147));
const github = __importStar(__nccwpck_require__(5438));
const jsyaml = __importStar(__nccwpck_require__(1917));
const filter_1 = __nccwpck_require__(3707);
const file_1 = __nccwpck_require__(4014);
const git = __importStar(__nccwpck_require__(3374));
Expand All @@ -570,6 +571,7 @@ async function run() {
const token = core.getInput('token', { required: false });
const ref = core.getInput('ref', { required: false });
const base = core.getInput('base', { required: false });
const filesInput = core.getInput('files', { required: false });
const filtersInput = core.getInput('filters', { required: true });
const filtersYaml = isPathInput(filtersInput) ? getConfigFileContent(filtersInput) : filtersInput;
const listFiles = core.getInput('list-files', { required: false }).toLowerCase() || 'none';
Expand All @@ -586,7 +588,8 @@ async function run() {
}
const filterConfig = { predicateQuantifier };
const filter = new filter_1.Filter(filtersYaml, filterConfig);
const files = await getChangedFiles(token, base, ref, initialFetchDepth);
core.info(`Detected ${filesInput} files`);
const files = await getChangedFiles(filesInput, token, base, ref, initialFetchDepth);
core.info(`Detected ${files.length} changed files`);
const results = filter.match(files);
exportResults(results, listFiles);
Expand All @@ -607,8 +610,13 @@ function getConfigFileContent(configPath) {
}
return fs.readFileSync(configPath, { encoding: 'utf8' });
}
async function getChangedFiles(token, base, ref, initialFetchDepth) {
async function getChangedFiles(files, token, base, ref, initialFetchDepth) {
var _a, _b;
if (files) {
core.info('Using list of files provided as input');
const doc = jsyaml.load(files);
return doc.map(filename => ({ filename, status: file_1.ChangeStatus.Modified }));
}
// if base is 'HEAD' only local uncommitted changes will be detected
// This is the simplest case as we don't need to fetch more commits or evaluate current/before refs
if (base === git.HEAD) {
Expand Down
50 changes: 32 additions & 18 deletions src/main.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import * as fs from 'fs'
import * as core from '@actions/core'
import * as fs from 'fs'
import * as github from '@actions/github'
import {GetResponseDataTypeFromEndpointMethod} from '@octokit/types'
import {PushEvent, PullRequestEvent} from '@octokit/webhooks-types'
import * as jsyaml from 'js-yaml'
import { GetResponseDataTypeFromEndpointMethod } from '@octokit/types'
import { PushEvent, PullRequestEvent } from '@octokit/webhooks-types'

import {
isPredicateQuantifier,
Expand All @@ -12,28 +13,29 @@ import {
PredicateQuantifier,
SUPPORTED_PREDICATE_QUANTIFIERS
} from './filter'
import {File, ChangeStatus} from './file'
import { File, ChangeStatus } from './file'
import * as git from './git'
import {backslashEscape, shellEscape} from './list-format/shell-escape'
import {csvEscape} from './list-format/csv-escape'
import { backslashEscape, shellEscape } from './list-format/shell-escape'
import { csvEscape } from './list-format/csv-escape'

type ExportFormat = 'none' | 'csv' | 'json' | 'shell' | 'escape'

async function run(): Promise<void> {
try {
const workingDirectory = core.getInput('working-directory', {required: false})
const workingDirectory = core.getInput('working-directory', { required: false })
if (workingDirectory) {
process.chdir(workingDirectory)
}

const token = core.getInput('token', {required: false})
const ref = core.getInput('ref', {required: false})
const base = core.getInput('base', {required: false})
const filtersInput = core.getInput('filters', {required: true})
const token = core.getInput('token', { required: false })
const ref = core.getInput('ref', { required: false })
const base = core.getInput('base', { required: false })
const filesInput = core.getInput('files', { required: false })
const filtersInput = core.getInput('filters', { required: true })
const filtersYaml = isPathInput(filtersInput) ? getConfigFileContent(filtersInput) : filtersInput
const listFiles = core.getInput('list-files', {required: false}).toLowerCase() || 'none'
const initialFetchDepth = parseInt(core.getInput('initial-fetch-depth', {required: false})) || 10
const predicateQuantifier = core.getInput('predicate-quantifier', {required: false}) || PredicateQuantifier.SOME
const listFiles = core.getInput('list-files', { required: false }).toLowerCase() || 'none'
const initialFetchDepth = parseInt(core.getInput('initial-fetch-depth', { required: false })) || 10
const predicateQuantifier = core.getInput('predicate-quantifier', { required: false }) || PredicateQuantifier.SOME

if (!isExportFormat(listFiles)) {
core.setFailed(`Input parameter 'list-files' is set to invalid value '${listFiles}'`)
Expand All @@ -46,10 +48,10 @@ async function run(): Promise<void> {
`'${predicateQuantifier}'. Valid values: ${SUPPORTED_PREDICATE_QUANTIFIERS.join(', ')}`
throw new Error(predicateQuantifierInvalidErrorMsg)
}
const filterConfig: FilterConfig = {predicateQuantifier}
const filterConfig: FilterConfig = { predicateQuantifier }

const filter = new Filter(filtersYaml, filterConfig)
const files = await getChangedFiles(token, base, ref, initialFetchDepth)
const files = await getChangedFiles(filesInput, token, base, ref, initialFetchDepth)
core.info(`Detected ${files.length} changed files`)
const results = filter.match(files)
exportResults(results, listFiles)
Expand All @@ -71,10 +73,22 @@ function getConfigFileContent(configPath: string): string {
throw new Error(`'${configPath}' is not a file.`)
}

return fs.readFileSync(configPath, {encoding: 'utf8'})
return fs.readFileSync(configPath, { encoding: 'utf8' })
}

async function getChangedFiles(token: string, base: string, ref: string, initialFetchDepth: number): Promise<File[]> {
async function getChangedFiles(
files: string,
token: string,
base: string,
ref: string,
initialFetchDepth: number
): Promise<File[]> {
if (files) {
core.info('Using list of files provided as input')
const doc = jsyaml.load(files) as string[]
return doc.map(filename => ({ filename, status: ChangeStatus.Modified }))
}

// if base is 'HEAD' only local uncommitted changes will be detected
// This is the simplest case as we don't need to fetch more commits or evaluate current/before refs
if (base === git.HEAD) {
Expand Down