Skip to content

Commit 5b3261b

Browse files
committed
Enforce that only compatible kinds can be enabled concurrently
1 parent 9267d8d commit 5b3261b

File tree

3 files changed

+80
-6
lines changed

3 files changed

+80
-6
lines changed

lib/init-action.js

Lines changed: 19 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/analyses.test.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import * as sinon from "sinon";
44
import * as actionsUtil from "./actions-util";
55
import {
66
AnalysisKind,
7+
compatibilityMatrix,
78
getAnalysisKinds,
89
parseAnalysisKinds,
910
supportedAnalysisKinds,
@@ -67,3 +68,36 @@ test("getAnalysisKinds - throws if `analysis-kinds` input is invalid", async (t)
6768
requiredInputStub.withArgs("analysis-kinds").returns("no-such-thing");
6869
await t.throwsAsync(getAnalysisKinds(getRunnerLogger(true), true));
6970
});
71+
72+
// Test the compatibility matrix by looping through all analysis kinds.
73+
const analysisKinds = Object.values(AnalysisKind);
74+
for (let i = 0; i < analysisKinds.length; i++) {
75+
const analysisKind = analysisKinds[i];
76+
77+
for (let j = i + 1; j < analysisKinds.length; j++) {
78+
const otherAnalysis = analysisKinds[j];
79+
80+
if (analysisKind === otherAnalysis) continue;
81+
if (compatibilityMatrix[analysisKind].has(otherAnalysis)) {
82+
test(`getAnalysisKinds - allows ${analysisKind} with ${otherAnalysis}`, async (t) => {
83+
const requiredInputStub = sinon.stub(actionsUtil, "getRequiredInput");
84+
requiredInputStub
85+
.withArgs("analysis-kinds")
86+
.returns([analysisKind, otherAnalysis].join(","));
87+
const result = await getAnalysisKinds(getRunnerLogger(true), true);
88+
t.is(result.length, 2);
89+
});
90+
} else {
91+
test(`getAnalysisKinds - throws if ${analysisKind} is enabled with ${otherAnalysis}`, async (t) => {
92+
const requiredInputStub = sinon.stub(actionsUtil, "getRequiredInput");
93+
requiredInputStub
94+
.withArgs("analysis-kinds")
95+
.returns([analysisKind, otherAnalysis].join(","));
96+
await t.throwsAsync(getAnalysisKinds(getRunnerLogger(true), true), {
97+
instanceOf: ConfigurationError,
98+
message: `${otherAnalysis} cannot be enabled at the same time as ${analysisKind}`,
99+
});
100+
});
101+
}
102+
}
103+
}

src/analyses.ts

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,15 @@ export enum AnalysisKind {
1212
CSRA = "csra",
1313
}
1414

15+
export type CompatibilityMatrix = Record<AnalysisKind, Set<AnalysisKind>>;
16+
17+
/** A mapping from analysis kinds to other analysis kinds which can be enabled concurrently. */
18+
export const compatibilityMatrix: CompatibilityMatrix = {
19+
[AnalysisKind.CodeScanning]: new Set([AnalysisKind.CodeQuality]),
20+
[AnalysisKind.CodeQuality]: new Set([AnalysisKind.CodeScanning]),
21+
[AnalysisKind.CSRA]: new Set(),
22+
};
23+
1524
// Exported for testing. A set of all known analysis kinds.
1625
export const supportedAnalysisKinds = new Set(Object.values(AnalysisKind));
1726

@@ -68,7 +77,7 @@ export async function getAnalysisKinds(
6877
return cachedAnalysisKinds;
6978
}
7079

71-
cachedAnalysisKinds = await parseAnalysisKinds(
80+
const analysisKinds = await parseAnalysisKinds(
7281
getRequiredInput("analysis-kinds"),
7382
);
7483

@@ -86,12 +95,27 @@ export async function getAnalysisKinds(
8695
// if an input to `quality-queries` was specified. We should remove this once
8796
// `quality-queries` is no longer used.
8897
if (
89-
!cachedAnalysisKinds.includes(AnalysisKind.CodeQuality) &&
98+
!analysisKinds.includes(AnalysisKind.CodeQuality) &&
9099
qualityQueriesInput !== undefined
91100
) {
92-
cachedAnalysisKinds.push(AnalysisKind.CodeQuality);
101+
analysisKinds.push(AnalysisKind.CodeQuality);
102+
}
103+
104+
// Check that all enabled analysis kinds are compatible with each other.
105+
for (const analysisKind of analysisKinds) {
106+
for (const otherAnalysisKind of analysisKinds) {
107+
if (analysisKind === otherAnalysisKind) continue;
108+
109+
if (!compatibilityMatrix[analysisKind].has(otherAnalysisKind)) {
110+
throw new ConfigurationError(
111+
`${otherAnalysisKind} cannot be enabled at the same time as ${analysisKind}`,
112+
);
113+
}
114+
}
93115
}
94116

117+
// Cache the analysis kinds and return them.
118+
cachedAnalysisKinds = analysisKinds;
95119
return cachedAnalysisKinds;
96120
}
97121

0 commit comments

Comments
 (0)