Skip to content
This repository has been archived by the owner on Jun 15, 2021. It is now read-only.

Commit

Permalink
feat: report errors on invalid 'uses' values (#50)
Browse files Browse the repository at this point in the history
Fixes #6
  • Loading branch information
OmarTawfik committed Mar 12, 2019
1 parent 1e0fc49 commit 2cc08f5
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 1 deletion.
51 changes: 50 additions & 1 deletion src/analysis/properties-analyzer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,54 @@

import { BoundNodeVisitor } from "../binding/bound-node-visitor";
import { DiagnosticBag } from "../util/diagnostics";
import { BoundDocument, BoundResolves, BoundSecrets, BoundOn, BoundEnv, BoundNeeds } from "../binding/bound-nodes";
import {
BoundDocument,
BoundResolves,
BoundSecrets,
BoundOn,
BoundEnv,
BoundNeeds,
BoundUses,
} from "../binding/bound-nodes";
import { MAXIMUM_SUPPORTED_SECRETS } from "../util/constants";
import * as webhooks from "@octokit/webhooks-definitions";

export function analyzeProperties(document: BoundDocument, actions: ReadonlySet<string>, bag: DiagnosticBag): void {
new PropertiesAnalyzer(document, actions, bag);
}
/*
fragment ALPHANUM : [a-zA-Z0-9];
fragment HEX : [0-9a-fA-F]+;
INTEGER : [0-9]+;
*/

module USES_REGEX {
const ALPHA_NUM = `[a-zA-Z0-9]`;
const ALPHA_NUM_DASH = `[a-zA-Z0-9-]`;

const DOCKER_HOST_COMPONENT = `(${ALPHA_NUM}|(${ALPHA_NUM}${ALPHA_NUM_DASH}*${ALPHA_NUM}))`;
const DOCKER_REGISTRY = `(${DOCKER_HOST_COMPONENT}(\\.${DOCKER_HOST_COMPONENT})*(:[0-9]+)?\\/)`;
const DOCKER_PATH_COMPONENT = `(${ALPHA_NUM}+([._-]${ALPHA_NUM}+)*)`;
const DOCKER_TAG = `(:[a-zA-Z0-9_]+)`;
const DOCKER_DIGEST_ALGORITHM = `[A-Za-z]${ALPHA_NUM}*`;
const DOCKER_DIGEST = `(@${DOCKER_DIGEST_ALGORITHM}([+.-_]${DOCKER_DIGEST_ALGORITHM})*:[a-fA-F0-9]+)`;
const DOCKER_USES = `docker:\\/\\/${DOCKER_REGISTRY}?${DOCKER_PATH_COMPONENT}(\\/${DOCKER_PATH_COMPONENT})*(${DOCKER_TAG}|${DOCKER_DIGEST})?`;

const LOCAL_USES = `\\.\\/.*`;

const REMOTE_OWNER = `${ALPHA_NUM}+(${ALPHA_NUM_DASH}${ALPHA_NUM}+)*`;
const REMOTE_REPO = `[a-zA-Z0-9-_.]+`;
const REMOTE_USES = `${REMOTE_OWNER}\\/${REMOTE_REPO}\\/.*@.+`;

const COMBINED = new RegExp(`^(${DOCKER_USES})|(${LOCAL_USES})|(${REMOTE_USES})$`);

export function test(value: string): boolean {
return COMBINED.test(value);
}
}

class PropertiesAnalyzer extends BoundNodeVisitor {
private readonly secrets = new Set<string>();
Expand Down Expand Up @@ -90,4 +131,12 @@ class PropertiesAnalyzer extends BoundNodeVisitor {
}
}
}

protected visitUses(node: BoundUses): void {
if (node.value) {
if (!USES_REGEX.test(node.value.value)) {
this.bag.invalidUses(node.value.syntax.range);
}
}
}
}
9 changes: 9 additions & 0 deletions src/util/diagnostics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export enum DiagnosticCode {
DuplicateActions,
ReservedEnvironmentVariable,
UnrecognizedEvent,
InvalidUses,
}

export interface Diagnostic {
Expand Down Expand Up @@ -253,4 +254,12 @@ export class DiagnosticBag {
message: `The event '${event}' is not a known event type.`,
});
}

public invalidUses(range: TextRange): void {
this.items.push({
range,
code: DiagnosticCode.InvalidUses,
message: `The 'uses' property must be a path, a Docker image, or an owner/repo@ref remote.`,
});
}
}
63 changes: 63 additions & 0 deletions test/properties-analysis.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,69 @@ ERROR: This property has duplicate 'b' actions.
10 | ]
11 | }
"
`);
});

it("reports an error on invalid local 'uses' value", () => {
expectDiagnostics(`
action "a" {
uses = "./ci"
}
action "b" {
uses = "ci"
}
`).toMatchInlineSnapshot(`
"
ERROR: The 'uses' property must be a path, a Docker image, or an owner/repo@ref remote.
4 | }
5 | action \\"b\\" {
6 | uses = \\"ci\\"
| ^^^^
7 | }
8 |
"
`);
});

it("reports an error on invalid remote 'uses' value", () => {
expectDiagnostics(`
action "a" {
uses = "owner/repo/path@ref"
}
action "b" {
uses = "owner/repo"
}
`).toMatchInlineSnapshot(`
"
ERROR: The 'uses' property must be a path, a Docker image, or an owner/repo@ref remote.
4 | }
5 | action \\"b\\" {
6 | uses = \\"owner/repo\\"
| ^^^^^^^^^^^^
7 | }
8 |
"
`);
});

it("reports an error on invalid docker 'uses' value", () => {
expectDiagnostics(`
action "a" {
uses = "docker://image"
}
action "b" {
uses = "docker://?"
}
`).toMatchInlineSnapshot(`
"
ERROR: The 'uses' property must be a path, a Docker image, or an owner/repo@ref remote.
4 | }
5 | action \\"b\\" {
6 | uses = \\"docker://?\\"
| ^^^^^^^^^^^^
7 | }
8 |
"
`);
});
});

0 comments on commit 2cc08f5

Please sign in to comment.