feat(ci): add CI/CD workflow with ESLint, TypeScript, tests, SonarQub…#182
Conversation
…e and CodeRabbit Closes vallabhatech#28 Signed-off-by: Your Name samalbishnupriya.06@gmail.com
|
@samalbishnupriya06-stack is attempting to deploy a commit to the vallabhatech's projects Team on Vercel. A member of the Team first needs to authorize it. |
📝 WalkthroughWalkthroughReplaces the minimal single-job CI workflow with a four-job pipeline (lint, typecheck, test, pr-comment). Adds a dependency review workflow and rewrites the SonarQube workflow to include Node setup and coverage before scanning. Adds ChangesCI/CD Pipeline and Quality Gate Setup
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related issues
Suggested reviewers
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
There was a problem hiding this comment.
Actionable comments posted: 11
🧹 Nitpick comments (1)
.github/coderabbit.yml (1)
28-31: ⚡ Quick winBroaden test path instructions to cover common test filename patterns.
Current test instructions only apply to
**/*.test.ts, so TSX/spec-style tests won’t receive the test-focused review guidance.Suggested update
path_instructions: @@ - - path: "**/*.test.ts" + - path: "**/*.test.ts" + instructions: | + Ensure tests are meaningful with proper assertions. + Check for edge cases and error scenarios. + - path: "**/*.test.tsx" + instructions: | + Ensure tests are meaningful with proper assertions. + Check for edge cases and error scenarios. + - path: "**/*.spec.ts" + instructions: | + Ensure tests are meaningful with proper assertions. + Check for edge cases and error scenarios. + - path: "**/*.spec.tsx" instructions: | Ensure tests are meaningful with proper assertions. Check for edge cases and error scenarios.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/coderabbit.yml around lines 28 - 31, The test path pattern in the instructions section only matches `**/*.test.ts` files, which excludes other common test filename conventions like spec files and TSX test files. Broaden the path pattern to cover multiple test file naming patterns including `.test.ts`, `.spec.ts`, `.test.tsx`, and `.spec.tsx` extensions so that all test files receive the meaningful assertions and edge case review guidance regardless of their naming convention.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/CONTRIBUTING_CI.md:
- Around line 9-11: Update the trigger descriptions in the CI Pipeline table to
be more explicit about branch targeting. The SonarQube Analysis and Dependency
Review workflow rows currently say "Every PR" but should specify that they only
run on PRs targeting `main` or `develop` branches, whereas the CI Pipeline
workflow in the first row runs on every PR. Replace the "Every PR" text in the
SonarQube Analysis and Dependency Review rows with wording that clearly
indicates the branch restriction to avoid contributor confusion.
- Line 51: The documented npm test command in the CONTRIBUTING_CI.md file does
not include the --coverage and --ci flags that are used in CI, which can lead to
local tests passing while CI fails. Update the npm test command to include both
the --coverage and --ci flags so developers run tests with the same
configuration as CI and catch any coverage or CI-mode specific issues locally
before pushing.
- Around line 10-27: Update the workflow file reference in the table row for
SonarQube Analysis on line 10 from `.github/workflows/sonarqube.yml` to
`.github/workflows/sonarcloud.yml` to match the SonarCloud setup instructions
provided in the "Getting SonarQube credentials (SonarCloud — free for open
source)" section that follows. This ensures consistency between the documented
workflow file and the actual SonarCloud configuration steps that contributors
are directed to follow.
In @.github/workflows/ci.yml:
- Around line 9-13: Move the `pull-requests: write` and `checks: write`
permissions from the workflow-wide permissions block (currently at lines 9-13)
to job-level permissions. Keep the workflow-level permissions block with only
`contents: read` for all jobs. Add a `permissions` section to the `pr-comment`
job that specifically grants `pull-requests: write` and `checks: write` to that
job alone. Review all instances of permissions blocks in the workflow (including
the section at lines 114-140) to ensure write permissions are scoped only to the
jobs that require them.
- Around line 118-119: The GitHub Actions workflow unconditionally posts
comments to PRs, which fails on forked PRs due to read-only GITHUB_TOKEN
permissions. Add a conditional guard to the comment-posting job or steps to
check if the PR originates from a fork using
github.event.pull_request.head.repo.fork, and skip the comment steps when true.
Alternatively, wrap the comment-posting steps in error handling that catches API
failures gracefully without causing the job to fail. Apply this fix to all
comment-posting steps in the workflow, including those around lines 118-119 and
the additional locations mentioned in the range 138-196.
- Around line 20-23: Replace all mutable tag references in the GitHub Actions
workflow files with their corresponding immutable commit SHAs. For each action
reference (such as actions/checkout@v4, actions/setup-node@v4, and others listed
on the affected lines across ci.yml, summary.yml, sonarqube.yml, codeql.yml,
dependency-review.yml, and other workflow files), change the `@version` tag format
to the full 40-character commit SHA format. Look up the commit SHA for each
specific version of each action and replace the tag-based reference with the
pinned commit SHA to ensure supply chain security and prevent potential
unauthorized retargeting by maintainers.
In @.github/workflows/dependency-review.yml:
- Around line 18-22: Replace the tag-pinned action references with full-length
commit SHAs for both the actions/checkout action (currently `@v4`) and the
actions/dependency-review-action action (currently `@v4`). Additionally, add
persist-credentials: false to the checkout step to disable credential
persistence and prevent the GITHUB_TOKEN from being accessible in subsequent
steps. You may optionally include version tags in comments next to the commit
SHAs for documentation purposes.
In @.github/workflows/sonarqube.yml:
- Around line 35-62: The sonarqube job is missing explicit permission
declarations, which causes it to use default elevated permissions. Add a
permissions block at the same indentation level as the name, runs-on, and steps
properties in the sonarqube job. Set the permissions to contents: read to grant
only the minimal required permission for checking out the code, following the
principle of least privilege for workflow token scopes.
- Line 41: Replace the mutable version tags in the workflow actions with
immutable commit SHAs for improved supply-chain security. Update the three
action references: actions/checkout@v4 on line 41, actions/setup-node@v4 on line
46, and SonarSource/sonarqube-scan-action@v5 on line 59 by replacing the version
tag (e.g., `@v4`) with the full commit SHA hash for each action to pin them to
specific, immutable versions.
In `@sonar-project.properties`:
- Line 1: The sonar.projectKey property at the beginning of the
sonar-project.properties file has a BOM (Byte Order Mark) character prefix that
can cause parsing issues. Remove the BOM character that appears before the
sonar.projectKey=vallabhatech_CareSync property by re-saving the file with UTF-8
encoding without BOM, ensuring the file starts directly with the 's' character
of 'sonar'.
- Around line 6-10: The sonar.test.inclusions property is configured to only
match TypeScript test files (.test.ts and .spec.ts), but the repository uses
JavaScript test files (.test.js and .spec.js). Update the sonar.test.inclusions
value to include both JavaScript and TypeScript test file patterns by adding
**/*.test.js and **/*.spec.js alongside the existing TypeScript patterns,
separated by commas, so that Sonar can properly detect and analyze all actual
test files in the repository.
---
Nitpick comments:
In @.github/coderabbit.yml:
- Around line 28-31: The test path pattern in the instructions section only
matches `**/*.test.ts` files, which excludes other common test filename
conventions like spec files and TSX test files. Broaden the path pattern to
cover multiple test file naming patterns including `.test.ts`, `.spec.ts`,
`.test.tsx`, and `.spec.tsx` extensions so that all test files receive the
meaningful assertions and edge case review guidance regardless of their naming
convention.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 3f2fb127-f441-4476-a3cf-65187b4a8adf
📒 Files selected for processing (6)
.github/CONTRIBUTING_CI.md.github/coderabbit.yml.github/workflows/ci.yml.github/workflows/dependency-review.yml.github/workflows/sonarqube.ymlsonar-project.properties
| | CI Pipeline (Lint + TypeScript + Tests) | `.github/workflows/ci.yml` | Every PR | | ||
| | SonarQube Analysis | `.github/workflows/sonarqube.yml` | Every PR | | ||
| | Dependency Review | `.github/workflows/dependency-review.yml` | Every PR | |
There was a problem hiding this comment.
Workflow trigger descriptions are too broad.
These rows say “Every PR”, but the Sonar and dependency-review workflows are described in this PR context as PRs targeting main/develop. Please make the table explicit to avoid contributor confusion.
Suggested wording
-| SonarQube Analysis | `.github/workflows/sonarqube.yml` | Every PR |
-| Dependency Review | `.github/workflows/dependency-review.yml` | Every PR |
+| SonarQube Analysis | `.github/workflows/sonarqube.yml` | PRs to `main` and `develop` |
+| Dependency Review | `.github/workflows/dependency-review.yml` | PRs to `main` and `develop` |📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| | CI Pipeline (Lint + TypeScript + Tests) | `.github/workflows/ci.yml` | Every PR | | |
| | SonarQube Analysis | `.github/workflows/sonarqube.yml` | Every PR | | |
| | Dependency Review | `.github/workflows/dependency-review.yml` | Every PR | | |
| | CI Pipeline (Lint + TypeScript + Tests) | `.github/workflows/ci.yml` | Every PR | | |
| | SonarQube Analysis | `.github/workflows/sonarqube.yml` | PRs to `main` and `develop` | | |
| | Dependency Review | `.github/workflows/dependency-review.yml` | PRs to `main` and `develop` | |
🧰 Tools
🪛 LanguageTool
[uncategorized] ~9-~9: The official name of this software platform is spelled with a capital “H”.
Context: ... Pipeline (Lint + TypeScript + Tests) | .github/workflows/ci.yml | Every PR | | SonarQ...
(GITHUB)
[uncategorized] ~10-~10: The official name of this software platform is spelled with a capital “H”.
Context: ...ml| Every PR | | SonarQube Analysis |.github/workflows/sonarqube.yml` | Every PR | |...
(GITHUB)
[uncategorized] ~11-~11: The official name of this software platform is spelled with a capital “H”.
Context: ...yml| Every PR | | Dependency Review |.github/workflows/dependency-review.yml` | Ever...
(GITHUB)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/CONTRIBUTING_CI.md around lines 9 - 11, Update the trigger
descriptions in the CI Pipeline table to be more explicit about branch
targeting. The SonarQube Analysis and Dependency Review workflow rows currently
say "Every PR" but should specify that they only run on PRs targeting `main` or
`develop` branches, whereas the CI Pipeline workflow in the first row runs on
every PR. Replace the "Every PR" text in the SonarQube Analysis and Dependency
Review rows with wording that clearly indicates the branch restriction to avoid
contributor confusion.
| | SonarQube Analysis | `.github/workflows/sonarqube.yml` | Every PR | | ||
| | Dependency Review | `.github/workflows/dependency-review.yml` | Every PR | | ||
|
|
||
| ## Required GitHub Secrets | ||
|
|
||
| Go to **Settings → Secrets and variables → Actions** and add: | ||
|
|
||
| | Secret | Description | | ||
| |--------|-------------| | ||
| | `SONAR_TOKEN` | Your SonarQube authentication token | | ||
| | `SONAR_HOST_URL` | Your SonarQube server URL (e.g. `https://sonarcloud.io`) | | ||
|
|
||
| ### Getting SonarQube credentials (SonarCloud — free for open source) | ||
| 1. Go to [sonarcloud.io](https://sonarcloud.io) and sign in with GitHub. | ||
| 2. Click **+** → **Analyze new project** → select `vallabhatech/CareSync`. | ||
| 3. Copy the **Project Key** into `sonar-project.properties`. | ||
| 4. Generate a token under **My Account → Security** and add it as `SONAR_TOKEN`. | ||
| 5. Set `SONAR_HOST_URL` to `https://sonarcloud.io`. |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== Sonar-related workflow files =="
fd -a 'sonar.*\.ya?ml' .github/workflows || true
echo
echo "== Sonar workflow triggers and key config (context) =="
rg -n -C3 'name:|on:|pull_request|SONAR_|sonar\.projectKey|sonar\.organization|uses:\s*SonarSource' .github/workflows || true
echo
echo "== Contributor doc references =="
rg -n -C2 'sonar|SONAR_|workflow' .github/CONTRIBUTING_CI.md || trueRepository: vallabhatech/CareSync
Length of output: 49251
Update workflow file reference in CONTRIBUTING_CI.md to match SonarCloud setup instructions.
The documentation at line 10 references .github/workflows/sonarqube.yml, but the setup guide (lines 22–27) directs contributors to SonarCloud (sonarcloud.io), which requires .github/workflows/sonarcloud.yml. The two workflows are distinct: sonarcloud.yml uses SonarCloud's managed service with sonar.projectKey and sonar.organization parameters, while sonarqube.yml is for self-hosted SonarQube with SONAR_HOST_URL. Update line 10 to reference .github/workflows/sonarcloud.yml to align with the SonarCloud-specific instructions that follow.
🧰 Tools
🪛 LanguageTool
[uncategorized] ~10-~10: The official name of this software platform is spelled with a capital “H”.
Context: ...ml| Every PR | | SonarQube Analysis |.github/workflows/sonarqube.yml` | Every PR | |...
(GITHUB)
[uncategorized] ~11-~11: The official name of this software platform is spelled with a capital “H”.
Context: ...yml| Every PR | | Dependency Review |.github/workflows/dependency-review.yml` | Ever...
(GITHUB)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/CONTRIBUTING_CI.md around lines 10 - 27, Update the workflow file
reference in the table row for SonarQube Analysis on line 10 from
`.github/workflows/sonarqube.yml` to `.github/workflows/sonarcloud.yml` to match
the SonarCloud setup instructions provided in the "Getting SonarQube credentials
(SonarCloud — free for open source)" section that follows. This ensures
consistency between the documented workflow file and the actual SonarCloud
configuration steps that contributors are directed to follow.
Source: Coding guidelines
| npx tsc --noEmit | ||
|
|
||
| # Tests | ||
| npm test |
There was a problem hiding this comment.
Align local test command with CI flags.
CI runs tests with --coverage --ci; documenting only npm test can let local checks pass while CI fails on coverage/CI-mode behavior.
Suggested update
-# Tests
-npm test
+# Tests (match CI behavior)
+npm test -- --coverage --ci📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| npm test | |
| # Tests (match CI behavior) | |
| npm test -- --coverage --ci |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/CONTRIBUTING_CI.md at line 51, The documented npm test command in
the CONTRIBUTING_CI.md file does not include the --coverage and --ci flags that
are used in CI, which can lead to local tests passing while CI fails. Update the
npm test command to include both the --coverage and --ci flags so developers run
tests with the same configuration as CI and catch any coverage or CI-mode
specific issues locally before pushing.
| permissions: | ||
| contents: read | ||
| pull-requests: write | ||
| checks: write | ||
|
|
There was a problem hiding this comment.
Scope GitHub token permissions to the commenting job only.
pull-requests: write and checks: write are granted workflow-wide, but only the PR comment step needs write access. Keep workflow/job defaults read-only and grant write only to pr-comment to reduce token abuse risk.
Suggested hardening diff
permissions:
contents: read
- pull-requests: write
- checks: write
jobs:
lint:
+ permissions:
+ contents: read
name: ESLint Check
@@
typecheck:
+ permissions:
+ contents: read
name: TypeScript Validation
@@
test:
+ permissions:
+ contents: read
name: Automated Tests
@@
pr-comment:
+ permissions:
+ contents: read
+ pull-requests: write
name: PR Feedback CommentAlso applies to: 114-140
🧰 Tools
🪛 zizmor (1.25.2)
[error] 11-11: overly broad permissions (excessive-permissions): pull-requests: write is overly broad at the workflow level
(excessive-permissions)
[warning] 12-12: overly broad permissions (excessive-permissions): checks: write is overly broad at the workflow level
(excessive-permissions)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/ci.yml around lines 9 - 13, Move the `pull-requests:
write` and `checks: write` permissions from the workflow-wide permissions block
(currently at lines 9-13) to job-level permissions. Keep the workflow-level
permissions block with only `contents: read` for all jobs. Add a `permissions`
section to the `pr-comment` job that specifically grants `pull-requests: write`
and `checks: write` to that job alone. Review all instances of permissions
blocks in the workflow (including the section at lines 114-140) to ensure write
permissions are scoped only to the jobs that require them.
Source: Linters/SAST tools
| uses: actions/checkout@v4 | ||
|
|
||
| - name: Setup Node.js | ||
| uses: actions/setup-node@v4 |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify all non-SHA action references in workflow files.
rg -nP '^\s*uses:\s*[^@]+@(?!(?:[a-f0-9]{40})\b)' .github/workflows/*.ymlRepository: vallabhatech/CareSync
Length of output: 2529
Pin third-party actions to immutable commit SHAs instead of mutable tag references.
Tag references like @v4, @v7, and @v9 can be retargeted by maintainers. For better supply chain security, all actions should be pinned to specific commit SHAs (40-character hex strings). This applies throughout the workflow files, not just the lines shown below.
Affected in ci.yml: lines 20, 23, 39, 53, 56, 72, 86, 89, 105, 121, 127, 133, 139. Also found in: summary.yml, sonarqube.yml, codeql.yml, dependency-review.yml, and others.
🧰 Tools
🪛 zizmor (1.25.2)
[error] 20-20: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
[error] 23-23: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/ci.yml around lines 20 - 23, Replace all mutable tag
references in the GitHub Actions workflow files with their corresponding
immutable commit SHAs. For each action reference (such as actions/checkout@v4,
actions/setup-node@v4, and others listed on the affected lines across ci.yml,
summary.yml, sonarqube.yml, codeql.yml, dependency-review.yml, and other
workflow files), change the `@version` tag format to the full 40-character commit
SHA format. Look up the commit SHA for each specific version of each action and
replace the tag-based reference with the pinned commit SHA to ensure supply
chain security and prevent potential unauthorized retargeting by maintainers.
Source: Linters/SAST tools
| - name: Checkout code | ||
| uses: actions/checkout@v4 | ||
|
|
||
| - name: Dependency Review | ||
| uses: actions/dependency-review-action@v4 |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify unpinned workflow actions and missing persist-credentials hardening.
set -euo pipefail
echo "== Unpinned uses (tag/branch refs) =="
rg -nP '^\s*uses:\s*[^@]+@(?![0-9a-fA-F]{40}\b).+$' .github/workflows
echo
echo "== Checkout steps missing persist-credentials:false context =="
rg -nP '^\s*uses:\s*actions/checkout@' .github/workflows -A4 -B1Repository: vallabhatech/CareSync
Length of output: 5612
🏁 Script executed:
cat -n .github/workflows/dependency-review.yml | head -30Repository: vallabhatech/CareSync
Length of output: 716
🌐 Web query:
GitHub Actions best practices SHA pinning credential persistence security
💡 Result:
To secure GitHub Actions workflows, adhere to the following best practices regarding SHA pinning and credential management. SHA Pinning Pin all third-party GitHub Actions to a full-length commit SHA [1][2][3]. Referencing actions by mutable tags (e.g., @v1) or branches is a significant security risk because these references can be silently updated or force-pushed by an attacker who compromises the maintainer's account, causing your workflows to execute malicious code without any changes to your repository [2][4][5]. While commit SHAs are immutable and provide cryptographic assurance, you should maintain readability by including the version tag in a comment (e.g., uses: owner/repo@sha # v1.2.3) [1][3]. Automation tools like Dependabot or Renovate can be configured to automatically create pull requests for SHA updates, balancing security with ease of maintenance [2][3][5]. Credential Persistence and Security To prevent the accidental exposure or misuse of credentials, implement the following: 1. Disable Credential Persistence: When using the actions/checkout action, set persist-credentials to false [6][7][3]. This prevents the action from storing the GITHUB_TOKEN or other credentials in the local.git/config file, which could otherwise be accessed by subsequent steps in the same workflow [7][3]. Only enable this if your workflow requires authenticated git operations (e.g., pushing code back to the repository) [6][7]. 2. Use OIDC for Cloud Authentication: Eliminate the use of long-lived static credentials (e.g., cloud access keys, personal access tokens) in your workflows [6][2][8]. Instead, leverage OpenID Connect (OIDC) to obtain short-lived, dynamic tokens from your cloud provider [6][2][9]. 3. Principle of Least Privilege: Configure the GITHUB_TOKEN with the minimum required permissions [1][10]. Use the permissions key at the workflow or job level to explicitly set defaults (e.g., permissions: contents: read) and only grant higher privileges to specific jobs that require them [1][3][10]. 4. Mask Sensitive Data: Never store secrets in plain text [11][10]. Any sensitive information that is not an official GitHub secret should be explicitly masked using the::add-mask:: workflow command to prevent it from appearing in logs [10]. These practices form a defense-in-depth strategy, protecting your CI/CD pipelines against supply chain attacks and credential theft [2][8].
Citations:
- 1: https://github.com/github/docs/blob/962a1c8dccb8c0f66548b324e5b921b5e4fbc3d6/content/actions/security-for-github-actions/security-guides/security-hardening-for-github-actions.md
- 2: https://devopsil.com/articles/2026-03-22-github-actions-security-hardening
- 3: https://getplumber.io/blog/harden-github-supply-chain
- 4: https://sebastion.dev/intelligence/2026-03-12-poc-supply-chain-compromise-via-mutable-git-tag-poisoning
- 5: https://www.systemshardening.com/articles/cicd/github-actions-trivy-compromise/
- 6: https://cheatsheetseries.owasp.org/cheatsheets/GitHub_Actions_Security_Cheat_Sheet.html
- 7: https://adaptive-enforcement-lab.com/secure/github-actions-security/third-party-actions/common-actions/
- 8: https://www.stepsecurity.io/blog/github-actions-security-best-practices
- 9: https://github.com/github/docs/blob/main/content/actions/how-tos/secure-your-work/security-harden-deployments/index.md
- 10: https://github.com/github/docs/blob/main/content/actions/reference/security/secure-use.md
- 11: https://docs.github.com/en/enterprise-server@2.22/actions/security-guides/security-hardening-for-github-actions
Pin actions to commit SHAs and disable credential persistence.
Lines 19 and 22 use tag-pinned action references (@v4) instead of commit SHAs, and the checkout step does not disable credential persistence. Tag-based references are mutable and create a supply-chain attack window where compromised maintainer accounts can silently inject malicious code. The default credential persistence also allows subsequent steps to access the GITHUB_TOKEN from git config.
Replace tag refs with full-length commit SHAs (optionally documented with version tags in comments for readability) and add persist-credentials: false to the checkout step:
- name: Checkout code
uses: actions/checkout@v4
+ with:
+ persist-credentials: false
- name: Dependency Review
- uses: actions/dependency-review-action@v4
+ uses: actions/dependency-review-action@<COMMIT_SHA>
with:
fail-on-severity: high
comment-summary-in-pr: always🧰 Tools
🪛 zizmor (1.25.2)
[warning] 18-19: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
[error] 19-19: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
[error] 22-22: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/dependency-review.yml around lines 18 - 22, Replace the
tag-pinned action references with full-length commit SHAs for both the
actions/checkout action (currently `@v4`) and the actions/dependency-review-action
action (currently `@v4`). Additionally, add persist-credentials: false to the
checkout step to disable credential persistence and prevent the GITHUB_TOKEN
from being accessible in subsequent steps. You may optionally include version
tags in comments next to the commit SHAs for documentation purposes.
Source: Linters/SAST tools
| jobs: | ||
| Analysis: | ||
| sonarqube: | ||
| name: SonarQube Scan | ||
| runs-on: ubuntu-latest | ||
|
|
||
| steps: | ||
| - name: Analyze with SonarQube | ||
| - name: Checkout code | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| fetch-depth: 0 # Required for SonarQube blame data | ||
|
|
||
| # You can pin the exact commit or the version. | ||
| # uses: SonarSource/sonarqube-scan-action@v1.1.0 | ||
| uses: SonarSource/sonarqube-scan-action@7295e71c9583053f5bf40e9d4068a0c974603ec8 | ||
| env: | ||
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information | ||
| SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} # Generate a token on SonarQube, add it to the secrets of this repo with the name SONAR_TOKEN (Settings > Secrets > Actions > add new repository secret) | ||
| SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} # add the URL of your instance to the secrets of this repo with the name SONAR_HOST_URL (Settings > Secrets > Actions > add new repository secret) | ||
| - name: Setup Node.js | ||
| uses: actions/setup-node@v4 | ||
| with: | ||
| # Additional arguments for the sonarcloud scanner | ||
| args: | ||
| # Unique key of your project. You can find it in SonarQube > [my project] > Project Information (top-right menu) | ||
| # mandatory | ||
| -Dsonar.projectKey= | ||
| # Comma-separated paths to directories containing main source files. | ||
| #-Dsonar.sources= # optional, default is project base directory | ||
| # When you need the analysis to take place in a directory other than the one from which it was launched | ||
| #-Dsonar.projectBaseDir= # optional, default is . | ||
| # Comma-separated paths to directories containing test source files. | ||
| #-Dsonar.tests= # optional. For more info about Code Coverage, please refer to https://docs.sonarcloud.io/enriching/test-coverage/overview/ | ||
| # Adds more detail to both client and server-side analysis logs, activating DEBUG mode for the scanner, and adding client-side environment variables and system properties to the server-side log of analysis report processing. | ||
| #-Dsonar.verbose= # optional, default is false | ||
| node-version: '20' | ||
| cache: 'npm' | ||
|
|
||
| - name: Install dependencies | ||
| run: npm ci | ||
|
|
||
| - name: Run tests with coverage | ||
| run: npm test -- --coverage --ci | ||
| continue-on-error: true | ||
|
|
||
| - name: SonarQube Scan | ||
| uses: SonarSource/sonarqube-scan-action@v5 | ||
| env: | ||
| SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} | ||
| SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} No newline at end of file |
There was a problem hiding this comment.
Add explicit least-privilege permissions for the SonarQube job.
This workflow relies on default token permissions. Set explicit minimal scopes (typically contents: read) to avoid over-privileged tokens.
Suggested diff
name: SonarQube Analysis
@@
on:
pull_request:
@@
+permissions:
+ contents: read
+
jobs:
sonarqube:🧰 Tools
🪛 zizmor (1.25.2)
[warning] 40-43: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
[warning] 36-62: overly broad permissions (excessive-permissions): default permissions used due to no permissions: block
(excessive-permissions)
[error] 41-41: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
[error] 46-46: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
[error] 59-59: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/sonarqube.yml around lines 35 - 62, The sonarqube job is
missing explicit permission declarations, which causes it to use default
elevated permissions. Add a permissions block at the same indentation level as
the name, runs-on, and steps properties in the sonarqube job. Set the
permissions to contents: read to grant only the minimal required permission for
checking out the code, following the principle of least privilege for workflow
token scopes.
Source: Linters/SAST tools
| steps: | ||
| - name: Analyze with SonarQube | ||
| - name: Checkout code | ||
| uses: actions/checkout@v4 |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Show non-SHA action refs in Sonar workflow.
rg -nP '^\s*uses:\s*[^@]+@(?!(?:[a-f0-9]{40})\b)' .github/workflows/sonarqube.ymlRepository: vallabhatech/CareSync
Length of output: 195
Pin workflow actions by commit SHA instead of version tags.
actions/checkout@v4, actions/setup-node@v4, and SonarSource/sonarqube-scan-action@v5 use mutable version tags; pinning to commit SHAs aligns with supply-chain security best practices by preventing unexpected updates if tags are reassigned.
Apply to lines 41, 46, and 59.
🧰 Tools
🪛 zizmor (1.25.2)
[error] 41-41: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/sonarqube.yml at line 41, Replace the mutable version tags
in the workflow actions with immutable commit SHAs for improved supply-chain
security. Update the three action references: actions/checkout@v4 on line 41,
actions/setup-node@v4 on line 46, and SonarSource/sonarqube-scan-action@v5 on
line 59 by replacing the version tag (e.g., `@v4`) with the full commit SHA hash
for each action to pin them to specific, immutable versions.
Source: Linters/SAST tools
| @@ -0,0 +1,14 @@ | |||
| sonar.projectKey=vallabhatech_CareSync | |||
There was a problem hiding this comment.
Remove the BOM prefix from the first property key.
The first key appears to start with a BOM (sonar.projectKey=...). That can break key recognition in some parsers and make project identification fail.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@sonar-project.properties` at line 1, The sonar.projectKey property at the
beginning of the sonar-project.properties file has a BOM (Byte Order Mark)
character prefix that can cause parsing issues. Remove the BOM character that
appears before the sonar.projectKey=vallabhatech_CareSync property by re-saving
the file with UTF-8 encoding without BOM, ensuring the file starts directly with
the 's' character of 'sonar'.
| sonar.exclusions=**/node_modules/**,**/*.test.ts,**/*.spec.ts,**/coverage/**,**/.next/** | ||
|
|
||
| sonar.tests=src | ||
| sonar.test.inclusions=**/*.test.ts,**/*.spec.ts | ||
|
|
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check whether TSX test files exist and would be missed by current sonar patterns.
fd -i '(.test|.spec).tsx$' srcRepository: vallabhatech/CareSync
Length of output: 47
🏁 Script executed:
# Search entire repo for .test.tsx or .spec.tsx files
fd -i '(.test|.spec).tsx$' .Repository: vallabhatech/CareSync
Length of output: 47
🏁 Script executed:
# Check if any .tsx files exist in the repo
fd -i '.tsx$' . | head -20Repository: vallabhatech/CareSync
Length of output: 47
🏁 Script executed:
# List actual test files to see what patterns are in use
fd -i '(.test|.spec).(ts|tsx)$' . | sortRepository: vallabhatech/CareSync
Length of output: 47
🏁 Script executed:
# List src directory structure
ls -la src/ 2>/dev/null | head -30Repository: vallabhatech/CareSync
Length of output: 803
🏁 Script executed:
# Look for any test/spec files with different patterns
fd -i 'test|spec' . --type f | grep -E '\.(ts|tsx|js|jsx)$' | head -20Repository: vallabhatech/CareSync
Length of output: 205
🏁 Script executed:
# Check for test configuration files
fd -i '(jest|vitest|mocha|karma)\.config' .Repository: vallabhatech/CareSync
Length of output: 47
🏁 Script executed:
# Check package.json for test configuration
cat package.json | grep -A 5 '"test"' 2>/dev/null || echo "No test script found"Repository: vallabhatech/CareSync
Length of output: 199
Update test pattern inclusions to match JavaScript test files.
Sonar configuration targets .test.ts and .spec.ts, but all test files in this JavaScript-based repository use .test.js naming (e.g., src/utils/notifications.test.js, src/i18n/i18n.test.js). The current patterns will exclude these actual test files from Sonar's test metrics. Update sonar.test.inclusions to include **/*.test.js,**/*.spec.js or use a pattern matching both JavaScript and TypeScript test files.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@sonar-project.properties` around lines 6 - 10, The sonar.test.inclusions
property is configured to only match TypeScript test files (.test.ts and
.spec.ts), but the repository uses JavaScript test files (.test.js and
.spec.js). Update the sonar.test.inclusions value to include both JavaScript and
TypeScript test file patterns by adding **/*.test.js and **/*.spec.js alongside
the existing TypeScript patterns, separated by commas, so that Sonar can
properly detect and analyze all actual test files in the repository.
|




Summary
Implements a comprehensive CI/CD pipeline to automate code quality checks on every PR.
Closes #28
Changes
.github/workflows/ci.yml— ESLint + TypeScript + Tests + PR comment with results.github/workflows/sonarqube.yml— SonarQube code quality analysis.github/workflows/dependency-review.yml— security scan for dependencies.github/coderabbit.yml— CodeRabbit AI review configsonar-project.properties— SonarQube project settings.github/CONTRIBUTING_CI.md— setup documentation for maintainersSetup needed by maintainers
SONAR_TOKENandSONAR_HOST_URLin repo SecretsSigned-off-by: Samal Bishnupriya samalbishnupriya.06@gmail.com
Summary by CodeRabbit
Documentation
Chores