eslint-plugin-github-action
Version:
Rules for consistent, readable and valid GitHub action files.
425 lines (362 loc) • 11.6 kB
text/typescript
import * as eslint from 'eslint';
import { Rule, Linter } from 'eslint';
import { JSONSchema4 } from 'json-schema';
import { AST } from 'yaml-eslint-parser';
interface SourceCode {
ast: AST.YAMLProgram
hasBOM: boolean
lines: string[]
text: string
commentsExistBetween(left: YAMLNodeOrToken, right: YAMLNodeOrToken): boolean
getAllComments(): AST.Comment[]
getCommentsAfter(nodeOrToken: YAMLNodeOrToken): AST.Comment[]
getCommentsBefore(nodeOrToken: YAMLNodeOrToken): AST.Comment[]
getCommentsInside(node: AST.YAMLNode): AST.Comment[]
getFirstToken(node: AST.YAMLNode): AST.Token
getIndexFromLoc(loc: AST.Position): number
getLastToken(node: AST.YAMLNode): AST.Token
getLines(): string[]
getLocFromIndex(index: number): AST.Position
// Inherited methods from TokenStore
// ---------------------------------
getNodeByRangeIndex(index: number): AST.YAMLNode | null
getTokenAfter(node: YAMLNodeOrToken): AST.Token | null
getTokenBefore(node: YAMLNodeOrToken): AST.Token | null
isSpaceBetweenTokens(first: YAMLToken, second: YAMLToken): boolean
visitorKeys: {
[nodeType: string]: string[]
}
parserServices?: {
isYAML?: true
parseError?: any
}
getComments(node: YAMLNodeOrToken): {
leading: AST.Comment[]
trailing: AST.Comment[]
}
getFirstToken(
node: AST.YAMLNode,
options?: CursorWithSkipOptions,
): YAMLToken | null
getFirstTokenBetween(
left: YAMLNodeOrToken,
right: YAMLNodeOrToken,
options?: CursorWithSkipOptions,
): YAMLToken | null
getFirstTokens(
node: AST.YAMLNode,
options?: CursorWithCountOptions,
): YAMLToken[]
getFirstTokensBetween(
left: YAMLNodeOrToken,
right: YAMLNodeOrToken,
options?: CursorWithCountOptions,
): YAMLToken[]
getLastToken(
node: AST.YAMLNode,
options?: CursorWithSkipOptions,
): YAMLToken | null
getLastTokenBetween(
left: YAMLNodeOrToken,
right: YAMLNodeOrToken,
options?: CursorWithSkipOptions,
): YAMLToken | null
getLastTokens(
node: AST.YAMLNode,
options?: CursorWithCountOptions,
): YAMLToken[]
getLastTokensBetween(
left: YAMLNodeOrToken,
right: YAMLNodeOrToken,
options?: CursorWithCountOptions,
): YAMLToken[]
getText(
node?: YAMLNodeOrToken,
beforeCount?: number,
afterCount?: number,
): string
getTokenAfter(
node: YAMLNodeOrToken,
options?: CursorWithSkipOptions,
): YAMLToken | null
getTokenBefore(
node: YAMLNodeOrToken,
options?: CursorWithSkipOptions,
): YAMLToken | null
getTokenByRangeStart(
offset: number,
options?: { includeComments?: boolean },
): YAMLToken | null
getTokens(
node: AST.YAMLNode,
beforeCount?: number,
afterCount?: number,
): YAMLToken[]
getTokens(
node: AST.YAMLNode,
options: CursorWithCountOptions | FilterPredicate,
): YAMLToken[]
getTokensAfter(
node: YAMLNodeOrToken,
options?: CursorWithCountOptions,
): YAMLToken[]
getTokensBefore(
node: YAMLNodeOrToken,
options?: CursorWithCountOptions,
): YAMLToken[]
getTokensBetween(
left: YAMLNodeOrToken,
right: YAMLNodeOrToken,
padding?: number | CursorWithCountOptions | FilterPredicate,
): YAMLToken[]
}
type CursorWithCountOptions =
| number
| FilterPredicate
| {
count?: number
filter?: FilterPredicate
includeComments?: boolean
}
type CursorWithSkipOptions =
| number
| FilterPredicate
| {
filter?: FilterPredicate
includeComments?: boolean
skip?: number
}
type FilterPredicate = (tokenOrComment: YAMLToken) => boolean
type YAMLNodeOrToken = AST.Token | AST.YAMLNode
type YAMLToken = AST.Comment | AST.Token
/**
* @file YAML ESLint types
*/
type ReportDescriptor<TMessageIds extends string> =
ReportDescriptorWithSuggestion<TMessageIds>
& (ReportDescriptorLocOnly | ReportDescriptorNodeOptionalLoc)
type ReportDescriptorBase<TMessageIds extends string> = {
readonly messageId: TMessageIds
readonly data?: ReportDescriptorMessageData
readonly fix?: Rule.ReportFixer
}
type ReportDescriptorLocOnly = {
loc: Readonly<AST.Position> | Readonly<AST.SourceLocation>
}
type ReportDescriptorMessageData = Readonly<Record<string, unknown>>
type ReportDescriptorNodeOptionalLoc = {
readonly node: AST.YAMLNode
readonly loc?: Readonly<AST.Position> | Readonly<AST.SourceLocation>
}
interface ReportDescriptorWithSuggestion<TMessageIds extends string>
extends ReportDescriptorBase<TMessageIds> {
readonly suggest?: readonly Rule.SuggestionReportDescriptor[]
}
interface RuleContext<
TMessageIds extends string,
TOptions extends readonly unknown[] = [],
> {
id: string
options: TOptions
parserPath: string
settings: { yml?: YMLSettings; [name: string]: any }
getAncestors(): AST.YAMLNode[]
getFilename(): string
getSourceCode(): SourceCode
report(descriptor: ReportDescriptor<TMessageIds>): void
parserServices?: {
isYAML?: true
parseError?: any
}
}
interface RuleListener {
Program?: (node: AST.YAMLProgram) => void
'Program:exit'?: (node: AST.YAMLProgram) => void
YAMLAlias?: (node: AST.YAMLAlias) => void
'YAMLAlias:exit'?: (node: AST.YAMLAlias) => void
YAMLAnchor?: (node: AST.YAMLAnchor) => void
'YAMLAnchor:exit'?: (node: AST.YAMLAnchor) => void
YAMLDirective?: (node: AST.YAMLDirective) => void
'YAMLDirective:exit'?: (node: AST.YAMLDirective) => void
YAMLDocument?: (node: AST.YAMLDocument) => void
'YAMLDocument:exit'?: (node: AST.YAMLDocument) => void
YAMLMapping?: (node: AST.YAMLMapping) => void
'YAMLMapping:exit'?: (node: AST.YAMLMapping) => void
YAMLPair?: (node: AST.YAMLPair) => void
'YAMLPair:exit'?: (node: AST.YAMLPair) => void
YAMLScalar?: (node: AST.YAMLScalar) => void
'YAMLScalar:exit'?: (node: AST.YAMLScalar) => void
YAMLSequence?: (node: AST.YAMLSequence) => void
'YAMLSequence:exit'?: (node: AST.YAMLSequence) => void
YAMLTag?: (node: AST.YAMLTag) => void
'YAMLTag:exit'?: (node: AST.YAMLTag) => void
YAMLWithMeta?: (node: AST.YAMLWithMeta) => void
'YAMLWithMeta:exit'?: (node: AST.YAMLWithMeta) => void
[key: string]: ((node: never) => void) | undefined
}
interface RuleMetaData<
TMessageIds extends string,
TDocs = unknown,
TOptions extends readonly unknown[] = [],
> {
messages: Record<TMessageIds, string>
schema: JSONSchema4 | readonly JSONSchema4[]
type: 'layout' | 'problem' | 'suggestion'
defaultOptions?: TOptions
deprecated?: boolean
docs?: RuleMetaDataDocs & TDocs
fixable?: 'code' | 'whitespace'
hasSuggestions?: boolean
replacedBy?: readonly string[]
}
interface RuleMetaDataDocs {
description: string
category?: string
recommended?: boolean
url?: string
}
interface RuleModule<
TMessageIds extends string,
TOptions extends readonly unknown[] = [],
TDocs = unknown,
> {
defaultOptions: TOptions
meta?: RuleMetaData<TMessageIds, TDocs, TOptions>
create(context: RuleContext<TMessageIds, TOptions>): RuleListener
}
type YMLSettings = { indent?: number }
type TimeoutMinutesRange = {
min?: number;
max?: number;
};
type MessageIds$7 = 'notInteger' | 'invalidRange';
type Options$5 = [
number | TimeoutMinutesRange | {
job?: number | TimeoutMinutesRange;
step?: number | TimeoutMinutesRange;
}
];
type MessageIds$6 = 'invalidEvent' | 'invalidPair';
type MessageIds$5 = 'noName' | 'invalidName';
type MessageIds$4 = 'noName' | 'invalidName';
type MessageIds$3 = 'noName' | 'invalidName';
type MessageIds$2 = 'noName' | 'invalidName';
declare const UsesStyle: {
readonly commit: "commit";
readonly release: "release";
readonly branch: "branch";
};
type AllowedUsesStyle = keyof typeof UsesStyle;
type MessageIds$1 = 'invalidStyle' | 'disallowRepository' | 'disallowDocker' | 'disallowStyle';
type Options$4 = [
AllowedUsesStyle | ({
[key in AllowedUsesStyle]?: boolean;
} & {
/**
* Ignore patterns
*/
ignores?: string[];
/**
* Allow using an action inside the repository.
*
* @default false
*/
allowRepository?: boolean;
/**
* Allow using an action from:
* - Docker Hub action
* - GitHub Packages Container registry.
* - Docker public registry action
*
* @default false
*/
allowDocker?: boolean;
})
];
/**
* @copyright https://github.com/ota-meshi/eslint-plugin-yml
* @license MIT {@link https://github.com/ota-meshi/eslint-plugin-yml/blob/master/LICENSE}
*/
declare const actionExtension: {
readonly yml: "yml";
readonly yaml: "yaml";
};
type AvailableExtension = keyof typeof actionExtension;
type Options$3 = [
AvailableExtension | {
extension?: AvailableExtension;
caseSensitive?: boolean;
}
];
type MessageIds = 'invalidTopLevelKey' | 'invalidJobKey' | 'invalidStepKey' | 'invalidServiceKey' | 'invalidStrategyKey' | 'invalidContainerKey';
type Options$2 = [number];
type CasingKind = 'camelCase' | 'kebab-case' | 'PascalCase' | 'snake_case' | 'Title Case' | 'Train-Case' | 'SCREAMING_SNAKE_CASE';
type AllowedCasing$1 = Exclude<CasingKind, 'Title Case'>;
type Options$1 = [
AllowedCasing$1 | ({
[key in AllowedCasing$1]?: boolean;
} & {
ignores?: string[];
})
];
type AllowedCasing = CasingKind;
type Options = [
AllowedCasing | ({
[key in AllowedCasing]?: boolean;
} & {
ignores?: string[];
})
];
declare const rules: {
'action-name-casing': RuleModule<"actionNameNotMatch", Options, unknown>;
'job-id-casing': RuleModule<"jobIdNotMatch", Options$1, unknown>;
'max-jobs-per-action': RuleModule<"toManyJobs", Options$2, unknown>;
'no-external-job': RuleModule<"disallowExternalJob", [], unknown>;
'no-invalid-key': RuleModule<MessageIds, [], unknown>;
'no-top-level-env': RuleModule<"disallowTopLevelEnv", [], unknown>;
'no-top-level-permissions': RuleModule<"disallowTopLevelPermissions", [], unknown>;
'prefer-file-extension': RuleModule<"unexpected", Options$3, unknown>;
'prefer-step-uses-style': RuleModule<MessageIds$1, Options$4, unknown>;
'require-action-name': RuleModule<MessageIds$2, [], unknown>;
'require-action-run-name': RuleModule<MessageIds$3, [], unknown>;
'require-job-name': RuleModule<MessageIds$4, [], unknown>;
'require-job-step-name': RuleModule<MessageIds$5, [], unknown>;
'valid-trigger-events': RuleModule<MessageIds$6, [], unknown>;
'valid-timeout-minutes': RuleModule<MessageIds$7, Options$5, unknown>;
};
type RuleDefinitions = typeof rules;
type RuleOptions = {
[K in keyof RuleDefinitions]: RuleDefinitions[K]['defaultOptions'];
};
type Rules = {
[K in keyof RuleOptions]: Linter.RuleEntry<RuleOptions[K]>;
};
declare const meta: {
name: string;
version: string;
};
/**
* recommended config
*/
declare const recommended: Linter.Config[];
declare const configs: {
recommended: Linter.Config<Linter.RulesRecord>[];
};
/**
* eslint-plugin-github-action
* Rules for consistent, readable and valid GitHub action files.
*
* @see {@link https://github.com/ntnyq/eslint-plugin-github-action}
*/
declare const plugin: {
meta: {
name: string;
version: string;
};
rules: Record<string, Rule.RuleModule>;
configs: {
recommended: eslint.Linter.Config<eslint.Linter.RulesRecord>[];
};
};
export { configs, plugin as default, meta, plugin, recommended, rules };
export type { RuleOptions, Rules };