Skip to content

chore: fix sonarqube issues #166

chore: fix sonarqube issues

chore: fix sonarqube issues #166

Workflow file for this run

name: Continuous Integration & Version and Tag
env:
GIT_FAKE_EMAIL: [email protected]
GIT_FAKE_USER: dt-dds
on:
push:
branches:
- main
pull_request:
branches:
- main
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.ref_name }}
cancel-in-progress: true
jobs:
check-fixups:
runs-on: ubuntu-latest
if: ${{ !contains(github.event.head_commit.message, 'release:') }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Check fixups commits
shell: bash
run: |
fixups=$(git log --oneline origin/main..HEAD -- | grep -e "fixup! " || true)
if [ -z "$fixups" ]; then
echo "Does not have fixups"
exit 0
else
RED='\033[0;31m'
NC='\033[0m' # No Color
echo -e "${RED}$fixups${NC}"
exit 1
fi
lint:
runs-on: ubuntu-latest
if: ${{ !contains(github.event.head_commit.message, 'release:') }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup node and yarn
uses: './.github/actions/yarn-node-install'
with:
CACHE_FILE_NAME: 'global'
- name: Run Lint
run: yarn lint
tests:
runs-on: ubuntu-latest
if: ${{ !contains(github.event.head_commit.message, 'release:') }}
needs: lint
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup node and yarn
uses: './.github/actions/yarn-node-install'
with:
CACHE_FILE_NAME: 'global'
- name: Run Tests
run: yarn test
- name: Consolidate Coverage Reports
run: |
echo "Consolidating coverage reports for SonarQube..."
echo "================================================="
# Create consolidated coverage directory
mkdir -p sonar-coverage
# Find all lcov.info files
echo "1. Finding coverage reports..."
coverage_files=$(find packages -name "lcov.info" -type f)
echo "Found coverage files:"
echo "$coverage_files"
if [ -z "$coverage_files" ]; then
echo "No coverage files found!"
exit 1
fi
# Consolidate all lcov.info files into one with corrected paths
echo ""
echo "2. Consolidating coverage reports with absolute paths..."
consolidated_file="sonar-coverage/lcov.info"
# Process each file and fix paths
for file in $coverage_files; do
if [ -f "$file" ] && [ -s "$file" ]; then
echo "Processing $file"
# Get the package directory (e.g., packages/react-packages/tabs from packages/react-packages/tabs/jest-coverage/lcov.info)
package_dir=$(dirname $(dirname $file))
echo " Package directory: $package_dir"
# Process the lcov file and update paths to be relative to project root
sed "s|^SF:src/|SF:$package_dir/src/|g; s|^SF:dist/|SF:$package_dir/dist/|g; s|^SF:lib/|SF:$package_dir/lib/|g; s|^SF:build/|SF:$package_dir/build/|g" "$file" >> "$consolidated_file"
fi
done
echo "Consolidated coverage report created: $consolidated_file"
# Show summary
echo ""
echo "3. Coverage report summary:"
if [ -f "$consolidated_file" ]; then
lines=$(wc -l < "$consolidated_file")
echo "Total lines in consolidated report: $lines"
# Show first few lines
echo "First 10 lines:"
head -10 "$consolidated_file"
else
echo "Consolidated file not created!"
exit 1
fi
echo "Coverage consolidation completed!"
- name: Upload Coverage Artifact
uses: actions/upload-artifact@v4
with:
name: sonar-coverage
path: sonar-coverage/**
blackduck-scan:
runs-on: ubuntu-latest
if: ${{ !contains(github.event.head_commit.message, 'release:') }}
timeout-minutes: 30
needs: tests
env:
BLACKDUCK_URL: ${{ vars.BLACKDUCK_URL }}
BLACKDUCK_PROJECT: ${{ vars.BLACKDUCK_PROJECT_NAME }}
BLACKDUCK_TOKEN: ${{ secrets.BLACKDUCK_TOKEN }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup node and yarn
uses: './.github/actions/yarn-node-install'
with:
CACHE_FILE_NAME: 'global'
- name: Set up Java 11
uses: actions/setup-java@v3
with:
java-version: '11'
distribution: temurin
- name: Extract version
id: pkg
run: |
echo "VERSION=$(jq -r .version packages/dt-dds-react/package.json)" >> $GITHUB_OUTPUT
- name: Versions Cleanup
run: |
# Get the bearer token to communicate with the API
echo "Fetching bearer token..."
bearer_token=$(
curl -s -X POST \
-H "Authorization: token $BLACKDUCK_TOKEN" \
$BLACKDUCK_URL/api/tokens/authenticate |
jq -er .bearerToken
)
# Get the project base URL
echo "Fetching base project URL for $BLACKDUCK_PROJECT..."
base_url=$(
curl -s -X GET \
-H "Authorization: Bearer ${bearer_token}" \
"$BLACKDUCK_URL/api/projects?q=name:$BLACKDUCK_PROJECT" |
jq -er ".items[0]._meta.href"
)
# List the versions and maybe delete the oldest one if needed
echo "Base project URL for $BLACKDUCK_PROJECT is ${base_url}, now listing versions..."
version_to_delete=$(
curl -s -X GET \
-H "Authorization: Bearer ${bearer_token}" \
"${base_url}/versions" |
jq -r '.items |= sort_by(.createdAt) | if .totalCount >= 10 then .items[0]._meta.href else "" end'
)
if [[ -z $version_to_delete ]]; then
echo "No version to delete, doing nothing."
else
echo "The limit of versions has been reached, going to delete version ${version_to_delete}."
curl -s -X DELETE \
-H "Authorization: Bearer ${bearer_token}" \
"${version_to_delete}"
fi
- name: Run Blackduck Scan
uses: blackduck-inc/black-duck-security-scan@v2
env:
DETECT_PROJECT_NAME: ${{ env.BLACKDUCK_PROJECT }}
DETECT_PROJECT_VERSION_NAME: ${{ steps.pkg.outputs.VERSION }}
with:
blackducksca_url: ${{ env.BLACKDUCK_URL }}
blackducksca_token: ${{ env.BLACKDUCK_TOKEN }}
blackducksca_scan_failure_severities: 'BLOCKER,CRITICAL'
blackducksca_scan_full: ${{ github.ref == 'refs/heads/main' }}
blackducksca_prComment_enabled: false
detect_args: '--logging.level.detect=DEBUG --detect.blackduck.rapid.compare.mode=ALL --detect.project.version.phase=RELEASED --detect.project.version.distribution=OPENSOURCE --detect.yarn.dependency.types.excluded=NON_PRODUCTION'
github_token: ${{ secrets.GITHUB_TOKEN }}
sonarqube-scan:
runs-on: ubuntu-latest
if: ${{ !contains(github.event.head_commit.message, 'release:') }}
needs: tests
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup node and yarn
uses: './.github/actions/yarn-node-install'
with:
CACHE_FILE_NAME: 'global'
- name: Download Coverage Artifact
uses: actions/download-artifact@v4
with:
name: sonar-coverage
path: sonar-coverage
- name: Prepare SonarQube Scan
run: |
echo "sonar.projectKey=${{ secrets.SONAR_PROJECT_KEY }}" > sonar-project.properties
echo "sonar.projectName=${{ secrets.SONAR_PROJECT_NAME }}" >> sonar-project.properties
echo "sonar.sources=packages" >> sonar-project.properties
echo "sonar.exclusions=**/node_modules/**,**/dist/**,**/jest-coverage/**,**/*.test.ts,**/*.test.tsx,**/*.spec.ts,**/*.spec.tsx,**/*.tokens.json,**/tokens/**,**/static/**,**/storybook-static/**,**/*.md,**/*.mdx,**/*.json,**/*.yml,**/*.yaml,**/*.config.js,**/*.config.ts,**/*.config.json,**/babel.config.js,**/jest.config.ts,**/tsconfig.json,**/tsup.config.ts,**/prettier.config.js,**/commitlint.config.js,**/turbo.json,**/yarn.lock,**/package-lock.json,**/pnpm-lock.yaml,**/*.lock,**/LICENSE.md,**/README.md,**/CHANGELOG.md,**/CONTRIBUTING.md,**/CODE_OF_CONDUCT.md,**/*.png,**/*.jpg,**/*.jpeg,**/*.gif,**/*.svg,**/*.ico,**/*.woff,**/*.woff2,**/*.ttf,**/*.otf,**/*.eot,packages/themes/src/tokens/**" >> sonar-project.properties
echo "sonar.test.inclusions=**/*.test.ts,**/*.test.tsx,**/*.spec.ts,**/*.spec.tsx" >> sonar-project.properties
echo "sonar.coverage.exclusions=**/*.test.ts,**/*.test.tsx,**/*.spec.ts,**/*.spec.tsx,**/node_modules/**,**/*.tokens.json,**/tokens/**,**/static/**,**/storybook-static/**,packages/themes/src/tokens/**" >> sonar-project.properties
echo "sonar.typescript.lcov.reportPaths=sonar-coverage/lcov.info" >> sonar-project.properties
echo "sonar.javascript.lcov.reportPaths=sonar-coverage/lcov.info" >> sonar-project.properties
echo "sonar.log.level=DEBUG" >> sonar-project.properties
# Configure PR or branch analysis for New Code metrics
if [ "${{ github.event_name }}" = "pull_request" ]; then
echo "sonar.pullrequest.key=${{ github.event.pull_request.number }}" >> sonar-project.properties
echo "sonar.pullrequest.branch=${{ github.head_ref }}" >> sonar-project.properties
echo "sonar.pullrequest.base=${{ github.base_ref }}" >> sonar-project.properties
else
echo "sonar.branch.name=${{ github.ref_name }}" >> sonar-project.properties
echo "sonar.newCode.referenceBranch=main" >> sonar-project.properties
fi
echo "SonarQube Configuration:"
cat sonar-project.properties
- name: Run SonarQube Scan
uses: sonarsource/[email protected]
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: ${{ secrets.SONAR_URL }}
- name: Run SonarQube Quality Gate check
run: |
echo "Waiting for SonarQube analysis to complete..."
sleep 30
# Query gate for PRs or branches accordingly
if [ "${{ github.event_name }}" = "pull_request" ]; then
gate_response=$(curl -s -u "${{ secrets.SONAR_TOKEN }}:" \
"${{ secrets.SONAR_URL }}/api/qualitygates/project_status?projectKey=${{ secrets.SONAR_PROJECT_KEY }}&pullRequest=${{ github.event.pull_request.number }}")
else
gate_response=$(curl -s -u "${{ secrets.SONAR_TOKEN }}:" \
"${{ secrets.SONAR_URL }}/api/qualitygates/project_status?projectKey=${{ secrets.SONAR_PROJECT_KEY }}&branch=${{ github.ref_name }}")
fi
gate_status=$(echo "$gate_response" | jq -r '.projectStatus.status')
echo "Quality Gate Status: $gate_status"
if [ "$gate_status" != "OK" ]; then
echo ""
echo "Quality Gate Failed: $gate_status"
echo "======================================"
echo "Quality Gate Conditions:"
echo "$gate_response" | jq -r '.projectStatus.conditions[] | " \(.metricKey): \(.status) (\(.actualValue)/\(.errorThreshold))"'
echo "Issues causing the failure:"
echo "============================"
curl -s -u "${{ secrets.SONAR_TOKEN }}:" \
"${{ secrets.SONAR_URL }}/api/issues/search?componentKeys=${{ secrets.SONAR_PROJECT_KEY }}&severities=BLOCKER,CRITICAL,MAJOR" \
| jq -r '.issues[] | "\(.severity): \(.message) [\(.component):\(.line)]"' \
| head -20
exit 1
else
echo "Quality Gate Passed!"
echo "No new issues introduced in this analysis."
fi
build:
runs-on: ubuntu-latest
if: ${{ !contains(github.event.head_commit.message, 'release:') }}
needs: [blackduck-scan, sonarqube-scan]
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup node and yarn
uses: './.github/actions/yarn-node-install'
with:
CACHE_FILE_NAME: 'global'
- name: Run Build
run: yarn run turbo build --filter='./packages/*'
generate-version-tag:
needs: [check-fixups, lint, tests, blackduck-scan, sonarqube-scan, build]
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main' && !contains(github.event.head_commit.message, 'release:')
steps:
- name: Generate CI_BOT Token
id: ci-bot-token
uses: actions/create-github-app-token@v2
with:
app-id: ${{ secrets.CI_BOT_ID }}
private-key: ${{ secrets.CI_BOT_PRIVATE_KEY }}
- name: Checkout branch
uses: actions/checkout@v4
with:
ref: ${{ github.ref }}
fetch-depth: 0
token: ${{ steps.ci-bot-token.outputs.token }}
- name: Setup node and yarn
uses: './.github/actions/yarn-node-install'
with:
CACHE_FILE_NAME: 'global'
- name: Setup fake credentials
run: |
git config --global user.email ${{ env.GIT_FAKE_EMAIL }}
git config --global user.name ${{ env.GIT_FAKE_USER }}
- name: Run build for changeset plugin
run: yarn run turbo build --filter=changeset-conventional-commits
- name: Bump affected packages version and tag
run: |
yarn changesets:ci
git push origin ${{ github.ref }}
git push origin --tags