Skip to content

[#3210] Fixed DCLint and Gitleaks scanning an empty directory in CI. - #3215

Merged
AlexSkrypnyk merged 5 commits into
mainfrom
feature/3210-scan-bind-mounts
Oct 20, 2026
Merged

AlexSkrypnyk merged 5 commits into
mainfrom
feature/3210-scan-bind-mounts

Conversation

@AlexSkrypnyk

Copy link
Copy Markdown
Member

Closes #3210

Summary

The DCLint step in the lint job of .circleci/config.yml and .github/workflows/build-test-deploy.yml, and the Gitleaks step in the CircleCI audit job, now scan the checkout instead of an empty directory. On CircleCI, each step creates the scanner container with docker create --rm, copies the checkout in with docker cp ./. and runs it with docker start --attach. On GitHub Actions, the DCLint step mounts the job container's volumes with --volumes-from "${HOSTNAME}" -w "${PWD}", the same way the Gitleaks step in .github/workflows/audit.yml already does.

All 3 steps mounted the checkout with docker run -v "${PWD}":..., and the Docker engine resolves that path on its own host, where it doesn't exist. The CircleCI lint and audit jobs talk to a remote engine through setup_remote_docker, and the GitHub Actions lint job runs inside the drevops/ci-runner container, so ${PWD} is a path inside the job container while docker run goes to the runner host's daemon. In both cases the engine mounted an empty directory: Gitleaks logged scanned ~0 bytes (0) and no leaks found, and DCLint printed nothing and passed.

After merge, a committed secret or a DCLint error fails these steps on both providers, so a consumer project with existing findings will see them fail for the first time after updating. VORTEX_CI_DCLINT_IGNORE_FAILURE and VORTEX_CI_GITLEAKS_IGNORE_FAILURE still let findings through, but on CircleCI a scanner that can't start at all, such as a failed image pull, now fails the step even with the flag set. Hadolint is untouched, because it already reads each Dockerfile from stdin.

Before / After

BEFORE

  scanner step:  docker run -v "${PWD}":/app <image>
        │
        ▼
  the Docker engine resolves ${PWD} on its own host
        │   CircleCI:        the remote engine has no ~/project
        │   GitHub Actions:  the runner host has no /__w/<repo>/<repo>
        ▼
  an empty directory is mounted at /app
        │
        ▼
  DCLint prints nothing, exit 0
  Gitleaks "scanned ~0 bytes (0)", "no leaks found", exit 0
AFTER

  CircleCI                                 GitHub Actions
  ┌──────────────────────────────────┐     ┌──────────────────────────────────┐
  │ docker create --rm <image>       │     │ docker run --rm                  │
  │ docker cp ./. "${container}:..." │     │   --volumes-from "${HOSTNAME}"   │
  │ docker start --attach            │     │   -w "${PWD}" <image>            │
  └────────────────┬─────────────────┘     └────────────────┬─────────────────┘
                   │ the checkout goes                      │ the scanner gets the
                   │ through the Docker API                 │ job container's mounts
                   ▼                                        ▼
  ┌───────────────────────────────────────────────────────────────────────────┐
  │ the scanner reads the real checkout                                       │
  │ DCLint lints docker-compose.yml, Gitleaks scans the files                 │
  │ a finding fails the step unless VORTEX_CI_*_IGNORE_FAILURE is 1           │
  └───────────────────────────────────────────────────────────────────────────┘

Changes

CI steps

  • .circleci/config.yml: the DCLint step in lint and the Gitleaks step in audit create the container, copy the checkout in and start it attached, so the container's exit code is the step's. A comment above each step records that the remote engine has no access to the checkout. --rm keeps the old cleanup, and under CircleCI's bash -eo pipefail a failed docker create or docker cp fails the step; only the scan's own exit code reaches the VORTEX_CI_*_IGNORE_FAILURE check.
  • .github/workflows/build-test-deploy.yml: the DCLint step in lint uses --volumes-from "${HOSTNAME}" -w "${PWD}".
  • Running the exact step text in drevops/ci-runner the way each provider runs it (the checkout only inside the job container for CircleCI, bind-mounted into the job container for GitHub Actions): the old steps pass with DCLint silent and Gitleaks at scanned ~0 bytes (0). The new steps report the database2 finding below when the exception is removed, and on CircleCI Gitleaks scans 2.35 MB, fails on a planted token, and passes with VORTEX_CI_GITLEAKS_IGNORE_FAILURE=1 while still reporting leaks found: 1.

The database2 exception

  • docker-compose.yml: once DCLint sees the file it fails with Service "database2" is exporting port "3306" which is already used by service "database". (no-duplicate-exported-ports). DCLint 3.1.0, the latest release, reads the container-only port '3306' as a published host port, but Docker publishes each container-only port on its own random host port, so the 2 services don't clash.
  • The exception is # dclint disable-line no-duplicate-exported-ports # container-only port, published on a random host port, on its own line directly above the database2 ports: key. DCLint reports this rule on the ports: line, and an own-line disable-line applies to the next line. A trailing comment on ports: would not survive installation: when DCLint is deselected, the installer removes every line containing dclint (Tools.php) and would take the ports: key with it. The trailing reason follows the # hadolint ignore=... # reason convention of .docker/*.dockerfile.
  • Turning the rule off in .dclintrc instead would also hide real clashes, such as 2 services publishing the same fixed host port.
  • Every installer fixture variant of docker-compose.yml that ships DCLint (28 of them, including all migration variants) passes DCLint after the CI processing step, and the installed baseline passes Gitleaks.

Regression guard

  • .vortex/tests/lint.ci.sh, which runs in vortex-test-common, fails when .circleci/config.yml, .github/workflows/build-test-deploy.yml or .github/workflows/audit.yml bind-mounts ${PWD}, $PWD, $(pwd) or ${GITHUB_WORKSPACE}, and names each offending line. Every job in those files runs in a container or against a remote engine. vortex-test-common.yml stays out because its vortex-test-actions job runs on the host, where its -v "${GITHUB_WORKSPACE:-.}" mount is valid. A grep error, such as a renamed file, fails the check instead of passing it.
  • Against main, the check names the 3 steps fixed here.

Tests

  • ToolsHandlerProcessTest: the new tools_no_dclint_migration scenario enables migration and deselects DCLint, then asserts that no dclint line survives and that database2 keeps its ports: key. Moving the directive to a trailing comment on ports: makes the scenario fail.
  • Installer fixtures are regenerated: the CircleCI variants for both steps, the GitHub Actions variants for the DCLint line, the migration variants for the directive, and the new scenario.

Documentation

  • .vortex/docs/content/development/code-quality/dclint.mdx: the database2 exception, and that deselecting DCLint also removes the dclint directives in docker-compose.yml.

@github-project-automation github-project-automation Bot moved this to BACKLOG in Vortex 1.x Oct 20, 2026
@AlexSkrypnyk AlexSkrypnyk added this to the 1.42.0 milestone Oct 20, 2026
@AlexSkrypnyk AlexSkrypnyk added the A4 Board worker 4 label Oct 20, 2026
@coderabbitai

coderabbitai Bot commented Oct 20, 2026

Copy link
Copy Markdown

Warning

Review limit reached

  • Run on-demand review

This review includes 6 billable files and costs up to $1.50.

  • Ask an admin to make reviews automatic

Open in CodeRabbit

Reviews can continue after your included limit without a manual trigger. An admin must approve usage-based billing.

Or wait 26 minutes for your next included review.

Check out review usage here.

View limit details

Limit details: You’ve used all 2 included reviews currently available. Your 81 included PR review attempts over the past 7 days set your current allowance at 2 reviews per hour.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: ASSERTIVE
  • Plan: Team
  • Run ID: 182c6f65-769b-4f1b-9e27-78d39f370011
📥 Commits

Reviewing files that changed from the base of the PR and between e7af8e9 and 7252a69.

⛔ Files ignored due to path filters: 52
  • .vortex/installer/tests/Fixtures/handler_process/_baseline/.github/workflows/build-test-deploy.yml is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/ciprovider_circleci/.circleci/config.yml is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/code_coverage_provider_codecov_circleci/.circleci/config.yml is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/deploy_types_all_circleci/.circleci/config.yml is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/deploy_types_none_circleci/.circleci/config.yml is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/deps_updates_provider_ci_circleci/.circleci/config.yml is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/migration_disabled_circleci/.circleci/config.yml is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/migration_enabled/docker-compose.yml is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/migration_enabled_circleci/.circleci/config.yml is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/migration_enabled_circleci/docker-compose.yml is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/migration_enabled_lagoon/docker-compose.yml is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/migration_fetch_source_acquia/docker-compose.yml is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/migration_fetch_source_container_registry/docker-compose.yml is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/migration_fetch_source_ftp/docker-compose.yml is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/migration_fetch_source_lagoon/docker-compose.yml is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/migration_fetch_source_s3/docker-compose.yml is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/migration_fetch_source_url/docker-compose.yml is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/timezone_circleci/.circleci/config.yml is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/tools_groups_no_be_lint_circleci/.circleci/config.yml is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/tools_groups_no_be_tests_circleci/.circleci/config.yml is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/tools_groups_no_fe_lint_circleci/.circleci/config.yml is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/tools_groups_no_fe_lint_no_theme_circleci/.circleci/config.yml is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/tools_no_behat_circleci/.circleci/config.yml is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/tools_no_dclint/.github/workflows/build-test-deploy.yml is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/tools_no_dclint_circleci/.circleci/config.yml is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/tools_no_dclint_migration/-.dclintrc is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/tools_no_dclint_migration/.ahoy.yml is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/tools_no_dclint_migration/.env is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/tools_no_dclint_migration/.github/workflows/build-test-deploy.yml is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/tools_no_dclint_migration/composer.json is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/tools_no_dclint_migration/docker-compose.yml is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/tools_no_dclint_migration/scripts/provision-20-migration.sh is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/tools_no_dclint_migration/tests/phpunit/Drupal/DatabaseSettingsTest.php is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/tools_no_dclint_migration/tests/phpunit/Drupal/EnvironmentSettingsTest.php is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/tools_no_dclint_migration/tests/phpunit/Drupal/SettingsTestCase.php is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/tools_no_dclint_migration/web/modules/custom/ys_migrate/migrations/ys_migrate_categories.yml is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/tools_no_dclint_migration/web/modules/custom/ys_migrate/ys_migrate.info.yml is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/tools_no_dclint_migration/web/sites/default/settings.migration.php is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/tools_no_dclint_migration/web/sites/default/settings.php is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/tools_no_docker_linters/.github/workflows/build-test-deploy.yml is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/tools_no_docker_linters_circleci/.circleci/config.yml is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/tools_no_eslint_circleci/.circleci/config.yml is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/tools_no_hadolint/.github/workflows/build-test-deploy.yml is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/tools_no_hadolint_circleci/.circleci/config.yml is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/tools_no_jest_circleci/.circleci/config.yml is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/tools_no_phpcs_circleci/.circleci/config.yml is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/tools_no_phpstan_circleci/.circleci/config.yml is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/tools_no_phpunit_circleci/.circleci/config.yml is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/tools_no_rector_circleci/.circleci/config.yml is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/tools_no_stylelint_circleci/.circleci/config.yml is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/tools_no_twig_circleci/.circleci/config.yml is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/tools_none/.github/workflows/build-test-deploy.yml is excluded by !.vortex/installer/tests/Fixtures/**
📒 Files selected for processing: 6
  • .circleci/config.yml
  • .github/workflows/build-test-deploy.yml
  • .vortex/docs/content/development/code-quality/dclint.mdx
  • .vortex/installer/tests/Functional/Prompts/Handlers/ToolsHandlerProcessTest.php
  • .vortex/tests/lint.ci.sh
  • docker-compose.yml
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@github-actions

This comment has been minimized.

@AlexSkrypnyk

This comment has been minimized.

@github-actions

This comment has been minimized.

@AlexSkrypnyk

This comment has been minimized.

@github-actions

Copy link
Copy Markdown

Code coverage (threshold: 90%)

  Classes: 100.00% (1/1)
  Methods: 100.00% (2/2)
  Lines:   100.00% (233/233)
Per-class coverage
Drupal\ys_demo\Plugin\Block\CounterBlock
  Methods: 100.00% ( 2/ 2)   Lines: 100.00% ( 10/ 10)

@AlexSkrypnyk

Copy link
Copy Markdown
Member Author

Code coverage (threshold: 90%)

  Classes: 100.00% (1/1)
  Methods: 100.00% (2/2)
  Lines:   100.00% (233/233)
Per-class coverage
Drupal\ys_demo\Plugin\Block\CounterBlock
  Methods: 100.00% ( 2/ 2)   Lines: 100.00% ( 10/ 10)

@codecov

codecov Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.09%. Comparing base (e7af8e9) to head (7252a69).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3215      +/-   ##
==========================================
- Coverage   92.29%   92.09%   -0.20%     
==========================================
  Files         113      105       -8     
  Lines        5099     4933     -166     
  Branches       49        3      -46     
==========================================
- Hits         4706     4543     -163     
+ Misses        393      390       -3     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions

Copy link
Copy Markdown

📖 Documentation preview for this pull request has been deployed to Netlify:

https://6ad716656d56d62db3877cc1--vortex-docs.netlify.app

This preview is rebuilt on every commit and is not the production documentation site.

@AlexSkrypnyk AlexSkrypnyk added the Needs review Pull request needs a review from assigned developers label Oct 20, 2026
@AlexSkrypnyk
AlexSkrypnyk merged commit a8b2031 into main Oct 20, 2026
36 checks passed
@AlexSkrypnyk
AlexSkrypnyk deleted the feature/3210-scan-bind-mounts branch October 20, 2026 08:04
@github-project-automation github-project-automation Bot moved this from BACKLOG to Release queue in Vortex 1.x Oct 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A4 Board worker 4 Needs review Pull request needs a review from assigned developers

Projects

Status: Released in 1.42.0

Development

Successfully merging this pull request may close these issues.

Gitleaks and DCLint scan an empty directory because their bind mounts miss the checkout

1 participant