feat: add SonarQube workflow template for PHP/Drupal - #7

Merged
MichaelFisher1997 merged 1 commit into
mainfrom
feature/sonarqube-workflow
Feb 12, 2026
Merged

feat: add SonarQube workflow template for PHP/Drupal#7
MichaelFisher1997 merged 1 commit into
mainfrom
feature/sonarqube-workflow

Conversation

@MichaelFisher1997

Copy link
Copy Markdown
Collaborator

Summary

Adds SonarQube workflow template for PHP/Drupal projects.

Changes

  • sonarqube.yml - Self-hosted SonarQube scan workflow with:

    • Push/PR triggers on main/master
    • PHP 8.3 setup with Composer caching
    • SonarQube scan action
    • SARIF export to GitHub Security Tab
    • Secrets: SONAR_TOKEN, SONAR_HOST_URL
  • sonar-project.properties - PHP/Drupal configuration template:

    • Project identification placeholders
    • Drupal source paths (web/modules/custom, web/themes/custom)
    • Comprehensive exclusions (vendor, core, contrib, etc.)
    • GitHub PR integration
  • Registry updates:

    • Discovers .properties files alongside .yml/.yaml
    • Metadata id field now overrides derived workflow ID

Testing

  • All 30 existing tests pass
  • Workflow discovered correctly by registry

- Add sonarqube.yml workflow with self-hosted SonarQube scan
- Add sonar-project.properties configuration template
- Includes SARIF export to GitHub Security Tab
- Update registry to discover .properties files
- Allow metadata.id to override derived workflow ID
@opencode-agent

Copy link
Copy Markdown

📋 Summary

No linked issues found in PR description.

This PR adds a comprehensive SonarQube workflow template for PHP/Drupal projects, including a GitHub Actions workflow with SARIF export and a properties configuration file. It also extends the registry to support .properties files and allows metadata id fields to override derived workflow IDs. The implementation is well-structured with proper metadata blocks and follows the existing patterns in the codebase.

🔴 Critical Issues (Must Fix - Blocks Merge)

None identified

⚠️ High Priority Issues (Should Fix)

[HIGH]src/core/registry.ts:307,310 - .properties files not handled in groupByBaseName
Confidence: High
Description: The groupByBaseName method uses regex /\.ya?ml$/ to strip extensions, but .properties files retain their extension. This causes incorrect base name grouping for properties files.
Impact: Properties files will be grouped incorrectly (e.g., sonar-project.properties won't match sonar-project as expected), potentially creating duplicate or orphaned workflow entries.
Suggested Fix: Update the regex in lines 307 and 310 to also handle .properties extension:

// Line 307constnames=newSet(files.map((file)=>file.replace(/\.(ya?ml|properties)$/,'')));// Line 310 constname=file.replace(/\.(ya?ml|properties)$/,'');

💡 Medium Priority Issues (Nice to Fix)

[MEDIUM]src/core/registry.ts:222 - ID override precedence could cause collisions
Confidence: Medium
Description: Allowing metadata id to override the derived ID provides flexibility but could lead to naming collisions if multiple workflows define the same custom ID.
Impact: If two workflows specify the same id in metadata, the second one will silently overwrite the first in the registry Map.
Suggested Fix: Add collision detection before setting the workflow:

constworkflowId=metadata.id??`${args.category.id}/${args.workflowType}`;if(workflows.has(workflowId)){console.warn(`Warning: Duplicate workflow ID '${workflowId}' detected. Skipping...`);returnnull;}

[MEDIUM]workflows/ci/sonarqube/sonarqube.yml:99 - SARIF upload only on push to main/master
Confidence: Low
Description: The SARIF upload step has a conditional that only runs on push events to main/master branches, which means PRs won't have security findings uploaded to the Security tab.
Impact: Developers won't see SonarQube security findings in the GitHub Security tab when reviewing PRs - only after merge.
Suggested Fix: Consider whether this is intentional. If you want PR findings in the Security tab, remove or modify the condition:

# Option 1: Upload on all eventsif: always()# Option 2: Upload on PRs too if: github.event_name == 'push' || github.event_name == 'pull_request'

ℹ️ Low Priority Suggestions (Optional)

[LOW]workflows/ci/sonarqube/sonar-project.properties:46-49 - Sonar exclusions use += syntax
Confidence: Medium
Description: The sonar-project.properties uses += operator to append to exclusions. While valid, some users may not be familiar with this syntax.
Impact: Users copying this config might be confused about whether to use = or +=.
Suggested Fix: Consider consolidating into single line for clarity, or add a comment explaining the syntax:

# Exclusions combined with commas (single line is clearer)sonar.exclusions=**/vendor/**,**/node_modules/**,**/libraries/**,**/dist/**,**/css/**,**/*.min.js,**/*.min.css,**/tests/**,**/test/**,**/spec/**,web/core/**,web/modules/contrib/**,web/themes/contrib/**,web/profiles/contrib/**,web/libraries/**,**/config/**,**/files/**

[LOW]workflows/ci/sonarqube/sonarqube.yml:59 - Hardcoded PHP version
Confidence: Low
Description: PHP 8.3 is hardcoded in the workflow.
Impact: Teams using different PHP versions will need to modify the workflow.
Suggested Fix: Consider if this should be configurable via workflow input or better documented in the description.

📊 SOLID Principles Score

PrincipleScoreNotes
Single Responsibility9Workflow file, config file, and registry changes each have clear, focused purposes
Open/Closed8Registry extended to support .properties without modifying existing logic extensively
Liskov Substitution9New files follow existing workflow patterns; no inheritance issues
Interface Segregation9Metadata blocks are focused and don't force unused fields
Dependency Inversion8Registry depends on abstractions; workflow depends on external actions via interfaces
Average8.6

🎯 Final Assessment

Overall Confidence Score: 85%

Confidence Breakdown:

  • Code Quality: 90% (clean implementation, follows conventions)
  • Completeness: 85% (minor gap in .properties extension handling)
  • Risk Level: 80% (low risk but potential for ID collisions)
  • Test Coverage: 85% (existing tests pass, but edge case in grouping not covered)

Merge Readiness:

  • All critical issues resolved
  • SOLID average score >= 6.0 (8.6 achieved)
  • Overall confidence >= 60% (85% achieved)
  • No security concerns
  • Tests present and passing (30 existing tests pass)

Verdict:

MERGE WITH FIXES

The PR is well-implemented and follows established patterns. Fix the .properties extension handling in groupByBaseName (lines 307, 310) before merging to ensure proper file grouping. The ID collision warning is optional but recommended for robustness.

New%20session%20-%202026-02-12T23%3A55%3A57.621Z
opencode session | github run

@MichaelFisher1997
MichaelFisher1997 merged commit 58b9b7b into mainFeb 12, 2026
2 checks passed
Sign up for freeto 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.

1 participant

@MichaelFisher1997
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

feat: add SonarQube workflow template for PHP/Drupal - #7

Merged
MichaelFisher1997 merged 1 commit into
mainfrom
feature/sonarqube-workflow
Feb 12, 2026
Merged

feat: add SonarQube workflow template for PHP/Drupal#7
MichaelFisher1997 merged 1 commit into
mainfrom
feature/sonarqube-workflow

Conversation

@MichaelFisher1997

Copy link
Copy Markdown
Collaborator

Summary

Adds SonarQube workflow template for PHP/Drupal projects.

Changes

  • sonarqube.yml - Self-hosted SonarQube scan workflow with:

    • Push/PR triggers on main/master
    • PHP 8.3 setup with Composer caching
    • SonarQube scan action
    • SARIF export to GitHub Security Tab
    • Secrets: SONAR_TOKEN, SONAR_HOST_URL
  • sonar-project.properties - PHP/Drupal configuration template:

    • Project identification placeholders
    • Drupal source paths (web/modules/custom, web/themes/custom)
    • Comprehensive exclusions (vendor, core, contrib, etc.)
    • GitHub PR integration
  • Registry updates:

    • Discovers .properties files alongside .yml/.yaml
    • Metadata id field now overrides derived workflow ID

Testing

  • All 30 existing tests pass
  • Workflow discovered correctly by registry

- Add sonarqube.yml workflow with self-hosted SonarQube scan
- Add sonar-project.properties configuration template
- Includes SARIF export to GitHub Security Tab
- Update registry to discover .properties files
- Allow metadata.id to override derived workflow ID
@opencode-agent

Copy link
Copy Markdown

📋 Summary

No linked issues found in PR description.

This PR adds a comprehensive SonarQube workflow template for PHP/Drupal projects, including a GitHub Actions workflow with SARIF export and a properties configuration file. It also extends the registry to support .properties files and allows metadata id fields to override derived workflow IDs. The implementation is well-structured with proper metadata blocks and follows the existing patterns in the codebase.

🔴 Critical Issues (Must Fix - Blocks Merge)

None identified

⚠️ High Priority Issues (Should Fix)

[HIGH]src/core/registry.ts:307,310 - .properties files not handled in groupByBaseName
Confidence: High
Description: The groupByBaseName method uses regex /\.ya?ml$/ to strip extensions, but .properties files retain their extension. This causes incorrect base name grouping for properties files.
Impact: Properties files will be grouped incorrectly (e.g., sonar-project.properties won't match sonar-project as expected), potentially creating duplicate or orphaned workflow entries.
Suggested Fix: Update the regex in lines 307 and 310 to also handle .properties extension:

// Line 307constnames=newSet(files.map((file)=>file.replace(/\.(ya?ml|properties)$/,'')));// Line 310 constname=file.replace(/\.(ya?ml|properties)$/,'');

💡 Medium Priority Issues (Nice to Fix)

[MEDIUM]src/core/registry.ts:222 - ID override precedence could cause collisions
Confidence: Medium
Description: Allowing metadata id to override the derived ID provides flexibility but could lead to naming collisions if multiple workflows define the same custom ID.
Impact: If two workflows specify the same id in metadata, the second one will silently overwrite the first in the registry Map.
Suggested Fix: Add collision detection before setting the workflow:

constworkflowId=metadata.id??`${args.category.id}/${args.workflowType}`;if(workflows.has(workflowId)){console.warn(`Warning: Duplicate workflow ID '${workflowId}' detected. Skipping...`);returnnull;}

[MEDIUM]workflows/ci/sonarqube/sonarqube.yml:99 - SARIF upload only on push to main/master
Confidence: Low
Description: The SARIF upload step has a conditional that only runs on push events to main/master branches, which means PRs won't have security findings uploaded to the Security tab.
Impact: Developers won't see SonarQube security findings in the GitHub Security tab when reviewing PRs - only after merge.
Suggested Fix: Consider whether this is intentional. If you want PR findings in the Security tab, remove or modify the condition:

# Option 1: Upload on all eventsif: always()# Option 2: Upload on PRs too if: github.event_name == 'push' || github.event_name == 'pull_request'

ℹ️ Low Priority Suggestions (Optional)

[LOW]workflows/ci/sonarqube/sonar-project.properties:46-49 - Sonar exclusions use += syntax
Confidence: Medium
Description: The sonar-project.properties uses += operator to append to exclusions. While valid, some users may not be familiar with this syntax.
Impact: Users copying this config might be confused about whether to use = or +=.
Suggested Fix: Consider consolidating into single line for clarity, or add a comment explaining the syntax:

# Exclusions combined with commas (single line is clearer)sonar.exclusions=**/vendor/**,**/node_modules/**,**/libraries/**,**/dist/**,**/css/**,**/*.min.js,**/*.min.css,**/tests/**,**/test/**,**/spec/**,web/core/**,web/modules/contrib/**,web/themes/contrib/**,web/profiles/contrib/**,web/libraries/**,**/config/**,**/files/**

[LOW]workflows/ci/sonarqube/sonarqube.yml:59 - Hardcoded PHP version
Confidence: Low
Description: PHP 8.3 is hardcoded in the workflow.
Impact: Teams using different PHP versions will need to modify the workflow.
Suggested Fix: Consider if this should be configurable via workflow input or better documented in the description.

📊 SOLID Principles Score

PrincipleScoreNotes
Single Responsibility9Workflow file, config file, and registry changes each have clear, focused purposes
Open/Closed8Registry extended to support .properties without modifying existing logic extensively
Liskov Substitution9New files follow existing workflow patterns; no inheritance issues
Interface Segregation9Metadata blocks are focused and don't force unused fields
Dependency Inversion8Registry depends on abstractions; workflow depends on external actions via interfaces
Average8.6

🎯 Final Assessment

Overall Confidence Score: 85%

Confidence Breakdown:

  • Code Quality: 90% (clean implementation, follows conventions)
  • Completeness: 85% (minor gap in .properties extension handling)
  • Risk Level: 80% (low risk but potential for ID collisions)
  • Test Coverage: 85% (existing tests pass, but edge case in grouping not covered)

Merge Readiness:

  • All critical issues resolved
  • SOLID average score >= 6.0 (8.6 achieved)
  • Overall confidence >= 60% (85% achieved)
  • No security concerns
  • Tests present and passing (30 existing tests pass)

Verdict:

MERGE WITH FIXES

The PR is well-implemented and follows established patterns. Fix the .properties extension handling in groupByBaseName (lines 307, 310) before merging to ensure proper file grouping. The ID collision warning is optional but recommended for robustness.

New%20session%20-%202026-02-12T23%3A55%3A57.621Z
opencode session | github run

@MichaelFisher1997
MichaelFisher1997 merged commit 58b9b7b into mainFeb 12, 2026
2 checks passed
Sign up for freeto 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.

1 participant

@MichaelFisher1997
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: add SonarQube workflow template for PHP/Drupal - #7

Merged
MichaelFisher1997 merged 1 commit into
mainfrom
feature/sonarqube-workflow
Feb 12, 2026
Merged

feat: add SonarQube workflow template for PHP/Drupal#7
MichaelFisher1997 merged 1 commit into
mainfrom
feature/sonarqube-workflow

Conversation

@MichaelFisher1997

Copy link
Copy Markdown
Collaborator

Summary

Adds SonarQube workflow template for PHP/Drupal projects.

Changes

  • sonarqube.yml - Self-hosted SonarQube scan workflow with:

    • Push/PR triggers on main/master
    • PHP 8.3 setup with Composer caching
    • SonarQube scan action
    • SARIF export to GitHub Security Tab
    • Secrets: SONAR_TOKEN, SONAR_HOST_URL
  • sonar-project.properties - PHP/Drupal configuration template:

    • Project identification placeholders
    • Drupal source paths (web/modules/custom, web/themes/custom)
    • Comprehensive exclusions (vendor, core, contrib, etc.)
    • GitHub PR integration
  • Registry updates:

    • Discovers .properties files alongside .yml/.yaml
    • Metadata id field now overrides derived workflow ID

Testing

  • All 30 existing tests pass
  • Workflow discovered correctly by registry

- Add sonarqube.yml workflow with self-hosted SonarQube scan
- Add sonar-project.properties configuration template
- Includes SARIF export to GitHub Security Tab
- Update registry to discover .properties files
- Allow metadata.id to override derived workflow ID
@opencode-agent

Copy link
Copy Markdown

📋 Summary

No linked issues found in PR description.

This PR adds a comprehensive SonarQube workflow template for PHP/Drupal projects, including a GitHub Actions workflow with SARIF export and a properties configuration file. It also extends the registry to support .properties files and allows metadata id fields to override derived workflow IDs. The implementation is well-structured with proper metadata blocks and follows the existing patterns in the codebase.

🔴 Critical Issues (Must Fix - Blocks Merge)

None identified

⚠️ High Priority Issues (Should Fix)

[HIGH]src/core/registry.ts:307,310 - .properties files not handled in groupByBaseName
Confidence: High
Description: The groupByBaseName method uses regex /\.ya?ml$/ to strip extensions, but .properties files retain their extension. This causes incorrect base name grouping for properties files.
Impact: Properties files will be grouped incorrectly (e.g., sonar-project.properties won't match sonar-project as expected), potentially creating duplicate or orphaned workflow entries.
Suggested Fix: Update the regex in lines 307 and 310 to also handle .properties extension:

// Line 307constnames=newSet(files.map((file)=>file.replace(/\.(ya?ml|properties)$/,'')));// Line 310 constname=file.replace(/\.(ya?ml|properties)$/,'');

💡 Medium Priority Issues (Nice to Fix)

[MEDIUM]src/core/registry.ts:222 - ID override precedence could cause collisions
Confidence: Medium
Description: Allowing metadata id to override the derived ID provides flexibility but could lead to naming collisions if multiple workflows define the same custom ID.
Impact: If two workflows specify the same id in metadata, the second one will silently overwrite the first in the registry Map.
Suggested Fix: Add collision detection before setting the workflow:

constworkflowId=metadata.id??`${args.category.id}/${args.workflowType}`;if(workflows.has(workflowId)){console.warn(`Warning: Duplicate workflow ID '${workflowId}' detected. Skipping...`);returnnull;}

[MEDIUM]workflows/ci/sonarqube/sonarqube.yml:99 - SARIF upload only on push to main/master
Confidence: Low
Description: The SARIF upload step has a conditional that only runs on push events to main/master branches, which means PRs won't have security findings uploaded to the Security tab.
Impact: Developers won't see SonarQube security findings in the GitHub Security tab when reviewing PRs - only after merge.
Suggested Fix: Consider whether this is intentional. If you want PR findings in the Security tab, remove or modify the condition:

# Option 1: Upload on all eventsif: always()# Option 2: Upload on PRs too if: github.event_name == 'push' || github.event_name == 'pull_request'

ℹ️ Low Priority Suggestions (Optional)

[LOW]workflows/ci/sonarqube/sonar-project.properties:46-49 - Sonar exclusions use += syntax
Confidence: Medium
Description: The sonar-project.properties uses += operator to append to exclusions. While valid, some users may not be familiar with this syntax.
Impact: Users copying this config might be confused about whether to use = or +=.
Suggested Fix: Consider consolidating into single line for clarity, or add a comment explaining the syntax:

# Exclusions combined with commas (single line is clearer)sonar.exclusions=**/vendor/**,**/node_modules/**,**/libraries/**,**/dist/**,**/css/**,**/*.min.js,**/*.min.css,**/tests/**,**/test/**,**/spec/**,web/core/**,web/modules/contrib/**,web/themes/contrib/**,web/profiles/contrib/**,web/libraries/**,**/config/**,**/files/**

[LOW]workflows/ci/sonarqube/sonarqube.yml:59 - Hardcoded PHP version
Confidence: Low
Description: PHP 8.3 is hardcoded in the workflow.
Impact: Teams using different PHP versions will need to modify the workflow.
Suggested Fix: Consider if this should be configurable via workflow input or better documented in the description.

📊 SOLID Principles Score

PrincipleScoreNotes
Single Responsibility9Workflow file, config file, and registry changes each have clear, focused purposes
Open/Closed8Registry extended to support .properties without modifying existing logic extensively
Liskov Substitution9New files follow existing workflow patterns; no inheritance issues
Interface Segregation9Metadata blocks are focused and don't force unused fields
Dependency Inversion8Registry depends on abstractions; workflow depends on external actions via interfaces
Average8.6

🎯 Final Assessment

Overall Confidence Score: 85%

Confidence Breakdown:

  • Code Quality: 90% (clean implementation, follows conventions)
  • Completeness: 85% (minor gap in .properties extension handling)
  • Risk Level: 80% (low risk but potential for ID collisions)
  • Test Coverage: 85% (existing tests pass, but edge case in grouping not covered)

Merge Readiness:

  • All critical issues resolved
  • SOLID average score >= 6.0 (8.6 achieved)
  • Overall confidence >= 60% (85% achieved)
  • No security concerns
  • Tests present and passing (30 existing tests pass)

Verdict:

MERGE WITH FIXES

The PR is well-implemented and follows established patterns. Fix the .properties extension handling in groupByBaseName (lines 307, 310) before merging to ensure proper file grouping. The ID collision warning is optional but recommended for robustness.

New%20session%20-%202026-02-12T23%3A55%3A57.621Z
opencode session | github run

@MichaelFisher1997
MichaelFisher1997 merged commit 58b9b7b into mainFeb 12, 2026
2 checks passed
Sign up for freeto 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.

1 participant

@MichaelFisher1997
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: add SonarQube workflow template for PHP/Drupal - #7

Merged
MichaelFisher1997 merged 1 commit into
mainfrom
feature/sonarqube-workflow
Feb 12, 2026
Merged

feat: add SonarQube workflow template for PHP/Drupal#7
MichaelFisher1997 merged 1 commit into
mainfrom
feature/sonarqube-workflow

Conversation

@MichaelFisher1997

Copy link
Copy Markdown
Collaborator

Summary

Adds SonarQube workflow template for PHP/Drupal projects.

Changes

  • sonarqube.yml - Self-hosted SonarQube scan workflow with:

    • Push/PR triggers on main/master
    • PHP 8.3 setup with Composer caching
    • SonarQube scan action
    • SARIF export to GitHub Security Tab
    • Secrets: SONAR_TOKEN, SONAR_HOST_URL
  • sonar-project.properties - PHP/Drupal configuration template:

    • Project identification placeholders
    • Drupal source paths (web/modules/custom, web/themes/custom)
    • Comprehensive exclusions (vendor, core, contrib, etc.)
    • GitHub PR integration
  • Registry updates:

    • Discovers .properties files alongside .yml/.yaml
    • Metadata id field now overrides derived workflow ID

Testing

  • All 30 existing tests pass
  • Workflow discovered correctly by registry

- Add sonarqube.yml workflow with self-hosted SonarQube scan
- Add sonar-project.properties configuration template
- Includes SARIF export to GitHub Security Tab
- Update registry to discover .properties files
- Allow metadata.id to override derived workflow ID
@opencode-agent

Copy link
Copy Markdown

📋 Summary

No linked issues found in PR description.

This PR adds a comprehensive SonarQube workflow template for PHP/Drupal projects, including a GitHub Actions workflow with SARIF export and a properties configuration file. It also extends the registry to support .properties files and allows metadata id fields to override derived workflow IDs. The implementation is well-structured with proper metadata blocks and follows the existing patterns in the codebase.

🔴 Critical Issues (Must Fix - Blocks Merge)

None identified

⚠️ High Priority Issues (Should Fix)

[HIGH]src/core/registry.ts:307,310 - .properties files not handled in groupByBaseName
Confidence: High
Description: The groupByBaseName method uses regex /\.ya?ml$/ to strip extensions, but .properties files retain their extension. This causes incorrect base name grouping for properties files.
Impact: Properties files will be grouped incorrectly (e.g., sonar-project.properties won't match sonar-project as expected), potentially creating duplicate or orphaned workflow entries.
Suggested Fix: Update the regex in lines 307 and 310 to also handle .properties extension:

// Line 307constnames=newSet(files.map((file)=>file.replace(/\.(ya?ml|properties)$/,'')));// Line 310 constname=file.replace(/\.(ya?ml|properties)$/,'');

💡 Medium Priority Issues (Nice to Fix)

[MEDIUM]src/core/registry.ts:222 - ID override precedence could cause collisions
Confidence: Medium
Description: Allowing metadata id to override the derived ID provides flexibility but could lead to naming collisions if multiple workflows define the same custom ID.
Impact: If two workflows specify the same id in metadata, the second one will silently overwrite the first in the registry Map.
Suggested Fix: Add collision detection before setting the workflow:

constworkflowId=metadata.id??`${args.category.id}/${args.workflowType}`;if(workflows.has(workflowId)){console.warn(`Warning: Duplicate workflow ID '${workflowId}' detected. Skipping...`);returnnull;}

[MEDIUM]workflows/ci/sonarqube/sonarqube.yml:99 - SARIF upload only on push to main/master
Confidence: Low
Description: The SARIF upload step has a conditional that only runs on push events to main/master branches, which means PRs won't have security findings uploaded to the Security tab.
Impact: Developers won't see SonarQube security findings in the GitHub Security tab when reviewing PRs - only after merge.
Suggested Fix: Consider whether this is intentional. If you want PR findings in the Security tab, remove or modify the condition:

# Option 1: Upload on all eventsif: always()# Option 2: Upload on PRs too if: github.event_name == 'push' || github.event_name == 'pull_request'

ℹ️ Low Priority Suggestions (Optional)

[LOW]workflows/ci/sonarqube/sonar-project.properties:46-49 - Sonar exclusions use += syntax
Confidence: Medium
Description: The sonar-project.properties uses += operator to append to exclusions. While valid, some users may not be familiar with this syntax.
Impact: Users copying this config might be confused about whether to use = or +=.
Suggested Fix: Consider consolidating into single line for clarity, or add a comment explaining the syntax:

# Exclusions combined with commas (single line is clearer)sonar.exclusions=**/vendor/**,**/node_modules/**,**/libraries/**,**/dist/**,**/css/**,**/*.min.js,**/*.min.css,**/tests/**,**/test/**,**/spec/**,web/core/**,web/modules/contrib/**,web/themes/contrib/**,web/profiles/contrib/**,web/libraries/**,**/config/**,**/files/**

[LOW]workflows/ci/sonarqube/sonarqube.yml:59 - Hardcoded PHP version
Confidence: Low
Description: PHP 8.3 is hardcoded in the workflow.
Impact: Teams using different PHP versions will need to modify the workflow.
Suggested Fix: Consider if this should be configurable via workflow input or better documented in the description.

📊 SOLID Principles Score

PrincipleScoreNotes
Single Responsibility9Workflow file, config file, and registry changes each have clear, focused purposes
Open/Closed8Registry extended to support .properties without modifying existing logic extensively
Liskov Substitution9New files follow existing workflow patterns; no inheritance issues
Interface Segregation9Metadata blocks are focused and don't force unused fields
Dependency Inversion8Registry depends on abstractions; workflow depends on external actions via interfaces
Average8.6

🎯 Final Assessment

Overall Confidence Score: 85%

Confidence Breakdown:

  • Code Quality: 90% (clean implementation, follows conventions)
  • Completeness: 85% (minor gap in .properties extension handling)
  • Risk Level: 80% (low risk but potential for ID collisions)
  • Test Coverage: 85% (existing tests pass, but edge case in grouping not covered)

Merge Readiness:

  • All critical issues resolved
  • SOLID average score >= 6.0 (8.6 achieved)
  • Overall confidence >= 60% (85% achieved)
  • No security concerns
  • Tests present and passing (30 existing tests pass)

Verdict:

MERGE WITH FIXES

The PR is well-implemented and follows established patterns. Fix the .properties extension handling in groupByBaseName (lines 307, 310) before merging to ensure proper file grouping. The ID collision warning is optional but recommended for robustness.

New%20session%20-%202026-02-12T23%3A55%3A57.621Z
opencode session | github run

@MichaelFisher1997
MichaelFisher1997 merged commit 58b9b7b into mainFeb 12, 2026
2 checks passed
Sign up for freeto 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.

1 participant

@MichaelFisher1997
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

feat: add SonarQube workflow template for PHP/Drupal - #7

Merged
MichaelFisher1997 merged 1 commit into
mainfrom
feature/sonarqube-workflow
Feb 12, 2026
Merged

feat: add SonarQube workflow template for PHP/Drupal#7
MichaelFisher1997 merged 1 commit into
mainfrom
feature/sonarqube-workflow

Conversation

@MichaelFisher1997

Copy link
Copy Markdown
Collaborator

Summary

Adds SonarQube workflow template for PHP/Drupal projects.

Changes

  • sonarqube.yml - Self-hosted SonarQube scan workflow with:

    • Push/PR triggers on main/master
    • PHP 8.3 setup with Composer caching
    • SonarQube scan action
    • SARIF export to GitHub Security Tab
    • Secrets: SONAR_TOKEN, SONAR_HOST_URL
  • sonar-project.properties - PHP/Drupal configuration template:

    • Project identification placeholders
    • Drupal source paths (web/modules/custom, web/themes/custom)
    • Comprehensive exclusions (vendor, core, contrib, etc.)
    • GitHub PR integration
  • Registry updates:

    • Discovers .properties files alongside .yml/.yaml
    • Metadata id field now overrides derived workflow ID

Testing

  • All 30 existing tests pass
  • Workflow discovered correctly by registry

- Add sonarqube.yml workflow with self-hosted SonarQube scan
- Add sonar-project.properties configuration template
- Includes SARIF export to GitHub Security Tab
- Update registry to discover .properties files
- Allow metadata.id to override derived workflow ID
@opencode-agent

Copy link
Copy Markdown

📋 Summary

No linked issues found in PR description.

This PR adds a comprehensive SonarQube workflow template for PHP/Drupal projects, including a GitHub Actions workflow with SARIF export and a properties configuration file. It also extends the registry to support .properties files and allows metadata id fields to override derived workflow IDs. The implementation is well-structured with proper metadata blocks and follows the existing patterns in the codebase.

🔴 Critical Issues (Must Fix - Blocks Merge)

None identified

⚠️ High Priority Issues (Should Fix)

[HIGH]src/core/registry.ts:307,310 - .properties files not handled in groupByBaseName
Confidence: High
Description: The groupByBaseName method uses regex /\.ya?ml$/ to strip extensions, but .properties files retain their extension. This causes incorrect base name grouping for properties files.
Impact: Properties files will be grouped incorrectly (e.g., sonar-project.properties won't match sonar-project as expected), potentially creating duplicate or orphaned workflow entries.
Suggested Fix: Update the regex in lines 307 and 310 to also handle .properties extension:

// Line 307constnames=newSet(files.map((file)=>file.replace(/\.(ya?ml|properties)$/,'')));// Line 310 constname=file.replace(/\.(ya?ml|properties)$/,'');

💡 Medium Priority Issues (Nice to Fix)

[MEDIUM]src/core/registry.ts:222 - ID override precedence could cause collisions
Confidence: Medium
Description: Allowing metadata id to override the derived ID provides flexibility but could lead to naming collisions if multiple workflows define the same custom ID.
Impact: If two workflows specify the same id in metadata, the second one will silently overwrite the first in the registry Map.
Suggested Fix: Add collision detection before setting the workflow:

constworkflowId=metadata.id??`${args.category.id}/${args.workflowType}`;if(workflows.has(workflowId)){console.warn(`Warning: Duplicate workflow ID '${workflowId}' detected. Skipping...`);returnnull;}

[MEDIUM]workflows/ci/sonarqube/sonarqube.yml:99 - SARIF upload only on push to main/master
Confidence: Low
Description: The SARIF upload step has a conditional that only runs on push events to main/master branches, which means PRs won't have security findings uploaded to the Security tab.
Impact: Developers won't see SonarQube security findings in the GitHub Security tab when reviewing PRs - only after merge.
Suggested Fix: Consider whether this is intentional. If you want PR findings in the Security tab, remove or modify the condition:

# Option 1: Upload on all eventsif: always()# Option 2: Upload on PRs too if: github.event_name == 'push' || github.event_name == 'pull_request'

ℹ️ Low Priority Suggestions (Optional)

[LOW]workflows/ci/sonarqube/sonar-project.properties:46-49 - Sonar exclusions use += syntax
Confidence: Medium
Description: The sonar-project.properties uses += operator to append to exclusions. While valid, some users may not be familiar with this syntax.
Impact: Users copying this config might be confused about whether to use = or +=.
Suggested Fix: Consider consolidating into single line for clarity, or add a comment explaining the syntax:

# Exclusions combined with commas (single line is clearer)sonar.exclusions=**/vendor/**,**/node_modules/**,**/libraries/**,**/dist/**,**/css/**,**/*.min.js,**/*.min.css,**/tests/**,**/test/**,**/spec/**,web/core/**,web/modules/contrib/**,web/themes/contrib/**,web/profiles/contrib/**,web/libraries/**,**/config/**,**/files/**

[LOW]workflows/ci/sonarqube/sonarqube.yml:59 - Hardcoded PHP version
Confidence: Low
Description: PHP 8.3 is hardcoded in the workflow.
Impact: Teams using different PHP versions will need to modify the workflow.
Suggested Fix: Consider if this should be configurable via workflow input or better documented in the description.

📊 SOLID Principles Score

PrincipleScoreNotes
Single Responsibility9Workflow file, config file, and registry changes each have clear, focused purposes
Open/Closed8Registry extended to support .properties without modifying existing logic extensively
Liskov Substitution9New files follow existing workflow patterns; no inheritance issues
Interface Segregation9Metadata blocks are focused and don't force unused fields
Dependency Inversion8Registry depends on abstractions; workflow depends on external actions via interfaces
Average8.6

🎯 Final Assessment

Overall Confidence Score: 85%

Confidence Breakdown:

  • Code Quality: 90% (clean implementation, follows conventions)
  • Completeness: 85% (minor gap in .properties extension handling)
  • Risk Level: 80% (low risk but potential for ID collisions)
  • Test Coverage: 85% (existing tests pass, but edge case in grouping not covered)

Merge Readiness:

  • All critical issues resolved
  • SOLID average score >= 6.0 (8.6 achieved)
  • Overall confidence >= 60% (85% achieved)
  • No security concerns
  • Tests present and passing (30 existing tests pass)

Verdict:

MERGE WITH FIXES

The PR is well-implemented and follows established patterns. Fix the .properties extension handling in groupByBaseName (lines 307, 310) before merging to ensure proper file grouping. The ID collision warning is optional but recommended for robustness.

New%20session%20-%202026-02-12T23%3A55%3A57.621Z
opencode session | github run

@MichaelFisher1997
MichaelFisher1997 merged commit 58b9b7b into mainFeb 12, 2026
2 checks passed
Sign up for freeto 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.

1 participant

@MichaelFisher1997
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: add SonarQube workflow template for PHP/Drupal - #7

Merged
MichaelFisher1997 merged 1 commit into
mainfrom
feature/sonarqube-workflow
Feb 12, 2026
Merged

feat: add SonarQube workflow template for PHP/Drupal#7
MichaelFisher1997 merged 1 commit into
mainfrom
feature/sonarqube-workflow

Conversation

@MichaelFisher1997

Copy link
Copy Markdown
Collaborator

Summary

Adds SonarQube workflow template for PHP/Drupal projects.

Changes

  • sonarqube.yml - Self-hosted SonarQube scan workflow with:

    • Push/PR triggers on main/master
    • PHP 8.3 setup with Composer caching
    • SonarQube scan action
    • SARIF export to GitHub Security Tab
    • Secrets: SONAR_TOKEN, SONAR_HOST_URL
  • sonar-project.properties - PHP/Drupal configuration template:

    • Project identification placeholders
    • Drupal source paths (web/modules/custom, web/themes/custom)
    • Comprehensive exclusions (vendor, core, contrib, etc.)
    • GitHub PR integration
  • Registry updates:

    • Discovers .properties files alongside .yml/.yaml
    • Metadata id field now overrides derived workflow ID

Testing

  • All 30 existing tests pass
  • Workflow discovered correctly by registry

- Add sonarqube.yml workflow with self-hosted SonarQube scan
- Add sonar-project.properties configuration template
- Includes SARIF export to GitHub Security Tab
- Update registry to discover .properties files
- Allow metadata.id to override derived workflow ID
@opencode-agent

Copy link
Copy Markdown

📋 Summary

No linked issues found in PR description.

This PR adds a comprehensive SonarQube workflow template for PHP/Drupal projects, including a GitHub Actions workflow with SARIF export and a properties configuration file. It also extends the registry to support .properties files and allows metadata id fields to override derived workflow IDs. The implementation is well-structured with proper metadata blocks and follows the existing patterns in the codebase.

🔴 Critical Issues (Must Fix - Blocks Merge)

None identified

⚠️ High Priority Issues (Should Fix)

[HIGH]src/core/registry.ts:307,310 - .properties files not handled in groupByBaseName
Confidence: High
Description: The groupByBaseName method uses regex /\.ya?ml$/ to strip extensions, but .properties files retain their extension. This causes incorrect base name grouping for properties files.
Impact: Properties files will be grouped incorrectly (e.g., sonar-project.properties won't match sonar-project as expected), potentially creating duplicate or orphaned workflow entries.
Suggested Fix: Update the regex in lines 307 and 310 to also handle .properties extension:

// Line 307constnames=newSet(files.map((file)=>file.replace(/\.(ya?ml|properties)$/,'')));// Line 310 constname=file.replace(/\.(ya?ml|properties)$/,'');

💡 Medium Priority Issues (Nice to Fix)

[MEDIUM]src/core/registry.ts:222 - ID override precedence could cause collisions
Confidence: Medium
Description: Allowing metadata id to override the derived ID provides flexibility but could lead to naming collisions if multiple workflows define the same custom ID.
Impact: If two workflows specify the same id in metadata, the second one will silently overwrite the first in the registry Map.
Suggested Fix: Add collision detection before setting the workflow:

constworkflowId=metadata.id??`${args.category.id}/${args.workflowType}`;if(workflows.has(workflowId)){console.warn(`Warning: Duplicate workflow ID '${workflowId}' detected. Skipping...`);returnnull;}

[MEDIUM]workflows/ci/sonarqube/sonarqube.yml:99 - SARIF upload only on push to main/master
Confidence: Low
Description: The SARIF upload step has a conditional that only runs on push events to main/master branches, which means PRs won't have security findings uploaded to the Security tab.
Impact: Developers won't see SonarQube security findings in the GitHub Security tab when reviewing PRs - only after merge.
Suggested Fix: Consider whether this is intentional. If you want PR findings in the Security tab, remove or modify the condition:

# Option 1: Upload on all eventsif: always()# Option 2: Upload on PRs too if: github.event_name == 'push' || github.event_name == 'pull_request'

ℹ️ Low Priority Suggestions (Optional)

[LOW]workflows/ci/sonarqube/sonar-project.properties:46-49 - Sonar exclusions use += syntax
Confidence: Medium
Description: The sonar-project.properties uses += operator to append to exclusions. While valid, some users may not be familiar with this syntax.
Impact: Users copying this config might be confused about whether to use = or +=.
Suggested Fix: Consider consolidating into single line for clarity, or add a comment explaining the syntax:

# Exclusions combined with commas (single line is clearer)sonar.exclusions=**/vendor/**,**/node_modules/**,**/libraries/**,**/dist/**,**/css/**,**/*.min.js,**/*.min.css,**/tests/**,**/test/**,**/spec/**,web/core/**,web/modules/contrib/**,web/themes/contrib/**,web/profiles/contrib/**,web/libraries/**,**/config/**,**/files/**

[LOW]workflows/ci/sonarqube/sonarqube.yml:59 - Hardcoded PHP version
Confidence: Low
Description: PHP 8.3 is hardcoded in the workflow.
Impact: Teams using different PHP versions will need to modify the workflow.
Suggested Fix: Consider if this should be configurable via workflow input or better documented in the description.

📊 SOLID Principles Score

PrincipleScoreNotes
Single Responsibility9Workflow file, config file, and registry changes each have clear, focused purposes
Open/Closed8Registry extended to support .properties without modifying existing logic extensively
Liskov Substitution9New files follow existing workflow patterns; no inheritance issues
Interface Segregation9Metadata blocks are focused and don't force unused fields
Dependency Inversion8Registry depends on abstractions; workflow depends on external actions via interfaces
Average8.6

🎯 Final Assessment

Overall Confidence Score: 85%

Confidence Breakdown:

  • Code Quality: 90% (clean implementation, follows conventions)
  • Completeness: 85% (minor gap in .properties extension handling)
  • Risk Level: 80% (low risk but potential for ID collisions)
  • Test Coverage: 85% (existing tests pass, but edge case in grouping not covered)

Merge Readiness:

  • All critical issues resolved
  • SOLID average score >= 6.0 (8.6 achieved)
  • Overall confidence >= 60% (85% achieved)
  • No security concerns
  • Tests present and passing (30 existing tests pass)

Verdict:

MERGE WITH FIXES

The PR is well-implemented and follows established patterns. Fix the .properties extension handling in groupByBaseName (lines 307, 310) before merging to ensure proper file grouping. The ID collision warning is optional but recommended for robustness.

New%20session%20-%202026-02-12T23%3A55%3A57.621Z
opencode session | github run

@MichaelFisher1997
MichaelFisher1997 merged commit 58b9b7b into mainFeb 12, 2026
2 checks passed
Sign up for freeto 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.

1 participant

@MichaelFisher1997
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: add SonarQube workflow template for PHP/Drupal - #7

Merged
MichaelFisher1997 merged 1 commit into
mainfrom
feature/sonarqube-workflow
Feb 12, 2026
Merged

feat: add SonarQube workflow template for PHP/Drupal#7
MichaelFisher1997 merged 1 commit into
mainfrom
feature/sonarqube-workflow

Conversation

@MichaelFisher1997

Copy link
Copy Markdown
Collaborator

Summary

Adds SonarQube workflow template for PHP/Drupal projects.

Changes

  • sonarqube.yml - Self-hosted SonarQube scan workflow with:

    • Push/PR triggers on main/master
    • PHP 8.3 setup with Composer caching
    • SonarQube scan action
    • SARIF export to GitHub Security Tab
    • Secrets: SONAR_TOKEN, SONAR_HOST_URL
  • sonar-project.properties - PHP/Drupal configuration template:

    • Project identification placeholders
    • Drupal source paths (web/modules/custom, web/themes/custom)
    • Comprehensive exclusions (vendor, core, contrib, etc.)
    • GitHub PR integration
  • Registry updates:

    • Discovers .properties files alongside .yml/.yaml
    • Metadata id field now overrides derived workflow ID

Testing

  • All 30 existing tests pass
  • Workflow discovered correctly by registry

- Add sonarqube.yml workflow with self-hosted SonarQube scan
- Add sonar-project.properties configuration template
- Includes SARIF export to GitHub Security Tab
- Update registry to discover .properties files
- Allow metadata.id to override derived workflow ID
@opencode-agent

Copy link
Copy Markdown

📋 Summary

No linked issues found in PR description.

This PR adds a comprehensive SonarQube workflow template for PHP/Drupal projects, including a GitHub Actions workflow with SARIF export and a properties configuration file. It also extends the registry to support .properties files and allows metadata id fields to override derived workflow IDs. The implementation is well-structured with proper metadata blocks and follows the existing patterns in the codebase.

🔴 Critical Issues (Must Fix - Blocks Merge)

None identified

⚠️ High Priority Issues (Should Fix)

[HIGH]src/core/registry.ts:307,310 - .properties files not handled in groupByBaseName
Confidence: High
Description: The groupByBaseName method uses regex /\.ya?ml$/ to strip extensions, but .properties files retain their extension. This causes incorrect base name grouping for properties files.
Impact: Properties files will be grouped incorrectly (e.g., sonar-project.properties won't match sonar-project as expected), potentially creating duplicate or orphaned workflow entries.
Suggested Fix: Update the regex in lines 307 and 310 to also handle .properties extension:

// Line 307constnames=newSet(files.map((file)=>file.replace(/\.(ya?ml|properties)$/,'')));// Line 310 constname=file.replace(/\.(ya?ml|properties)$/,'');

💡 Medium Priority Issues (Nice to Fix)

[MEDIUM]src/core/registry.ts:222 - ID override precedence could cause collisions
Confidence: Medium
Description: Allowing metadata id to override the derived ID provides flexibility but could lead to naming collisions if multiple workflows define the same custom ID.
Impact: If two workflows specify the same id in metadata, the second one will silently overwrite the first in the registry Map.
Suggested Fix: Add collision detection before setting the workflow:

constworkflowId=metadata.id??`${args.category.id}/${args.workflowType}`;if(workflows.has(workflowId)){console.warn(`Warning: Duplicate workflow ID '${workflowId}' detected. Skipping...`);returnnull;}

[MEDIUM]workflows/ci/sonarqube/sonarqube.yml:99 - SARIF upload only on push to main/master
Confidence: Low
Description: The SARIF upload step has a conditional that only runs on push events to main/master branches, which means PRs won't have security findings uploaded to the Security tab.
Impact: Developers won't see SonarQube security findings in the GitHub Security tab when reviewing PRs - only after merge.
Suggested Fix: Consider whether this is intentional. If you want PR findings in the Security tab, remove or modify the condition:

# Option 1: Upload on all eventsif: always()# Option 2: Upload on PRs too if: github.event_name == 'push' || github.event_name == 'pull_request'

ℹ️ Low Priority Suggestions (Optional)

[LOW]workflows/ci/sonarqube/sonar-project.properties:46-49 - Sonar exclusions use += syntax
Confidence: Medium
Description: The sonar-project.properties uses += operator to append to exclusions. While valid, some users may not be familiar with this syntax.
Impact: Users copying this config might be confused about whether to use = or +=.
Suggested Fix: Consider consolidating into single line for clarity, or add a comment explaining the syntax:

# Exclusions combined with commas (single line is clearer)sonar.exclusions=**/vendor/**,**/node_modules/**,**/libraries/**,**/dist/**,**/css/**,**/*.min.js,**/*.min.css,**/tests/**,**/test/**,**/spec/**,web/core/**,web/modules/contrib/**,web/themes/contrib/**,web/profiles/contrib/**,web/libraries/**,**/config/**,**/files/**

[LOW]workflows/ci/sonarqube/sonarqube.yml:59 - Hardcoded PHP version
Confidence: Low
Description: PHP 8.3 is hardcoded in the workflow.
Impact: Teams using different PHP versions will need to modify the workflow.
Suggested Fix: Consider if this should be configurable via workflow input or better documented in the description.

📊 SOLID Principles Score

PrincipleScoreNotes
Single Responsibility9Workflow file, config file, and registry changes each have clear, focused purposes
Open/Closed8Registry extended to support .properties without modifying existing logic extensively
Liskov Substitution9New files follow existing workflow patterns; no inheritance issues
Interface Segregation9Metadata blocks are focused and don't force unused fields
Dependency Inversion8Registry depends on abstractions; workflow depends on external actions via interfaces
Average8.6

🎯 Final Assessment

Overall Confidence Score: 85%

Confidence Breakdown:

  • Code Quality: 90% (clean implementation, follows conventions)
  • Completeness: 85% (minor gap in .properties extension handling)
  • Risk Level: 80% (low risk but potential for ID collisions)
  • Test Coverage: 85% (existing tests pass, but edge case in grouping not covered)

Merge Readiness:

  • All critical issues resolved
  • SOLID average score >= 6.0 (8.6 achieved)
  • Overall confidence >= 60% (85% achieved)
  • No security concerns
  • Tests present and passing (30 existing tests pass)

Verdict:

MERGE WITH FIXES

The PR is well-implemented and follows established patterns. Fix the .properties extension handling in groupByBaseName (lines 307, 310) before merging to ensure proper file grouping. The ID collision warning is optional but recommended for robustness.

New%20session%20-%202026-02-12T23%3A55%3A57.621Z
opencode session | github run

@MichaelFisher1997
MichaelFisher1997 merged commit 58b9b7b into mainFeb 12, 2026
2 checks passed
Sign up for freeto 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.

1 participant

@MichaelFisher1997
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

feat: add SonarQube workflow template for PHP/Drupal - #7

Merged
MichaelFisher1997 merged 1 commit into
mainfrom
feature/sonarqube-workflow
Feb 12, 2026
Merged

feat: add SonarQube workflow template for PHP/Drupal#7
MichaelFisher1997 merged 1 commit into
mainfrom
feature/sonarqube-workflow

Conversation

@MichaelFisher1997

Copy link
Copy Markdown
Collaborator

Summary

Adds SonarQube workflow template for PHP/Drupal projects.

Changes

  • sonarqube.yml - Self-hosted SonarQube scan workflow with:

    • Push/PR triggers on main/master
    • PHP 8.3 setup with Composer caching
    • SonarQube scan action
    • SARIF export to GitHub Security Tab
    • Secrets: SONAR_TOKEN, SONAR_HOST_URL
  • sonar-project.properties - PHP/Drupal configuration template:

    • Project identification placeholders
    • Drupal source paths (web/modules/custom, web/themes/custom)
    • Comprehensive exclusions (vendor, core, contrib, etc.)
    • GitHub PR integration
  • Registry updates:

    • Discovers .properties files alongside .yml/.yaml
    • Metadata id field now overrides derived workflow ID

Testing

  • All 30 existing tests pass
  • Workflow discovered correctly by registry

- Add sonarqube.yml workflow with self-hosted SonarQube scan
- Add sonar-project.properties configuration template
- Includes SARIF export to GitHub Security Tab
- Update registry to discover .properties files
- Allow metadata.id to override derived workflow ID
@opencode-agent

Copy link
Copy Markdown

📋 Summary

No linked issues found in PR description.

This PR adds a comprehensive SonarQube workflow template for PHP/Drupal projects, including a GitHub Actions workflow with SARIF export and a properties configuration file. It also extends the registry to support .properties files and allows metadata id fields to override derived workflow IDs. The implementation is well-structured with proper metadata blocks and follows the existing patterns in the codebase.

🔴 Critical Issues (Must Fix - Blocks Merge)

None identified

⚠️ High Priority Issues (Should Fix)

[HIGH]src/core/registry.ts:307,310 - .properties files not handled in groupByBaseName
Confidence: High
Description: The groupByBaseName method uses regex /\.ya?ml$/ to strip extensions, but .properties files retain their extension. This causes incorrect base name grouping for properties files.
Impact: Properties files will be grouped incorrectly (e.g., sonar-project.properties won't match sonar-project as expected), potentially creating duplicate or orphaned workflow entries.
Suggested Fix: Update the regex in lines 307 and 310 to also handle .properties extension:

// Line 307constnames=newSet(files.map((file)=>file.replace(/\.(ya?ml|properties)$/,'')));// Line 310 constname=file.replace(/\.(ya?ml|properties)$/,'');

💡 Medium Priority Issues (Nice to Fix)

[MEDIUM]src/core/registry.ts:222 - ID override precedence could cause collisions
Confidence: Medium
Description: Allowing metadata id to override the derived ID provides flexibility but could lead to naming collisions if multiple workflows define the same custom ID.
Impact: If two workflows specify the same id in metadata, the second one will silently overwrite the first in the registry Map.
Suggested Fix: Add collision detection before setting the workflow:

constworkflowId=metadata.id??`${args.category.id}/${args.workflowType}`;if(workflows.has(workflowId)){console.warn(`Warning: Duplicate workflow ID '${workflowId}' detected. Skipping...`);returnnull;}

[MEDIUM]workflows/ci/sonarqube/sonarqube.yml:99 - SARIF upload only on push to main/master
Confidence: Low
Description: The SARIF upload step has a conditional that only runs on push events to main/master branches, which means PRs won't have security findings uploaded to the Security tab.
Impact: Developers won't see SonarQube security findings in the GitHub Security tab when reviewing PRs - only after merge.
Suggested Fix: Consider whether this is intentional. If you want PR findings in the Security tab, remove or modify the condition:

# Option 1: Upload on all eventsif: always()# Option 2: Upload on PRs too if: github.event_name == 'push' || github.event_name == 'pull_request'

ℹ️ Low Priority Suggestions (Optional)

[LOW]workflows/ci/sonarqube/sonar-project.properties:46-49 - Sonar exclusions use += syntax
Confidence: Medium
Description: The sonar-project.properties uses += operator to append to exclusions. While valid, some users may not be familiar with this syntax.
Impact: Users copying this config might be confused about whether to use = or +=.
Suggested Fix: Consider consolidating into single line for clarity, or add a comment explaining the syntax:

# Exclusions combined with commas (single line is clearer)sonar.exclusions=**/vendor/**,**/node_modules/**,**/libraries/**,**/dist/**,**/css/**,**/*.min.js,**/*.min.css,**/tests/**,**/test/**,**/spec/**,web/core/**,web/modules/contrib/**,web/themes/contrib/**,web/profiles/contrib/**,web/libraries/**,**/config/**,**/files/**

[LOW]workflows/ci/sonarqube/sonarqube.yml:59 - Hardcoded PHP version
Confidence: Low
Description: PHP 8.3 is hardcoded in the workflow.
Impact: Teams using different PHP versions will need to modify the workflow.
Suggested Fix: Consider if this should be configurable via workflow input or better documented in the description.

📊 SOLID Principles Score

PrincipleScoreNotes
Single Responsibility9Workflow file, config file, and registry changes each have clear, focused purposes
Open/Closed8Registry extended to support .properties without modifying existing logic extensively
Liskov Substitution9New files follow existing workflow patterns; no inheritance issues
Interface Segregation9Metadata blocks are focused and don't force unused fields
Dependency Inversion8Registry depends on abstractions; workflow depends on external actions via interfaces
Average8.6

🎯 Final Assessment

Overall Confidence Score: 85%

Confidence Breakdown:

  • Code Quality: 90% (clean implementation, follows conventions)
  • Completeness: 85% (minor gap in .properties extension handling)
  • Risk Level: 80% (low risk but potential for ID collisions)
  • Test Coverage: 85% (existing tests pass, but edge case in grouping not covered)

Merge Readiness:

  • All critical issues resolved
  • SOLID average score >= 6.0 (8.6 achieved)
  • Overall confidence >= 60% (85% achieved)
  • No security concerns
  • Tests present and passing (30 existing tests pass)

Verdict:

MERGE WITH FIXES

The PR is well-implemented and follows established patterns. Fix the .properties extension handling in groupByBaseName (lines 307, 310) before merging to ensure proper file grouping. The ID collision warning is optional but recommended for robustness.

New%20session%20-%202026-02-12T23%3A55%3A57.621Z
opencode session | github run

@MichaelFisher1997
MichaelFisher1997 merged commit 58b9b7b into mainFeb 12, 2026
2 checks passed
Sign up for freeto 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.

1 participant

@MichaelFisher1997