Skip to content

[#2868] Pinned Hadolint to v2.15.0 and replaced its global ignores with justified per-line ones. - #2867

Merged
AlexSkrypnyk merged 8 commits into
mainfrom
feature/hadolint-version
Jul 31, 2026
Merged

[#2868] Pinned Hadolint to v2.15.0 and replaced its global ignores with justified per-line ones.#2867
AlexSkrypnyk merged 8 commits into
mainfrom
feature/hadolint-version

Conversation

@AlexSkrypnyk

@AlexSkrypnyk AlexSkrypnyk commented Jul 30, 2026

Copy link
Copy Markdown
Member

Closes #2868

Summary

Hadolint was invoked as the untagged hadolint/hadolint, which resolves to latest on every run, while every sibling CI tool image is pinned (zavoloklom/dclint:3.1.0, ghcr.io/gitleaks/gitleaks:v8.30.1). Hadolint v2.15.0 shipped on 2026-07-30 with two new rules, so the lint job started failing without a single line of this repository changing.

This pins the image, resolves the findings the new rules raise, replaces every file-level suppression with a justified per-line one, adds a Renovate manager so the pin cannot rot, and records the check in the release skill.

Verified against both releases: v2.14.0 reports zero findings on all six Dockerfiles, v2.15.0 reported eight before this change and zero after.

Changes

Pinned the image

hadolint/hadolint becomes hadolint/hadolint:v2.15.0 in .github/workflows/build-test-deploy.yml, .circleci/config.yml, and .vortex/tests/lint.dockerfiles.sh, so both CI providers and a local run all execute the same linter.

Replaced every global ignore with a per-line one

# hadolint global ignore= suppresses a rule for a whole file, including for code added later, so a suppression added for one known line silently blesses every future violation in that file. DL3064 is a security rule - globally ignored in cli.dockerfile, a future ARG AWS_SECRET_ACCESS_KEY would pass unnoticed. All five global pragmas are gone; every remaining suppression sits on the line it applies to and carries a short reason, using hadolint's supported # hadolint ignore=RULE # reason form so each costs one line:

File Rule Applies to
cli.dockerfile DL3064 x3 PACKAGE_TOKEN, ARG/ENV DRUPAL_PRIVATE_FILES
cli.dockerfile DL3018 the apk add
cli.dockerfile SC2174 the mkdir -p -m
clamav.dockerfile DL3008 the apt-get install
clamav.dockerfile DL3066 x2 USER root, USER clamav
database.dockerfile DL3064 the MYSQL_* block
database.dockerfile DL3066 x2 USER root, USER mysql
nginx-drupal.dockerfile DL3018 the apk add
php.dockerfile DL3018 the apk add
solr.dockerfile DL3066 x2 USER root, USER solr

None of the findings is a real defect. PACKAGE_TOKEN defaults to empty and is supplied at build time via --mount=type=secret. DRUPAL_PRIVATE_FILES is a directory path matched on the substring private. The MYSQL_* values are the fixed throwaway credentials the uselagoon/mysql-8.4 image contract expects for local and CI databases, with deployed environments injecting their own. The DL3066 hits are the base images' own service accounts, referenced by name because the base images' own tooling refers to them by name. DL3018 and DL3008 cover package sets that track the pinned base image.

Removed six suppressions that suppress nothing

Linting each file with every pragma stripped shows which rules actually fire. Six did not fire at all under v2.15.0 and were deleted rather than carried forward with an invented justification:

  • SC2155 in cli.dockerfile - fires on export/local/readonly foo=$(...); that RUN uses a plain token=$(...) assignment.
  • DL3018 in clamav.dockerfile - a Debian base image with no apk.
  • DL3018 in solr.dockerfile - no package installation in the file.
  • DL3006 in database.dockerfile, nginx-drupal.dockerfile and php.dockerfile - no longer raised for an ARG-substituted FROM.

A suppression that suppresses nothing is the same blind spot as a global one: it reads as a reviewed exception when nothing is being excepted.

Tracked the pins with Renovate

Added a customManagers regex to renovate.json covering image references inside docker run commands in .circleci/config.yml and .github/workflows/*.yml. Renovate's built-in github-actions manager only parses uses:, container: and services:, and the existing custom manager is scoped to docker-compose.yml IMAGE: lines, so none of these pins was watched. Validated offline against the real files: the regex matches exactly the seven image references (hadolint, dclint and gitleaks in both providers, plus rhysd/actionlint in the test harness) and nothing else - notably not the "${PWD}":/app volume arguments or the ${VORTEX_CI_*_IGNORE_FAILURE:-0} defaults on the same lines. The CI paths were also added to the existing Container images - All package rule so these bumps group with the .docker/** ones.

Recorded the check in the release skill

.claude/skills/prepare-vortex-release/SKILL.md gains a CI tool image item under Container images. It is a verification step rather than a manual bump, since Renovate now tracks these, and it states that an untagged reference is a release blocker regardless.

Updated a test assertion

ToolsHandlerProcessTest asserted that # hadolint global ignore= survives deselecting hadolint. The intent - Dockerfile directives are inert comments that stay useful when the tool is run by hand - is unchanged; the assertion now matches the per-line form.

Regenerated fixtures

ahoy update-snapshots reports 149/149 datasets passing with no fixture drift. Fixtures store the image tag as hadolint/hadolint:__VERSION__, so future version bumps produce no fixture churn.

Screenshots

N/A

Before / After

BEFORE
                                                     
  docker run --rm -i hadolint/hadolint               
                     └─ no tag, resolves to latest   
                                                     
  upstream ships v2.15.0 with DL3064 + DL3066        
                     │                               
                     ▼                               
  8 findings appear overnight, lint job turns red    
  with zero changes in this repository               
                                                     
  5 files carry a file-wide "global ignore",         
  6 of those pragmas suppress nothing at all         
                                                     
  renovate.json watches .docker/** only,             
  so no CI tool image is tracked                     


AFTER
                                                     
  docker run --rm -i hadolint/hadolint:v2.15.0       
                     └─ pinned, same result always   
                                                     
  every suppression sits on the line it applies to   
  and states its reason in one line                  
                     │                               
                     ▼                               
  DL3064 stays active for any future ARG or ENV      
  that has not been individually justified           
                                                     
  renovate.json customManagers regex now watches     
  all 7 CI image pins across both providers          

@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 23 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 5dfbd502-8720-415a-89a0-6105de37b276

📥 Commits

Reviewing files that changed from the base of the PR and between d41596a and 7f67da4.

⛔ Files ignored due to path filters (46)
  • .vortex/installer/tests/Fixtures/handler_process/_baseline/.docker/clamav.dockerfile is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/_baseline/.docker/cli.dockerfile is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/_baseline/.docker/database.dockerfile is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/_baseline/.docker/nginx-drupal.dockerfile is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/_baseline/.docker/php.dockerfile is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/_baseline/.docker/solr.dockerfile is excluded by !.vortex/installer/tests/Fixtures/**
  • .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/_baseline/renovate.json 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/hosting_acquia/.docker/cli.dockerfile is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/hosting_acquia/.docker/nginx-drupal.dockerfile is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/hosting_project_name___acquia/.docker/cli.dockerfile is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/hosting_project_name___acquia/.docker/nginx-drupal.dockerfile 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_circleci/.circleci/config.yml is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/names/.docker/cli.dockerfile is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/theme_claro/.docker/cli.dockerfile is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/theme_custom/.docker/cli.dockerfile is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/theme_olivero/.docker/cli.dockerfile is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/theme_stark/.docker/cli.dockerfile 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/.docker/cli.dockerfile 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_groups_no_fe_lint_no_theme_circleci/.docker/cli.dockerfile 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_circleci/.circleci/config.yml 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_eslint_circleci/.circleci/config.yml is excluded by !.vortex/installer/tests/Fixtures/**
  • .vortex/installer/tests/Fixtures/handler_process/tools_no_eslint_no_theme/.docker/cli.dockerfile 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_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_stylelint_no_theme/.docker/cli.dockerfile 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 (12)
  • .circleci/config.yml
  • .claude/skills/prepare-vortex-release/SKILL.md
  • .docker/clamav.dockerfile
  • .docker/cli.dockerfile
  • .docker/database.dockerfile
  • .docker/nginx-drupal.dockerfile
  • .docker/php.dockerfile
  • .docker/solr.dockerfile
  • .github/workflows/build-test-deploy.yml
  • .vortex/installer/tests/Functional/Handlers/ToolsHandlerProcessTest.php
  • .vortex/tests/lint.dockerfiles.sh
  • renovate.json

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

@github-actions

This comment has been minimized.

@AlexSkrypnyk

This comment has been minimized.

2 similar comments
@AlexSkrypnyk

This comment has been minimized.

@AlexSkrypnyk

This comment has been minimized.

@github-actions

github-actions Bot commented Jul 30, 2026

Copy link
Copy Markdown

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

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

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

@codecov

codecov Bot commented Jul 30, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 86.38%. Comparing base (d41596a) to head (7f67da4).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2867      +/-   ##
==========================================
- Coverage   86.81%   86.38%   -0.43%     
==========================================
  Files         100       93       -7     
  Lines        4846     4687     -159     
  Branches       47        3      -44     
==========================================
- Hits         4207     4049     -158     
+ Misses        639      638       -1     

☔ 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.

@AlexSkrypnyk AlexSkrypnyk changed the title Pinned Hadolint to v2.15.0 and resolved the new DL3064 and DL3066 findings. Pinned Hadolint to v2.15.0 and resolved its new rule violations. Jul 30, 2026
@github-actions

This comment has been minimized.

@AlexSkrypnyk

This comment has been minimized.

2 similar comments
@AlexSkrypnyk

This comment has been minimized.

@AlexSkrypnyk

This comment has been minimized.

@AlexSkrypnyk AlexSkrypnyk changed the title Pinned Hadolint to v2.15.0 and resolved its new rule violations. [#2868] Pinned Hadolint to v2.15.0 and replaced its global ignores with justified per-line ones. Jul 31, 2026
@github-actions

This comment has been minimized.

@AlexSkrypnyk

This comment has been minimized.

2 similar comments
@AlexSkrypnyk

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:   98.55% (204/207)
Per-class coverage
Drupal\ys_demo\Plugin\Block\CounterBlock
  Methods: 100.00% ( 2/ 2)   Lines: 100.00% ( 10/ 10)

@AlexSkrypnyk

This comment has been minimized.

@AlexSkrypnyk

Copy link
Copy Markdown
Member Author

Code coverage (threshold: 90%)

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

1 similar comment
@AlexSkrypnyk

Copy link
Copy Markdown
Member Author

Code coverage (threshold: 90%)

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

@AlexSkrypnyk AlexSkrypnyk added the Needs review Pull request needs a review from assigned developers label Jul 31, 2026
@AlexSkrypnyk
AlexSkrypnyk merged commit c98f69d into main Jul 31, 2026
34 checks passed
@AlexSkrypnyk
AlexSkrypnyk deleted the feature/hadolint-version branch July 31, 2026 01:29
@github-project-automation github-project-automation Bot moved this from BACKLOG to Release queue in Vortex 1.x Jul 31, 2026
@AlexSkrypnyk AlexSkrypnyk added this to the 1.41.0 milestone Jul 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Needs review Pull request needs a review from assigned developers

Projects

Status: Release queue

Development

Successfully merging this pull request may close these issues.

Pin the 'hadolint' image tag and replace its global rule suppressions

1 participant