Skip to content

build(ci): replace MegaLinter with per-tool GitHub Actions lint workflows#240

Merged
WilliamBerryiii merged 11 commits intomainfrom
feature/issue-235-replace-megalinter
Mar 15, 2026
Merged

build(ci): replace MegaLinter with per-tool GitHub Actions lint workflows#240
WilliamBerryiii merged 11 commits intomainfrom
feature/issue-235-replace-megalinter

Conversation

@WilliamBerryiii
Copy link
Member

Description

Replaced the monolithic MegaLinter orchestration with 8 dedicated, per-tool reusable GitHub Actions workflows following hve-core modular build system patterns. Each workflow uses workflow_call with a soft-fail boolean input, enabling the PR pipeline to fail on lint violations while the main branch can optionally warn. Both pr-validation.yml and main.yml orchestrators were rewired to call all lint jobs in parallel with zero dependency gates, maximizing CI throughput.

Reusable Lint Workflows

Created 8 new reusable workflows in .github/workflows/, each self-contained with tool installation, file discovery, lint execution, and artifact upload stages:

  • shell-lint.yml — bash -n syntax check, ShellCheck, shfmt
  • terraform-lint.ymlterraform fmt check, tflint with pinned SHA
  • bicep-lint.ymlaz bicep build validation across all bicep directories
  • docs-lint.yml — markdownlint, markdown-table-formatter, cspell
  • code-quality-lint.yml — ESLint, Prettier JSON check
  • powershell-lint.yml — PSScriptAnalyzer with project settings
  • security-scan.yml — gitleaks, grype SCA, secretlint with SARIF upload to GitHub Security tab
  • yaml-lint.yml — yamllint, helm lint, hadolint

All workflows share consistent patterns: persist-credentials: false on checkout, env: SOFT_FAIL indirection for safe shell interpolation, and 30-day artifact retention.

Orchestrator Rewiring

Updated both pipeline orchestrators to replace the single mega-linter job with 8 parallel lint job calls. Removed unnecessary needs: dependency gates from downstream jobs that had no data dependency on lint results:

  • pr-validation.yml — removed needs: from docs-automation, docs-check-terraform, docs-check-bicep, aio-version-check; narrowed matrix-changes dependency to [docs-automation] only
  • main.yml — removed needs: from docs-check-terraform-main, docs-check-bicep-main; preserved deploy-pages-main dependency gate as a real deployment prerequisite

npm Script Migration

Replaced 7 mega-linter-runner-based npm scripts with direct tool invocations. Removed the mega-linter-runner dependency and added cspell and eslint as project dependencies.

Cleanup

Deleted megalinter.yml (reusable workflow, 117 lines) and .mega-linter.yml (root config, 154 lines). Updated a stale mega-linter comment reference in resource-provider-pwsh-tests.yml.

Related Issue

Related to #235

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Blueprint modification or addition
  • Component modification or addition
  • Documentation update
  • CI/CD pipeline change
  • Other (please describe):

Implementation Details

The approach decomposes MegaLinter's 22-linter monolith into 8 focused workflows grouped by tool domain. Each workflow is a workflow_call target that orchestrators invoke as parallel jobs. This replaces the serial MegaLinter execution (which ran all linters sequentially in a single container) with parallel native runners, reducing CI wall-clock time.

The soft-fail input on each workflow defaults to false (hard fail). The PR orchestrator passes no override (enforcing lint failures as blocking), while the main orchestrator also uses the default (enforcing quality on the main branch). The env: SOFT_FAIL pattern avoids direct ${{ inputs.soft-fail }} interpolation in shell blocks, following the GitHub Actions security recommendation for input handling.

secretlint is installed inline in security-scan.yml via npm install --no-save rather than added to package.json. This keeps security-only tooling out of the local development environment while maintaining CI coverage.

Testing Performed

  • Manual validation
  • Other:

YAML syntax validated via Python yaml.safe_load for all 10 workflow files. Structural consistency verified across all 8 reusable workflows. JSON formatting validated via Prettier. Zero MegaLinter references confirmed in .github/workflows/. Full CI validation will run on first push.

Validation Steps

  1. Verify the PR triggers all 8 lint jobs in parallel under the GitHub Actions checks tab
  2. Confirm lint jobs start immediately without waiting for dependency-scan or codeql-analysis
  3. Check that security-scan uploads SARIF results to the GitHub Security tab
  4. Verify npm run lint executes the migrated script chain locally
  5. Confirm megalinter.yml and .mega-linter.yml are absent from the repository

Checklist

  • I have updated the documentation accordingly
  • I have added tests to cover my changes
  • All new and existing tests passed
  • I have run terraform fmt on all Terraform code
  • I have run terraform validate on all Terraform code
  • I have run az bicep format on all Bicep code
  • I have run az bicep build to validate all Bicep code
  • I have checked for any sensitive data/tokens that should not be committed
  • I have run MegaLinter on my code (mega-linter-runner)

Additional Notes

  • This PR intentionally removes MegaLinter and replaces the "I have run MegaLinter" checklist item with the per-tool lint workflows — the last checkbox above is not applicable
  • 12+ residual MegaLinter references remain in non-workflow files (.cspell.json, .gitignore, .github/copilot-instructions.md, .devcontainer/README.md, azure-pipelines.yml, etc.) — tracked as follow-up work, not in scope for this PR
  • No Terraform, Bicep, or application source code was modified — this is purely CI infrastructure and npm configuration
  • The azure-pipelines.yml MegaLinter template reference is a known follow-up item that may require separate ADO pipeline changes

Screenshots (if applicable)

N/A — CI/CD pipeline changes with no UI impact

@WilliamBerryiii WilliamBerryiii requested a review from a team as a code owner March 11, 2026 20:33
Copilot AI review requested due to automatic review settings March 11, 2026 20:33
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR replaces the repository’s MegaLinter-based linting with a set of reusable, per-tool GitHub Actions workflows, and rewires the PR + main CI orchestrators to run these lint jobs in parallel. It also updates package.json scripts/dependencies to remove mega-linter-runner usage and run tools directly.

Changes:

  • Added 8 reusable lint workflows (workflow_call) covering shell, Terraform, Bicep, docs, code-quality, PowerShell, security, and YAML/Helm/Dockerfile linting.
  • Updated pr-validation.yml and main.yml to remove MegaLinter jobs and invoke the new lint workflows in parallel.
  • Migrated npm lint scripts away from mega-linter-runner and removed MegaLinter config/workflow files.

Reviewed changes

Copilot reviewed 14 out of 15 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
package.json Removes mega-linter-runner usage; adds direct tool invocations and new deps (cspell/eslint).
.mega-linter.yml Deletes MegaLinter configuration.
.github/workflows/megalinter.yml Deletes MegaLinter reusable workflow.
.github/workflows/pr-validation.yml Replaces MegaLinter job with parallel per-tool lint workflow calls; adjusts needs graph.
.github/workflows/main.yml Replaces MegaLinter job with parallel per-tool lint workflow calls; adjusts needs graph.
.github/workflows/shell-lint.yml New reusable shell lint workflow (bash -n, ShellCheck, shfmt).
.github/workflows/terraform-lint.yml New reusable Terraform lint workflow (fmt + TFLint).
.github/workflows/bicep-lint.yml New reusable Bicep validation workflow (az bicep build across repo).
.github/workflows/docs-lint.yml New reusable docs lint workflow (markdownlint, table formatter check, cspell).
.github/workflows/code-quality-lint.yml New reusable code-quality workflow (ESLint + Prettier JSON check).
.github/workflows/powershell-lint.yml New reusable PowerShell lint workflow (PSScriptAnalyzer).
.github/workflows/security-scan.yml New reusable security workflow (gitleaks, grype, secretlint + SARIF upload).
.github/workflows/yaml-lint.yml New reusable YAML/Helm/Dockerfile workflow (yamllint, helm lint, hadolint).
.github/workflows/resource-provider-pwsh-tests.yml Updates a stale MegaLinter reference in usage example comment.

@github-advanced-security
Copy link

You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool.

What Enabling Code Scanning Means:

  • The 'Security' tab will display more code scanning analysis results (e.g., for the default branch).
  • Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results.
  • You will be able to see the analysis results for the pull request's branch on this overview once the scans have completed and the checks have passed.

For more information about GitHub Code Scanning, check out the documentation.

Copilot AI review requested due to automatic review settings March 11, 2026 23:03
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 14 out of 15 changed files in this pull request and generated 6 comments.

Copy link
Collaborator

@katriendg katriendg left a comment

Choose a reason for hiding this comment

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

Thank you 🙏 🙏 🙏 for this one, it's going to be such an improvement!

I have a few comments, the one I would push to a new issue + PR potentially is the cleanup of -devcontainer & bicep lint, mostly because it requires updating a few docs. For now just removing the two lines would already be good?

Copy link
Member

@bindsi bindsi left a comment

Choose a reason for hiding this comment

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

Thanks for this nice PR and the tremendous improvement we´ll achieve during the pipeline runs. 🙏

@bindsi
Copy link
Member

bindsi commented Mar 13, 2026

@WilliamBerryiii I see .megalinter.yaml is removed but the new individual linters don´t have own config files --> would this make sense for quick change of rules? Or do you intend to update the configuration in a workflow step of the linter then by passing the right parameter?

@WilliamBerryiii
Copy link
Member Author

@WilliamBerryiii I see .megalinter.yaml is removed but the new individual linters don´t have own config files --> would this make sense for quick change of rules? Or do you intend to update the configuration in a workflow step of the linter then by passing the right parameter?

All the linters should have their own configs when we are not using the defaults. The prior two PRs should have finished that out.

@WilliamBerryiii
Copy link
Member Author

Follow-up issue created for the bicep-lint npm script addition and stale documentation references: #257

- add shell, terraform, bicep, docs, code-quality, powershell, security, yaml lint workflows
- rewire pr-validation.yml and main.yml to call 8 parallel lint jobs
- migrate npm scripts from mega-linter-runner to direct tool invocations
- remove megalinter.yml workflow and .mega-linter.yml config

🔧 - Generated by Copilot
- Remove dependency-scan gating from all 8 lint jobs in both workflows
- Remove codeql-analysis gate from dependency-scan in PR workflow
- Remove lint-job gates from downstream docs and version-check jobs
- Narrow matrix-changes dependency to docs-automation only
- Remove soft-fail: true from main branch lint jobs (enforce quality)
- Standardize soft-fail to env var indirection in 4 workflows
- Standardize artifact retention to 30 days across all workflows
- Fix corrupted hashicorp/setup-terraform SHA in terraform-lint.yml

🔧 - Generated by Copilot
…stall

- microsoft enterprise policy blocks third-party actions not in the allowed list
- replace uses: terraform-linters/setup-tflint with curl-based pinned v0.54.0 install

🔧 - Generated by Copilot
…r step

- markdown-table-formatter CLI has no --ignore option
- use find with -not -path exclusions piped via xargs instead

🔧 - Generated by Copilot
…lations

- terraform-lint: tflint terraform_required_providers warnings (#242)
- shell-lint: ShellCheck and shfmt violations (#243)
- code-quality-lint: ESLint violations in docs JS (#244)

🐛 - Generated by Copilot
- pin Grype v0.80.0, Terraform v1.9.8, PSScriptAnalyzer v1.22.0, Helm v3.16.3
- fix gitleaks --exit-code and secretlint node_modules exclusions
- add shellcheck/shfmt install step; fix find|xargs with -print0/-0/-r
- add az bicep install in bicep-lint; align cspell exclusions across configs
- add fail-on-severity threshold to .grype.yaml

🔒 - Generated by Copilot
- Add shell: bash to workflow summary steps

- Fix POSIX compliance: == to = in test comparisons

- Add \ default pattern for unset variables

- Remove obsolete devcontainer lint scripts from package.json

🔧 - Generated by Copilot
Copilot AI review requested due to automatic review settings March 15, 2026 01:29
@WilliamBerryiii WilliamBerryiii force-pushed the feature/issue-235-replace-megalinter branch from 64d4d8f to a1d208e Compare March 15, 2026 01:29
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 16 out of 17 changed files in this pull request and generated 5 comments.

- add deleted credentials.yaml commit to gitleaks allowlist
- upgrade existing short hashes to full 40-char hashes

🔒 - Generated by Copilot
- resolve CI failure from commit allowlist incompatibility with 8.21.2

🔧 - Generated by Copilot
Copilot AI review requested due to automatic review settings March 15, 2026 03:43
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 17 out of 18 changed files in this pull request and generated 6 comments.

- Previous v0.80.0 used a legacy DB feed no longer updated regularly
- Stale DB (6 days old, max 5 allowed) was the sole remaining CI failure

🤖 - Generated by Copilot
…ties

- ignore flatted 3.3.3 prototype pollution (GHSA-25h7-pfq9-p65f)
- ignore aws-lc-sys 0.32.3 vulnerabilities (GHSA-65p9-r9h6-22vj, GHSA-hfpc-8r3f-gw53, GHSA-vw5v-4f2q-w9xf)

🔒 - Generated by Copilot
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 17 out of 18 changed files in this pull request and generated 6 comments.

@WilliamBerryiii WilliamBerryiii merged commit 022a1a1 into main Mar 15, 2026
35 checks passed
@WilliamBerryiii WilliamBerryiii deleted the feature/issue-235-replace-megalinter branch March 15, 2026 18:14
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.

5 participants