mirror of
https://github.com/actions/labeler.git
synced 2025-12-13 04:57:21 +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
|
const matchConfig: MatchConfig[] = [{changedFiles: {any: ['*.txt']}}];
|
||||||
// transformed in toMatchConfig
|
|
||||||
const matchConfig = [
|
|
||||||
{'changed-files': [{any: ['*.txt']}]}
|
|
||||||
] as unknown as MatchConfig[];
|
|
||||||
|
|
||||||
describe('checkMatchConfigs', () => {
|
describe('checkMatchConfigs', () => {
|
||||||
it('returns true when our pattern does match changed files', () => {
|
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 core from '@actions/core';
|
||||||
import * as github from '@actions/github';
|
import * as github from '@actions/github';
|
||||||
import * as yaml from 'js-yaml';
|
import * as yaml from 'js-yaml';
|
||||||
import {Minimatch} from 'minimatch';
|
|
||||||
|
|
||||||
|
import {
|
||||||
|
ChangedFilesMatchConfig,
|
||||||
|
getChangedFiles,
|
||||||
|
toChangedFilesMatchConfig,
|
||||||
|
checkAny,
|
||||||
|
checkAll
|
||||||
|
} from './changedFiles';
|
||||||
import {checkBranch, toBranchMatchConfig, BranchMatchConfig} from './branch';
|
import {checkBranch, toBranchMatchConfig, BranchMatchConfig} from './branch';
|
||||||
|
|
||||||
interface ChangedFilesMatchConfig {
|
|
||||||
changedFiles?: {
|
|
||||||
all?: string[];
|
|
||||||
any?: string[];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export type MatchConfig = ChangedFilesMatchConfig & BranchMatchConfig;
|
export type MatchConfig = ChangedFilesMatchConfig & BranchMatchConfig;
|
||||||
|
|
||||||
type ClientType = ReturnType<typeof github.getOctokit>;
|
type ClientType = ReturnType<typeof github.getOctokit>;
|
||||||
@@ -76,27 +75,6 @@ function getPrNumber(): number | undefined {
|
|||||||
return pullRequest.number;
|
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(
|
async function getMatchConfigs(
|
||||||
client: ClientType,
|
client: ClientType,
|
||||||
configurationPath: string
|
configurationPath: string
|
||||||
@@ -148,49 +126,6 @@ function getLabelConfigMapFromObject(
|
|||||||
return labelMap;
|
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 {
|
function toMatchConfig(config: MatchConfig): MatchConfig {
|
||||||
const changedFilesConfig = toChangedFilesMatchConfig(config);
|
const changedFilesConfig = toChangedFilesMatchConfig(config);
|
||||||
const branchConfig = toBranchMatchConfig(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(
|
export function checkMatchConfigs(
|
||||||
changedFiles: string[],
|
changedFiles: string[],
|
||||||
matchConfigs: MatchConfig[]
|
matchConfigs: MatchConfig[]
|
||||||
@@ -219,50 +150,6 @@ export function checkMatchConfigs(
|
|||||||
return true;
|
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 {
|
function checkMatch(changedFiles: string[], matchConfig: MatchConfig): boolean {
|
||||||
if (matchConfig.changedFiles?.all) {
|
if (matchConfig.changedFiles?.all) {
|
||||||
if (!checkAll(changedFiles, matchConfig.changedFiles.all)) {
|
if (!checkAll(changedFiles, matchConfig.changedFiles.all)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user