Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions src/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -297,12 +297,16 @@ export class Parser {
let index = 0;
if (expandVariables) {
for (const line of fileSplit) {
interactiveMatch = interactiveMatch ?? /#\s?@\s?[Ii]nteractive/.exec(line);
injectSSHAgent = injectSSHAgent ?? /#\s?@\s?[Ii]njectSSHAgent/.exec(line);
noArtifactsToSourceMatch = noArtifactsToSourceMatch ?? /#\s?@\s?NoArtifactsToSource/i.exec(line);
descriptionMatch = descriptionMatch ?? /#\s?@\s?[Dd]escription (?<description>.*)/.exec(line);
if (/^\s*#/.test(line)) {
interactiveMatch = interactiveMatch ?? /#\s?@\s?[Ii]nteractive/.exec(line);
injectSSHAgent = injectSSHAgent ?? /#\s?@\s?[Ii]njectSSHAgent/.exec(line);
noArtifactsToSourceMatch = noArtifactsToSourceMatch ?? /#\s?@\s?NoArtifactsToSource/i.exec(line);
descriptionMatch = descriptionMatch ?? /#\s?@\s?[Dd]escription (?<description>.*)/.exec(line);
index++;
continue;
}

const jobMatch = /\w:/.exec(line);
const jobMatch = /^[^\s#].*:/.exec(line);
if (jobMatch && (interactiveMatch || descriptionMatch || injectSSHAgent || noArtifactsToSourceMatch)) {
if (interactiveMatch) {
fileSplitClone.splice(index + 1, 0, " gclInteractive: true");
Expand All @@ -317,7 +321,7 @@ export class Parser {
index++;
}
if (descriptionMatch) {
fileSplitClone.splice(index + 1, 0, ` gclDescription: ${descriptionMatch?.groups?.description ?? ""}`);
fileSplitClone.splice(index + 1, 0, ` gclDescription: ${JSON.stringify(descriptionMatch?.groups?.description ?? "")}`);
index++;
}
interactiveMatch = null;
Expand Down
37 changes: 37 additions & 0 deletions tests/test-cases/comment-directive-anchor/.gitlab-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
# @Description Runs first
firstjob:
script:
- echo "first"

# @Description Upload source maps. Opt in per brand:
# sourcemaps:
# extends: [.foo]
sourcemaps:
script:
- echo "sourcemaps"

# @Description Deploys everything
deploy to prod:
script:
- echo "deploy"

# @Description Builds the image
build/image:
script:
- echo "build"

# @Description Quoted with a colon: and "quotes"
"quoted job":
script:
- echo "quoted"

# @Description Single quoted job
'single quoted':
script:
- echo "single"

# @Description Runs the tests
plainjob:
script:
- echo "test"
32 changes: 32 additions & 0 deletions tests/test-cases/comment-directive-anchor/integration.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import {WriteStreamsMock} from "../../../src/write-streams.js";
import {handler} from "../../../src/handler.js";
import {initSpawnSpy} from "../../mocks/utils.mock.js";
import {WhenStatics} from "../../mocks/when-statics.js";

beforeAll(() => {
initSpawnSpy(WhenStatics.all);
});

test.concurrent("comment-directive-anchor --list", async () => {
const writeStreams = new WriteStreamsMock();
await handler({
cwd: "tests/test-cases/comment-directive-anchor/",
list: true,
noColor: true,
stateDir: ".gitlab-ci-local-comment-directive-anchor",
}, writeStreams);

const descriptionOf = (jobName: string) => {
const line = writeStreams.stdoutLines.find(l => l.startsWith(`${jobName} `));
expect(line, `no output line for job ${jobName}`).toBeDefined();
return line!.slice(jobName.length).trimStart().replace(/\s{2,}.*$/, "");
};

expect(descriptionOf("firstjob")).toBe("Runs first");
expect(descriptionOf("sourcemaps")).toBe("Upload source maps. Opt in per brand:");
expect(descriptionOf("deploy to prod")).toBe("Deploys everything");
expect(descriptionOf("build/image")).toBe("Builds the image");
expect(descriptionOf("quoted job")).toBe("Quoted with a colon: and \"quotes\"");
expect(descriptionOf("single quoted")).toBe("Single quoted job");
expect(descriptionOf("plainjob")).toBe("Runs the tests");
});