Skip to content

New optional .gitlab-ci-local-ignores file to list file to ignore to sync with jobs - #1884

Open
jrd wants to merge 1 commit into
firecow:masterfrom
jrd:ignores_file
Open

New optional .gitlab-ci-local-ignores file to list file to ignore to sync with jobs#1884
jrd wants to merge 1 commit into
firecow:masterfrom
jrd:ignores_file

Conversation

@jrd

@jrd jrd commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

The file could also be specified on command line.

Format should follow the rsync ignore format.

Also never sync the .git/lfs directory which, if it exists, is usually huge.

This pull request could replace #1883 if this solution is preferred.


Summary by cubic

Add an optional .gitlab-ci-local-ignores file and a --ignores-file flag to exclude files from rsync across pipelines, stages, and shell isolation. Always exclude .git/lfs, and safely escape the ignore file path.

  • New Features

    • Support .gitlab-ci-local-ignores using rsync ignore syntax (default path).
    • Add --ignores-file to set a custom ignore file path.
  • Bug Fixes

    • Escape the ignores file path in rsync to prevent command injection.

Written for commit dc2b57b. Summary will update on new commits.

Review in cubic

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 5 files

Re-trigger cubic

@jrd jrd mentioned this pull request Jun 22, 2026
@firecow

firecow commented Jun 22, 2026

Copy link
Copy Markdown
Owner

@jrd Can we add a test to verify and avoid future regressions?

Comment thread src/utils.ts Outdated
@jrd

jrd commented Jun 22, 2026

Copy link
Copy Markdown
Contributor Author

I’ll add a test later this day (I’m UTC+2)

@jrd

jrd commented Jun 25, 2026

Copy link
Copy Markdown
Contributor Author

@jrd Can we add a test to verify and avoid future regressions?

Done. Hope the test is good enough… (because I didn’t cover all cases)

@jrd
jrd requested a review from firecow June 30, 2026 23:53
Comment thread src/utils.ts Outdated
Comment on lines +385 to +386
`--exclude-from=<(git ls-files -o --directory | awk '{print "/"$0}')`, // eslint-disable-line @stylistic/quotes
`--exclude-from=<(cat ${Utils.safeBashString(ignoresFile)} 2>/dev/null || true)`,

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
`--exclude-from=<(git ls-files -o --directory | awk '{print "/"$0}')`, // eslint-disable-line @stylistic/quotes
`--exclude-from=<(cat ${Utils.safeBashString(ignoresFile)} 2>/dev/null || true)`,
"--exclude-from=<(git ls-files -o --directory | awk '{print \"/\"$0}')",
...await fs.pathExists(ignoresFile) ? [`--exclude-from=${Utils.safeBashString(ignoresFile)}`] : [],

Comment thread src/index.ts Outdated
})
.option("ignores-file", {
type: "string",
description: "Path to a ignores file",

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
description: "Path to a ignores file",
description: "Path to an ignores file",

Comment thread src/handler.ts Outdated
}
parser = await Parser.create(argv, writeStreams, pipelineIid, jobs);
await Utils.rsyncTrackedFiles(cwd, stateDir, ".docker");
await Utils.rsyncTrackedFiles(cwd, stateDir, `${cwd}/${argv.ignoresFile}`, ".docker");

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
await Utils.rsyncTrackedFiles(cwd, stateDir, `${cwd}/${argv.ignoresFile}`, ".docker");
await Utils.rsyncTrackedFiles(cwd, stateDir, path.resolve(cwd, argv.ignoresFile), ".docker");

Comment thread src/handler.ts Outdated
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, `${cwd}/${argv.ignoresFile}`, ".docker");

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
await Utils.rsyncTrackedFiles(cwd, stateDir, `${cwd}/${argv.ignoresFile}`, ".docker");
await Utils.rsyncTrackedFiles(cwd, stateDir, path.resolve(cwd, argv.ignoresFile), ".docker");

Comment thread src/handler.ts Outdated
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, `${cwd}/${argv.ignoresFile}`, ".docker");

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
await Utils.rsyncTrackedFiles(cwd, stateDir, `${cwd}/${argv.ignoresFile}`, ".docker");
await Utils.rsyncTrackedFiles(cwd, stateDir, path.resolve(cwd, argv.ignoresFile), ".docker");

Comment thread src/job.ts Outdated
// 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, `${cwd}/${this.argv.ignoresFile}`, `${safeJobName}`);

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
await Utils.rsyncTrackedFiles(cwd, stateDir, `${cwd}/${this.argv.ignoresFile}`, `${safeJobName}`);
await Utils.rsyncTrackedFiles(cwd, stateDir, path.resolve(cwd, this.argv.ignoresFile), `${safeJobName}`);

---
test-job:
script:
- tree -a

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- tree -a

Comment thread src/handler.ts Outdated
}
parser = await Parser.create(argv, writeStreams, pipelineIid, jobs);
await Utils.rsyncTrackedFiles(cwd, stateDir, ".docker");
await Utils.rsyncTrackedFiles(cwd, stateDir, `${cwd}/${argv.ignoresFile}`, ".docker");

@firecow firecow Jul 31, 2026

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

${cwd}/${argv.ignoresFile} breaks --ignores-file /abs/path${cwd}//abs/path. Verified: original reports test-job > 2 (exclusions silently dropped), 1 after path.resolve. The 2>/dev/null || true is what hides it; a typo'd path fails silently too.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I get it, thanks.

---
test-job:
script:
- tree -a

@firecow firecow Jul 31, 2026

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not asserted, and not installed here, so the whole test file fails locally with tree: command not found. Passes only because GitHub runners ship it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh I see, can I replace it with find ?

…o sync with jobs.

The file could also be specified on command line.

Format should follow the `rsync` ignore format.

Also never sync the `.git/lfs` directory which, if it exists, is usually
huge.
@jrd

jrd commented Aug 6, 2026

Copy link
Copy Markdown
Contributor Author

Should be good now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants