Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions .github/workflows/sonar-ci-artifacts.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
name: CI test report
on:
push:
branches:
- main
pull_request:
types: [opened, synchronize, reopened]

jobs:
check-changes:
runs-on: ubuntu-latest
outputs:
code: ${{ steps.filter.outputs.code }}
steps:
- uses: actions/checkout@v4
- uses: dorny/paths-filter@d1c1ffe0248fe513906c8e24db8ea791d46f8590 #v3.0.3
id: filter
with:
filters: |
code:
- '!docs/**'

build:
runs-on: ubuntu-latest
needs: check-changes
if: needs.check-changes.outputs.code == 'true'
steps:

- name: Checkout repo
uses: actions/checkout@v4
with:
# Disabling shallow clones is recommended for improving the relevancy of reporting
fetch-depth: 0

- name: Set up Go
uses: ./.github/actions/setup-go-kpt
with:
install-kpt: "false"

- name: Run unit tests to generate coverage report
id: test
run: make test

- name: Archive test results
if: steps.test.outcome == 'success'
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: ./coverage.out

- name: Save PR number to file
if: github.event_name == 'pull_request'
run: echo ${{ github.event.number }} > PR_NUMBER.txt

- name: Archive PR number
if: github.event_name == 'pull_request'
uses: actions/upload-artifact@v4
with:
name: PR_NUMBER
path: PR_NUMBER.txt

test-summary:
name: Test Summary
if: always()
needs: [check-changes, build]
runs-on: ubuntu-latest
steps:
- run: exit 1
if: |
needs.check-changes.outputs.code == 'true' &&
(needs.build.result == 'failure' || needs.build.result == 'cancelled')
- run: echo "Tests passed or skipped"
138 changes: 138 additions & 0 deletions .github/workflows/sonarcloud.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
name: SonarCloud analysis

on:
workflow_run:
workflows: [CI test report]
types: [completed]

jobs:
check-artifacts:
runs-on: ubuntu-latest
if: github.event.workflow_run.conclusion == 'success'
permissions:
actions: read
outputs:
has-artifacts: ${{ steps.check.outputs.has-artifacts }}
steps:
- name: Check for coverage artifact
id: check
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
const artifacts = await github.rest.actions.listWorkflowRunArtifacts({
owner: context.repo.owner,
repo: context.repo.repo,
run_id: ${{ github.event.workflow_run.id }}
});
const hasCoverage = artifacts.data.artifacts.some(a => a.name === 'coverage-report');
core.setOutput('has-artifacts', hasCoverage);

sonarqube:
needs: check-artifacts
if: needs.check-artifacts.outputs.has-artifacts == 'true'
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
pull-requests: read
steps:
- name: Download PR number artifact
if: github.event.workflow_run.event == 'pull_request'
uses: dawidd6/action-download-artifact@b6e2e70617bc3265edd6dab6c906732b2f1ae151 # v21
with:
workflow: CI test report
run_id: ${{ github.event.workflow_run.id }}
name: PR_NUMBER

- name: Read PR_NUMBER.txt
if: github.event.workflow_run.event == 'pull_request'
id: pr_number
uses: juliangruber/read-file-action@271ff311a4947af354c6abcd696a306553b9ec18 # v1.1.8
with:
path: ./PR_NUMBER.txt

- name: Request GitHub API for PR data
if: github.event.workflow_run.event == 'pull_request'
uses: octokit/request-action@b91aabaa861c777dcdb14e2387e30eddf04619ae # v3.0.0
id: get_pr_data
with:
route: GET /repos/{full_name}/pulls/{number}
number: ${{ steps.pr_number.outputs.content }}
full_name: ${{ github.event.repository.full_name }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Extract PR metadata
if: github.event.workflow_run.event == 'pull_request'
id: pr_meta
env:
PR_DATA: ${{ steps.get_pr_data.outputs.data }}
run: |
echo "number=$(echo "$PR_DATA" | jq -r '.number')" >> "$GITHUB_OUTPUT"
echo "head_ref=$(echo "$PR_DATA" | jq -r '.head.ref')" >> "$GITHUB_OUTPUT"
echo "base_ref=$(echo "$PR_DATA" | jq -r '.base.ref')" >> "$GITHUB_OUTPUT"

# Use SHA for checkout — immune to branch-name injection.
# allow-unsafe-pr-checkout is safe here: we only scan (no script execution
# from fork code) and persist-credentials is false.
- name: Checkout PR head
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0

Check failure on line 79 in .github/workflows/sonarcloud.yml

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Make sure that no untrusted code is executed from a fork.

See more on https://sonarcloud.io/project/issues?id=kptdev_kpt&issues=AZ-KDlIKpKMmGSWnQetw&open=AZ-KDlIKpKMmGSWnQetw&pullRequest=4657
with:
repository: ${{ github.event.workflow_run.head_repository.full_name }}
ref: ${{ github.event.workflow_run.head_sha }}
fetch-depth: 0
persist-credentials: false
allow-unsafe-pr-checkout: true

# Branch names passed via env (not expression interpolation in run:)
- name: Checkout base branch
if: github.event.workflow_run.event == 'pull_request'
env:
BASE_REF: ${{ steps.pr_meta.outputs.base_ref }}
HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
CLONE_URL: ${{ github.event.repository.clone_url }}
run: |
git remote add upstream "$CLONE_URL"
git fetch upstream
git checkout -B "$BASE_REF" "upstream/$BASE_REF"
git checkout "$HEAD_SHA"
git clean -ffdx && git reset --hard HEAD

- name: Download coverage artifact
uses: dawidd6/action-download-artifact@b6e2e70617bc3265edd6dab6c906732b2f1ae151 # v21
with:
workflow: CI test report
run_id: ${{ github.event.workflow_run.id }}
name: coverage-report
use_unzip: true

- name: Fix Go module paths in coverage
run: |
sed -i 's|github.com/kptdev/kpt|.|g' coverage.out

- name: SonarQube Scan on PR
if: github.event.workflow_run.event == 'pull_request'
uses: SonarSource/sonarqube-scan-action@713881670b6b3676cda39549040e2d88c70d582e # v8.2.0
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
with:
args:
-Dsonar.projectKey=kptdev_kpt
-Dsonar.organization=kptdev
-Dproject.settings=sonar-project.properties
-Dsonar.pullrequest.key=${{ steps.pr_meta.outputs.number }}
-Dsonar.pullrequest.branch=${{ steps.pr_meta.outputs.head_ref }}
-Dsonar.pullrequest.base=${{ steps.pr_meta.outputs.base_ref }}

- name: SonarCloud Scan on push
if: >-
github.event.workflow_run.event == 'push' &&
github.event.workflow_run.head_repository.full_name == github.event.repository.full_name
uses: SonarSource/sonarqube-scan-action@713881670b6b3676cda39549040e2d88c70d582e # v8.2.0
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
with:
args:
-Dsonar.projectKey=kptdev_kpt
-Dsonar.organization=kptdev
-Dproject.settings=sonar-project.properties
21 changes: 21 additions & 0 deletions sonar-project.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Required metadata
sonar.projectKey=kptdev_kpt
sonar.projectName=kpt
sonar.organization=kptdev

sonar.language=go

# Path to your Go source code
sonar.sources=pkg, func, commands, internal, run, api

# Exclude files if needed
sonar.exclusions=**/test/**, **/examples/*, **/scripts/*, **/*_test.go, **/testing*, **/generated/**, **/testdata/**, **/*zz_generated.*

# To include test coverage reports (optional)
#sonar.tests=./
sonar.test.inclusions=**/*_test.go
sonar.coverage.exclusions=**/test/**, **/*_test.go, **/testing*, **/api/**
sonar.go.tests.reportPaths=report.xml
sonar.go.coverage.reportPaths=coverage.out
# To exclude duplicated blocks from CPD (Copy-Paste Detection)
sonar.cpd.exclusions=**/*_test.go, **/test/**, **/testing**, **/api/**
Loading