chore: fix sonarqube issues #166
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |