mirror of
https://github.com/actions/labeler.git
synced 2025-12-11 12:07:32 +00:00
Move all changedFiles logic into it's own file
This commit is contained in:
@@ -10,11 +10,7 @@ beforeAll(() => {
|
||||
});
|
||||
});
|
||||
|
||||
// I have to double cast here as this is what the output from js-yaml looks like which then gets
|
||||
// transformed in toMatchConfig
|
||||
const matchConfig = [
|
||||
{'changed-files': [{any: ['*.txt']}]}
|
||||
] as unknown as MatchConfig[];
|
||||
const matchConfig: MatchConfig[] = [{changedFiles: {any: ['*.txt']}}];
|
||||
|
||||
describe('checkMatchConfigs', () => {
|
||||
it('returns true when our pattern does match changed files', () => {
|
||||
|
||||
126
src/changedFiles.ts
Normal file
126
src/changedFiles.ts
Normal file
@@ -0,0 +1,126 @@
|
||||
import * as core from '@actions/core';
|
||||
import * as github from '@actions/github';
|
||||
import {Minimatch} from 'minimatch';
|
||||
|
||||
export interface ChangedFilesMatchConfig {
|
||||
changedFiles?: {
|
||||
all?: string[];
|
||||
any?: string[];
|
||||
};
|
||||
}
|
||||
|
||||
type ClientType = ReturnType<typeof github.getOctokit>;
|
||||
|
||||
export async function getChangedFiles(
|
||||
client: ClientType,
|
||||
prNumber: number
|
||||
): Promise<string[]> {
|
||||
const listFilesOptions = client.rest.pulls.listFiles.endpoint.merge({
|
||||
owner: github.context.repo.owner,
|
||||
repo: github.context.repo.repo,
|
||||
pull_number: prNumber
|
||||
});
|
||||
|
||||
const listFilesResponse = await client.paginate(listFilesOptions);
|
||||
const changedFiles = listFilesResponse.map((f: any) => f.filename);
|
||||
|
||||
core.debug('found changed files:');
|
||||
for (const file of changedFiles) {
|
||||
core.debug(' ' + file);
|
||||
}
|
||||
|
||||
return changedFiles;
|
||||
}
|
||||
|
||||
export function toChangedFilesMatchConfig(
|
||||
config: any
|
||||
): ChangedFilesMatchConfig {
|
||||
if (!config['changed-files']) {
|
||||
return {};
|
||||
}
|
||||
const changedFilesConfig = config['changed-files'];
|
||||
|
||||
// If the value provided is a string or an array of strings then default to `any` matching
|
||||
if (typeof changedFilesConfig === 'string') {
|
||||
return {
|
||||
changedFiles: {
|
||||
any: [changedFilesConfig]
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const changedFilesMatchConfig = {
|
||||
changedFiles: {}
|
||||
};
|
||||
|
||||
if (Array.isArray(changedFilesConfig)) {
|
||||
if (changedFilesConfig.every(entry => typeof entry === 'string')) {
|
||||
changedFilesMatchConfig.changedFiles = {
|
||||
any: changedFilesConfig
|
||||
};
|
||||
} else {
|
||||
// If it is not an array of strings then it should be array of further config options
|
||||
// so assign them to our `changedFilesMatchConfig`
|
||||
Object.assign(
|
||||
changedFilesMatchConfig.changedFiles,
|
||||
...changedFilesConfig
|
||||
);
|
||||
Object.keys(changedFilesMatchConfig.changedFiles).forEach(key => {
|
||||
const value = changedFilesMatchConfig.changedFiles[key];
|
||||
changedFilesMatchConfig.changedFiles[key] = Array.isArray(value)
|
||||
? value
|
||||
: [value];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return changedFilesMatchConfig;
|
||||
}
|
||||
|
||||
function printPattern(matcher: Minimatch): string {
|
||||
return (matcher.negate ? '!' : '') + matcher.pattern;
|
||||
}
|
||||
|
||||
function isMatch(changedFile: string, matchers: Minimatch[]): boolean {
|
||||
core.debug(` matching patterns against file ${changedFile}`);
|
||||
for (const matcher of matchers) {
|
||||
core.debug(` - ${printPattern(matcher)}`);
|
||||
if (!matcher.match(changedFile)) {
|
||||
core.debug(` ${printPattern(matcher)} did not match`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
core.debug(` all patterns matched`);
|
||||
return true;
|
||||
}
|
||||
|
||||
// equivalent to "Array.some()" but expanded for debugging and clarity
|
||||
export function checkAny(changedFiles: string[], globs: string[]): boolean {
|
||||
const matchers = globs.map(g => new Minimatch(g));
|
||||
core.debug(` checking "any" patterns`);
|
||||
for (const changedFile of changedFiles) {
|
||||
if (isMatch(changedFile, matchers)) {
|
||||
core.debug(` "any" patterns matched against ${changedFile}`);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
core.debug(` "any" patterns did not match any files`);
|
||||
return false;
|
||||
}
|
||||
|
||||
// equivalent to "Array.every()" but expanded for debugging and clarity
|
||||
export function checkAll(changedFiles: string[], globs: string[]): boolean {
|
||||
const matchers = globs.map(g => new Minimatch(g));
|
||||
core.debug(` checking "all" patterns`);
|
||||
for (const changedFile of changedFiles) {
|
||||
if (!isMatch(changedFile, matchers)) {
|
||||
core.debug(` "all" patterns did not match against ${changedFile}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
core.debug(` "all" patterns matched all files`);
|
||||
return true;
|
||||
}
|
||||
127
src/labeler.ts
127
src/labeler.ts
@@ -1,17 +1,16 @@
|
||||
import * as core from '@actions/core';
|
||||
import * as github from '@actions/github';
|
||||
import * as yaml from 'js-yaml';
|
||||
import {Minimatch} from 'minimatch';
|
||||
|
||||
import {
|
||||
ChangedFilesMatchConfig,
|
||||
getChangedFiles,
|
||||
toChangedFilesMatchConfig,
|
||||
checkAny,
|
||||
checkAll
|
||||
} from './changedFiles';
|
||||
import {checkBranch, toBranchMatchConfig, BranchMatchConfig} from './branch';
|
||||
|
||||
interface ChangedFilesMatchConfig {
|
||||
changedFiles?: {
|
||||
all?: string[];
|
||||
any?: string[];
|
||||
};
|
||||
}
|
||||
|
||||
export type MatchConfig = ChangedFilesMatchConfig & BranchMatchConfig;
|
||||
|
||||
type ClientType = ReturnType<typeof github.getOctokit>;
|
||||
@@ -76,27 +75,6 @@ function getPrNumber(): number | undefined {
|
||||
return pullRequest.number;
|
||||
}
|
||||
|
||||
async function getChangedFiles(
|
||||
client: ClientType,
|
||||
prNumber: number
|
||||
): Promise<string[]> {
|
||||
const listFilesOptions = client.rest.pulls.listFiles.endpoint.merge({
|
||||
owner: github.context.repo.owner,
|
||||
repo: github.context.repo.repo,
|
||||
pull_number: prNumber
|
||||
});
|
||||
|
||||
const listFilesResponse = await client.paginate(listFilesOptions);
|
||||
const changedFiles = listFilesResponse.map((f: any) => f.filename);
|
||||
|
||||
core.debug('found changed files:');
|
||||
for (const file of changedFiles) {
|
||||
core.debug(' ' + file);
|
||||
}
|
||||
|
||||
return changedFiles;
|
||||
}
|
||||
|
||||
async function getMatchConfigs(
|
||||
client: ClientType,
|
||||
configurationPath: string
|
||||
@@ -148,49 +126,6 @@ function getLabelConfigMapFromObject(
|
||||
return labelMap;
|
||||
}
|
||||
|
||||
function toChangedFilesMatchConfig(config: any): ChangedFilesMatchConfig {
|
||||
if (!config['changed-files']) {
|
||||
return {};
|
||||
}
|
||||
const changedFilesConfig = config['changed-files'];
|
||||
|
||||
// If the value provided is a string or an array of strings then default to `any` matching
|
||||
if (typeof changedFilesConfig === 'string') {
|
||||
return {
|
||||
changedFiles: {
|
||||
any: [changedFilesConfig]
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const changedFilesMatchConfig = {
|
||||
changedFiles: {}
|
||||
};
|
||||
|
||||
if (Array.isArray(changedFilesConfig)) {
|
||||
if (changedFilesConfig.every(entry => typeof entry === 'string')) {
|
||||
changedFilesMatchConfig.changedFiles = {
|
||||
any: changedFilesConfig
|
||||
};
|
||||
} else {
|
||||
// If it is not an array of strings then it should be array of further config options
|
||||
// so assign them to our `changedFilesMatchConfig`
|
||||
Object.assign(
|
||||
changedFilesMatchConfig.changedFiles,
|
||||
...changedFilesConfig
|
||||
);
|
||||
Object.keys(changedFilesMatchConfig.changedFiles).forEach(key => {
|
||||
const value = changedFilesMatchConfig.changedFiles[key];
|
||||
changedFilesMatchConfig.changedFiles[key] = Array.isArray(value)
|
||||
? value
|
||||
: [value];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return changedFilesMatchConfig;
|
||||
}
|
||||
|
||||
function toMatchConfig(config: MatchConfig): MatchConfig {
|
||||
const changedFilesConfig = toChangedFilesMatchConfig(config);
|
||||
const branchConfig = toBranchMatchConfig(config);
|
||||
@@ -201,10 +136,6 @@ function toMatchConfig(config: MatchConfig): MatchConfig {
|
||||
};
|
||||
}
|
||||
|
||||
function printPattern(matcher: Minimatch): string {
|
||||
return (matcher.negate ? '!' : '') + matcher.pattern;
|
||||
}
|
||||
|
||||
export function checkMatchConfigs(
|
||||
changedFiles: string[],
|
||||
matchConfigs: MatchConfig[]
|
||||
@@ -219,50 +150,6 @@ export function checkMatchConfigs(
|
||||
return true;
|
||||
}
|
||||
|
||||
function isMatch(changedFile: string, matchers: Minimatch[]): boolean {
|
||||
core.debug(` matching patterns against file ${changedFile}`);
|
||||
for (const matcher of matchers) {
|
||||
core.debug(` - ${printPattern(matcher)}`);
|
||||
if (!matcher.match(changedFile)) {
|
||||
core.debug(` ${printPattern(matcher)} did not match`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
core.debug(` all patterns matched`);
|
||||
return true;
|
||||
}
|
||||
|
||||
// equivalent to "Array.some()" but expanded for debugging and clarity
|
||||
function checkAny(changedFiles: string[], globs: string[]): boolean {
|
||||
const matchers = globs.map(g => new Minimatch(g));
|
||||
core.debug(` checking "any" patterns`);
|
||||
for (const changedFile of changedFiles) {
|
||||
if (isMatch(changedFile, matchers)) {
|
||||
core.debug(` "any" patterns matched against ${changedFile}`);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
core.debug(` "any" patterns did not match any files`);
|
||||
return false;
|
||||
}
|
||||
|
||||
// equivalent to "Array.every()" but expanded for debugging and clarity
|
||||
function checkAll(changedFiles: string[], globs: string[]): boolean {
|
||||
const matchers = globs.map(g => new Minimatch(g));
|
||||
core.debug(` checking "all" patterns`);
|
||||
for (const changedFile of changedFiles) {
|
||||
if (!isMatch(changedFile, matchers)) {
|
||||
core.debug(` "all" patterns did not match against ${changedFile}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
core.debug(` "all" patterns matched all files`);
|
||||
return true;
|
||||
}
|
||||
|
||||
function checkMatch(changedFiles: string[], matchConfig: MatchConfig): boolean {
|
||||
if (matchConfig.changedFiles?.all) {
|
||||
if (!checkAll(changedFiles, matchConfig.changedFiles.all)) {
|
||||
|
||||
Reference in New Issue
Block a user