Configure advisory Qodana analysis (#313)

## Summary

- configure advisory Qodana PHP 2026.1 analysis for trusted pull
requests and master, beta, canary, and internal branch scans
- install both Composer projects and the edge-agent/edge-broker Node
dependencies before analysis
- exclude generated, vendor, build, cache, legacy-test, and local-agent
trees
- keep Quick Fixes, SARIF artifacts, baselines, thresholds, and
required-check enforcement disabled during calibration

## Safety

- fails closed when QODANA_TOKEN is absent
- skips draft, fork, and Dependabot pull requests
- uses least-privilege GitHub permissions and immutable action SHAs
- uploads findings to the dedicated api Qodana Cloud project

## Validation

- actionlint 1.7.12
- SchemaStore qodana-1.0 validation
- bootstrap shell syntax and lockfile structure checks
- immutable action tag verification
- git diff --check
- independent review completed with no findings

## Live verification

- [PR-mode
scan](https://github.com/copenhagentruckwash/api/actions/runs/29494056175)
completed successfully with 0 changed-file problems, 439 inspections,
and a passed license audit ([Qodana
report](https://qodana.cloud/projects/P2nXd/reports/LJv98e))
- [full branch
scan](https://github.com/copenhagentruckwash/api/actions/runs/29495399119)
completed successfully and uploaded 8,248 current findings across 725
files, 439 inspections, and a passed license audit to the dedicated api
project ([Qodana
report](https://qodana.cloud/projects/P2nXd/reports/qJMOxX))
- the initial debt remains advisory; baseline and required-check
enforcement are intentionally deferred until findings are triaged
This commit is contained in:
Jeppe B
2026-07-16 14:35:59 +02:00
committed by GitHub
parent 511605b619
commit 6566027746
2 changed files with 78 additions and 70 deletions
+50 -30
View File
@@ -1,7 +1,18 @@
name: Qodana
on:
workflow_dispatch:
pull_request:
branches:
- master
- beta
- canary
- internal
types:
- opened
- reopened
- synchronize
- ready_for_review
push:
branches:
- master
@@ -9,46 +20,55 @@ on:
- canary
- internal
concurrency:
group: qodana-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
qodana:
# CI runs on the repository's self-hosted runner pool.
runs-on: [self-hosted, Linux, X64, pleno, backend, docker]
name: Qodana
if: >-
github.event_name != 'pull_request' ||
(
github.event.pull_request.draft == false &&
github.event.pull_request.head.repo.full_name == github.repository &&
github.event.pull_request.user.login != 'dependabot[bot]'
)
runs-on: ubuntu-24.04
timeout-minutes: 60
permissions:
contents: read
pull-requests: read
checks: read
checks: write
pull-requests: write
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }} # Use PR head when available, otherwise the pushed SHA.
fetch-depth: 0 # a full history is required for pull request analysis
persist-credentials: false
- name: Mark repository as safe for Git
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
- name: Prepare Qodana cache directories
run: |
mkdir -p "${RUNNER_TEMP}/qodana/caches"
mkdir -p "${RUNNER_TEMP}/qodana/results"
- name: Detect Qodana Cloud token
id: qodana-token
- name: Require Qodana Cloud token
env:
QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }}
shell: bash
run: |
if [ -n "${QODANA_TOKEN:-}" ]; then
echo "present=true" >> "$GITHUB_OUTPUT"
else
echo "present=false" >> "$GITHUB_OUTPUT"
set -euo pipefail
if [[ -z "${QODANA_TOKEN}" ]]; then
echo "::error::QODANA_TOKEN is not configured for this repository."
exit 1
fi
- name: 'Qodana Scan'
if: ${{ steps.qodana-token.outputs.present == 'true' }}
uses: JetBrains/qodana-action@v2026.1
- name: Check out the analyzed commit
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
pr-mode: false
ref: ${{ github.event.pull_request.head.sha || github.sha }}
fetch-depth: 0
persist-credentials: false
- name: Run Qodana
uses: JetBrains/qodana-action@4861e015da555e86a72b862892aba6c2b93e6891 # v2026.1.3
with:
pr-mode: ${{ github.event_name == 'pull_request' }}
use-caches: true
cache-default-branch-only: true
use-annotations: true
post-pr-comment: true
github-token: ${{ github.token }}
push-fixes: none
upload-result: false
env:
QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }}
QODANA_ENDPOINT: 'https://qodana.cloud'
- name: 'Skip Qodana Scan (missing cloud token)'
if: ${{ steps.qodana-token.outputs.present != 'true' }}
run: echo "Skipping Qodana because QODANA_TOKEN is not configured."
+28 -40
View File
@@ -1,46 +1,34 @@
#-------------------------------------------------------------------------------#
# Qodana analysis is configured by qodana.yaml file #
# https://www.jetbrains.com/help/qodana/qodana-yaml.html #
#-------------------------------------------------------------------------------#
#################################################################################
# WARNING: Do not store sensitive information in this file, #
# as its contents will be included in the Qodana report. #
#################################################################################
version: "1.0"
#Specify inspection profile for code analysis
linter: jetbrains/qodana-php:2026.1
profile:
name: qodana.starter
name: qodana.recommended
#Enable inspections
#include:
# - name: <SomeEnabledInspectionId>
php:
version: "8.2"
#Disable inspections
#exclude:
# - name: <SomeDisabledInspectionId>
# paths:
# - <path/where/not/run/inspection>
bootstrap: |+
set -eu
composer --working-dir=services/nginx/app install --no-interaction --prefer-dist --no-progress --ignore-platform-reqs
composer --working-dir=services/nginx/app/modules/washcertificates install --no-interaction --prefer-dist --no-progress --ignore-platform-reqs
npm --prefix services/edge-agent ci --ignore-scripts
npm --prefix services/edge-broker ci --ignore-scripts
#Execute shell command before Qodana execution (Applied in CI/CD pipeline)
#bootstrap: sh ./prepare-qodana.sh
#Install IDE plugins before Qodana execution (Applied in CI/CD pipeline)
#plugins:
# - id: <plugin.id> #(plugin id can be found at https://plugins.jetbrains.com)
# Quality gate. Will fail the CI/CD pipeline if any condition is not met
# severityThresholds - configures maximum thresholds for different problem severities
# testCoverageThresholds - configures minimum code coverage on a whole project and newly added code
# Code Coverage is available in Ultimate and Ultimate Plus plans
#failureConditions:
# severityThresholds:
# any: 15
# critical: 5
# testCoverageThresholds:
# fresh: 70
# total: 50
#Specify Qodana linter for analysis (Applied in CI/CD pipeline)
linter: jetbrains/qodana-php:2025.3
exclude:
- name: All
paths:
- services/nginx/app/vendor
- services/nginx/app/modules/washcertificates/vendor
- services/nginx/app/build
- services/nginx/app/.phpunit.cache
- services/nginx/app/tests/Legacy
- services/edge-agent/node_modules
- services/edge-broker/node_modules
- services/edge-agent/dist
- documentation/generated
- documentation/topics/generated
- documentation/_build
- documentation/_site_rebuild_20260317
- .tmp
- .openclaw