Skip to content
Open
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
5 changes: 5 additions & 0 deletions src/argv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export function injectGclVariableEnvVars (argv: {variable?: string[]; [key: stri
export class Argv {
static readonly default = {
"variablesFile": ".gitlab-ci-local-variables.yml",
"ignoresFile": ".gitlab-ci-local-ignores",
"inputsFile": ".gitlab-ci-local-inputs.yml",
"evaluateRuleChanges": true,
"ignoreSchemaPaths": [] as string[],
Expand Down Expand Up @@ -170,6 +171,10 @@ export class Argv {
return this.map.get("inputsFile") ?? Argv.default.inputsFile;
}

get ignoresFile (): string {
return this.map.get("ignoresFile") ?? Argv.default.ignoresFile;
}

get evaluateRuleChanges (): boolean {
return this.map.get("evaluateRuleChanges") ?? Argv.default.evaluateRuleChanges;
}
Expand Down
6 changes: 3 additions & 3 deletions src/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export async function handler (args: any, writeStreams: WriteStreams, jobs: Job[
pipelineIid = await state.getPipelineIid(cwd, stateDir);
}
parser = await Parser.create(argv, writeStreams, pipelineIid, jobs);
await Utils.rsyncTrackedFiles(cwd, stateDir, ".docker");
await Utils.rsyncTrackedFiles(cwd, stateDir, path.resolve(cwd, argv.ignoresFile), ".docker");
await Commander.runJobs(argv, parser, writeStreams);
if (argv.needs || argv.onlyNeeds) {
writeStreams.stderr(chalk`{grey pipeline finished} in {grey ${prettyHrtime(process.hrtime(time))}}\n`);
Expand All @@ -94,7 +94,7 @@ export async function handler (args: any, writeStreams: WriteStreams, jobs: Job[
const time = process.hrtime();
const pipelineIid = await state.getPipelineIid(cwd, stateDir);
parser = await Parser.create(argv, writeStreams, pipelineIid, jobs);
await Utils.rsyncTrackedFiles(cwd, stateDir, ".docker");
await Utils.rsyncTrackedFiles(cwd, stateDir, path.resolve(cwd, argv.ignoresFile), ".docker");
await Commander.runJobsInStage(argv, parser, writeStreams);
writeStreams.stderr(chalk`{grey pipeline finished} in {grey ${prettyHrtime(process.hrtime(time))}}\n`);
} else {
Expand All @@ -105,7 +105,7 @@ export async function handler (args: any, writeStreams: WriteStreams, jobs: Job[
const time = process.hrtime();
const pipelineIid = await state.incrementPipelineIid(cwd, stateDir);
parser = await Parser.create(argv, writeStreams, pipelineIid, jobs);
await Utils.rsyncTrackedFiles(cwd, stateDir, ".docker");
await Utils.rsyncTrackedFiles(cwd, stateDir, path.resolve(cwd, argv.ignoresFile), ".docker");
await Commander.runPipeline(argv, parser, writeStreams);
if (childPipelineDepth == 0) writeStreams.stderr(chalk`{grey pipeline finished} in {grey ${prettyHrtime(process.hrtime(time))}}\n`);
}
Expand Down
6 changes: 6 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,12 @@ process.on("SIGUSR2", async () => {
requiresArg: true,
default: Argv.default.inputsFile,
})
.option("ignores-file", {
type: "string",
description: "Path to an ignores file",
requiresArg: true,
default: Argv.default.ignoresFile,
})
.option("completion", {
type: "boolean",
description: "Generate tab completion script",
Expand Down
2 changes: 1 addition & 1 deletion src/job.ts
Original file line number Diff line number Diff line change
Expand Up @@ -920,7 +920,7 @@ If you know what you're doing and would like to suppress this warning, use one o

// Copy git tracked files to build folder if shell isolation enabled.
if (!imageName && this.argv.shellIsolation) {
await Utils.rsyncTrackedFiles(cwd, stateDir, `${safeJobName}`);
await Utils.rsyncTrackedFiles(cwd, stateDir, path.resolve(cwd, this.argv.ignoresFile), `${safeJobName}`);
}

if (this.interactive) {
Expand Down
13 changes: 11 additions & 2 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -378,10 +378,19 @@ export class Utils {
return !relative.startsWith("..");
}

static async rsyncTrackedFiles (cwd: string, stateDir: string, target: string): Promise<{hrdeltatime: [number, number]}> {
static async rsyncTrackedFiles (cwd: string, stateDir: string, ignoresFile: string, target: string): Promise<{hrdeltatime: [number, number]}> {
const time = process.hrtime();
await fs.mkdirp(`${cwd}/${stateDir}/builds/${target}`);
await Utils.bash(`rsync -a --delete-excluded --delete --exclude-from=<(git ls-files -o --directory | awk '{print "/"$0}') --exclude ${stateDir}/ ./ ${stateDir}/builds/${target}/`, cwd);
const cmd = [
"rsync -a --delete-excluded --delete",
"--exclude-from=<(git ls-files -o --directory | awk '{print \"/\"$0}')",
...await fs.pathExists(ignoresFile) ? [`--exclude-from=${Utils.safeBashString(ignoresFile)}`] : [],
"--exclude .git/lfs",
`--exclude ${stateDir}/`,
"./",
`${stateDir}/builds/${target}/`,
].join(" ");
await Utils.bash(cmd, cwd);
return {hrdeltatime: process.hrtime(time)};
}

Expand Down
5 changes: 5 additions & 0 deletions tests/test-cases/project-ignores-file/.gitlab-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
test-job:
script:
- find . -type f
- find $STATE_DIR -type f -name '*.txt' -print | wc -l
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*-big-*
34 changes: 34 additions & 0 deletions tests/test-cases/project-ignores-file/integration.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import {WriteStreamsMock} from "../../../src/write-streams.js";
import {handler} from "../../../src/handler.js";

const cwd = "tests/test-cases/project-ignores-file";
const ignoresFile = "gitlab-ci-local-ignores-test-job";

test.concurrent("project-no-ignores-file", async () => {
const writeStreams = new WriteStreamsMock();
const stateDir = ".gitlab-ci-local-no-ignores-file";
await handler({
cwd,
job: ["test-job"],
noColor: true,
stateDir,
variable: [`STATE_DIR=${stateDir}`],
}, writeStreams);
const expected = ["test-job > 2"];
expect(writeStreams.stdoutLines).toEqual(expect.arrayContaining(expected));
});

test.concurrent("project-ignores-file", async () => {
const writeStreams = new WriteStreamsMock();
const stateDir = ".gitlab-ci-local-ignores-file";
await handler({
cwd,
job: ["test-job"],
ignoresFile,
noColor: true,
stateDir,
variable: [`STATE_DIR=${stateDir}`],
}, writeStreams);
const expected = ["test-job > 1"];
expect(writeStreams.stdoutLines).toEqual(expect.arrayContaining(expected));
});
1 change: 1 addition & 0 deletions tests/test-cases/project-ignores-file/test-big-file.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
I should be ignored
1 change: 1 addition & 0 deletions tests/test-cases/project-ignores-file/test-small-file.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
I should be rsynced