mirror of
https://github.com/SonarSource/sonarqube-scan-action.git
synced 2025-12-13 01:41:15 +00:00
Compare commits
117 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a31c9398be | ||
|
|
40f5b61913 | ||
|
|
9bf7c126a1 | ||
|
|
ba6563cca7 | ||
|
|
5ffbad4454 | ||
|
|
fd88b7d7cc | ||
|
|
27a157d234 | ||
|
|
e327da8e78 | ||
|
|
ff001fd600 | ||
|
|
a88c96d7e4 | ||
|
|
a64281002c | ||
|
|
60aee7033b | ||
|
|
502204eab4 | ||
|
|
0b794a06fa | ||
|
|
ece10df5d7 | ||
|
|
ee80e84272 | ||
|
|
cbabf0572a | ||
|
|
16df975da5 | ||
|
|
ed9f3aad50 | ||
|
|
8f448484d9 | ||
|
|
6a808e9a20 | ||
|
|
9db61695c9 | ||
|
|
5837ebfcca | ||
|
|
1a6d90ebcb | ||
|
|
016cabf33a | ||
|
|
5fc8cfce6b | ||
|
|
786af10ed4 | ||
|
|
01850e2590 | ||
|
|
8c71dc039c | ||
|
|
ef211f93a6 | ||
|
|
74f62c995b | ||
|
|
c8aa051cc4 | ||
|
|
bfe63be746 | ||
|
|
2500896589 | ||
|
|
73bc64cb64 | ||
|
|
7d51dd28ef | ||
|
|
be0a85295f | ||
|
|
12d7d00f02 | ||
|
|
aa494459d7 | ||
|
|
1474b34972 | ||
|
|
961628671d | ||
|
|
f932b663ac | ||
|
|
550777f6eb | ||
|
|
0303d6b62e | ||
|
|
3ed7560138 | ||
|
|
73cb22d49a | ||
|
|
994c850d7a | ||
|
|
7622374390 | ||
|
|
6bbc1364b8 | ||
|
|
d6b87b0feb | ||
|
|
bfd4e558cd | ||
|
|
26c51824c8 | ||
|
|
0ab314b63d | ||
|
|
ea0362bf7b | ||
|
|
d1fd0ebe22 | ||
|
|
00e62e1190 | ||
|
|
844ce2710b | ||
|
|
a36db763ac | ||
|
|
1b442ee39a | ||
|
|
f4eddd92b8 | ||
|
|
7b13cfe195 | ||
|
|
1f659fabd3 | ||
|
|
05ca09c2da | ||
|
|
6440c73982 | ||
|
|
94d4f8ac4a | ||
|
|
13990a6956 | ||
|
|
66a0baa492 | ||
|
|
884b79409b | ||
|
|
f885e52a75 | ||
|
|
2af7c4bea3 | ||
|
|
0c0f3958d9 | ||
|
|
8c8682dac7 | ||
|
|
bfafdf2896 | ||
|
|
aecaf43ae5 | ||
|
|
540792c588 | ||
|
|
e56fc172a4 | ||
|
|
94ac847096 | ||
|
|
86fe817756 | ||
|
|
44de84c3e8 | ||
|
|
8c56bc3994 | ||
|
|
e4c4bdc17f | ||
|
|
16be80a080 | ||
|
|
968b486245 | ||
|
|
320b72385a | ||
|
|
fed3555e67 | ||
|
|
9bea6a46af | ||
|
|
d3ca1743de | ||
|
|
0c14a18753 | ||
|
|
f8003d5a3a | ||
|
|
04623c1cb1 | ||
|
|
be64f35726 | ||
|
|
6abcb2537c | ||
|
|
53c3e3207f | ||
|
|
9ad16418d1 | ||
|
|
74e7b4f998 | ||
|
|
1b9d398800 | ||
|
|
ccaf9efb11 | ||
|
|
69c1a75940 | ||
|
|
4b0bfc149f | ||
|
|
9cc4f58b79 | ||
|
|
5829c57497 | ||
|
|
d57dba2a10 | ||
|
|
427bad7016 | ||
|
|
a6ba0aafc2 | ||
|
|
1db0a52e3c | ||
|
|
50d5d98163 | ||
|
|
26fe7d6b0e | ||
|
|
fd8151470c | ||
|
|
bdba66714e | ||
|
|
72def085d4 | ||
|
|
7295e71c95 | ||
|
|
b755ad2c7e | ||
|
|
7153604e5b | ||
|
|
1f3c95ed10 | ||
|
|
495aa71ae8 | ||
|
|
a81ac001b5 | ||
|
|
9b49068b67 |
64 changed files with 35009 additions and 215 deletions
1
.github/CODEOWNERS
vendored
Normal file
1
.github/CODEOWNERS
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
.github/* @sonarsource/orchestration-processing-squad
|
||||
19
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
19
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
<!--
|
||||
Only for standalone PRs without Jira issue in the PR title:
|
||||
* Replace this comment with Epic ID to create a new Task in Jira
|
||||
* Replace this comment with Issue ID to create a new Sub-Task in Jira
|
||||
* Ignore or delete this note to create a new Task in Jira without a parent
|
||||
-->
|
||||
|
||||
Please be aware that we are not actively looking for feature contributions. The truth is that it's extremely difficult for someone outside SonarSource to comply with our roadmap and expectations. Therefore, we typically only accept minor cosmetic changes and typo fixes. If you would like to see a new feature, please create a new thread in the forum ["Suggest new features"](https://community.sonarsource.com/c/suggestions/features).
|
||||
|
||||
With that in mind, if you would like to submit a code contribution, make sure that you adhere to the following guidelines and all tests are passing:
|
||||
|
||||
- [ ] Please explain your motives to contribute this change: what problem you are trying to fix, what improvement you are trying to make
|
||||
- [ ] Make sure any code you changed is covered by tests
|
||||
- [ ] If there is a [JIRA](http://jira.sonarsource.com/browse/SONAR) ticket available, please make your commits and pull request start with the ticket ID (SONAR-XXXX)
|
||||
|
||||
We will try to give you feedback on your contribution as quickly as possible.
|
||||
|
||||
Thank You!
|
||||
The SonarSource Team
|
||||
16
.github/dependabot.yml
vendored
Normal file
16
.github/dependabot.yml
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
# To get started with Dependabot version updates, you'll need to specify which
|
||||
# package ecosystems to update and where the package manifests are located.
|
||||
# Please see the documentation for all configuration options:
|
||||
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
|
||||
|
||||
version: 2
|
||||
|
||||
updates:
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
timezone: "CET"
|
||||
open-pull-requests-limit: 100
|
||||
commit-message:
|
||||
prefix: "NO-JIRA "
|
||||
15
.github/qa-nginx-redirecting/compose.yml
vendored
Normal file
15
.github/qa-nginx-redirecting/compose.yml
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
services:
|
||||
https-proxy:
|
||||
image: nginx
|
||||
ports:
|
||||
- 8080:8080
|
||||
volumes:
|
||||
- $GITHUB_WORKSPACE/.github/qa-nginx-redirecting/nginx.conf:/etc/nginx/nginx.conf:ro
|
||||
- $GITHUB_WORKSPACE/.github/qa-nginx-redirecting/nginx.crt:/etc/nginx/nginx.crt:ro
|
||||
- $GITHUB_WORKSPACE/.github/qa-nginx-redirecting/nginx.key:/etc/nginx/nginx.key:ro
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "--fail", "--insecure", "https://localhost:8080/health"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 20
|
||||
start_period: 2m
|
||||
10
.github/qa-nginx-redirecting/generate-ssl.sh
vendored
Executable file
10
.github/qa-nginx-redirecting/generate-ssl.sh
vendored
Executable file
|
|
@ -0,0 +1,10 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Generate self-signed SSL certificate for localhost with 1-day expiry
|
||||
openssl req -x509 -nodes -days 1 -newkey rsa:2048 \
|
||||
-keyout nginx.key \
|
||||
-out nginx.crt \
|
||||
-subj "/C=US/ST=CA/L=Local/O=Test/CN=localhost" \
|
||||
-addext "subjectAltName=DNS:localhost,IP:127.0.0.1"
|
||||
|
||||
echo "SSL certificates generated with 1-day expiry: nginx.crt and nginx.key"
|
||||
34
.github/qa-nginx-redirecting/nginx.conf
vendored
Normal file
34
.github/qa-nginx-redirecting/nginx.conf
vendored
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
user nginx;
|
||||
worker_processes auto;
|
||||
|
||||
error_log /var/log/nginx/error.log notice;
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
sendfile on;
|
||||
|
||||
keepalive_timeout 65;
|
||||
|
||||
include /etc/nginx/conf.d/*.conf;
|
||||
|
||||
server {
|
||||
listen 8080 ssl;
|
||||
ssl_certificate /etc/nginx/nginx.crt;
|
||||
ssl_certificate_key /etc/nginx/nginx.key;
|
||||
|
||||
location /health {
|
||||
add_header 'Content-Type' 'text/plain';
|
||||
return 200 "healthy\n";
|
||||
}
|
||||
|
||||
location ~ /clientRedirectToSonarBinaries/(.*) {
|
||||
return 301 "https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/$1";
|
||||
}
|
||||
}
|
||||
}
|
||||
26
.github/qa-sq-behind-ngix/compose.yml
vendored
Normal file
26
.github/qa-sq-behind-ngix/compose.yml
vendored
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
services:
|
||||
sonarqube:
|
||||
image: sonarqube:lts-community
|
||||
ports:
|
||||
- 9000:9000
|
||||
healthcheck:
|
||||
test: 'grep -Fq "SonarQube is operational" /opt/sonarqube/logs/sonar.log'
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 20
|
||||
start_period: 2m
|
||||
|
||||
https-proxy:
|
||||
image: nginx
|
||||
ports:
|
||||
- 4443:4443
|
||||
volumes:
|
||||
- $GITHUB_WORKSPACE/.github/qa-sq-behind-ngix/nginx.conf:/etc/nginx/nginx.conf:ro
|
||||
- $GITHUB_WORKSPACE/.github/qa-sq-behind-ngix/server.crt:/etc/nginx/server.crt:ro
|
||||
- $GITHUB_WORKSPACE/.github/qa-sq-behind-ngix/server.key:/etc/nginx/server.key:ro
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "--fail", "localhost:8080/health"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 20
|
||||
start_period: 2m
|
||||
43
.github/qa-sq-behind-ngix/nginx.conf
vendored
Normal file
43
.github/qa-sq-behind-ngix/nginx.conf
vendored
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
user nginx;
|
||||
worker_processes auto;
|
||||
|
||||
error_log /var/log/nginx/error.log notice;
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
sendfile on;
|
||||
|
||||
keepalive_timeout 65;
|
||||
|
||||
include /etc/nginx/conf.d/*.conf;
|
||||
|
||||
server {
|
||||
listen 8080;
|
||||
|
||||
location /health {
|
||||
add_header 'Content-Type' 'text/plain';
|
||||
return 200 "healthy\n";
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 4443 ssl;
|
||||
|
||||
ssl_protocols TLSv1.1 TLSv1.2;
|
||||
ssl_certificate /etc/nginx/server.crt;
|
||||
ssl_certificate_key /etc/nginx/server.key;
|
||||
|
||||
location / {
|
||||
proxy_pass http://sonarqube:9000;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-For $remote_addr;
|
||||
proxy_set_header X-Forwarded-Proto https;
|
||||
}
|
||||
}
|
||||
}
|
||||
28
.github/workflows/PullRequestClosed.yml
vendored
Normal file
28
.github/workflows/PullRequestClosed.yml
vendored
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
name: Pull Request Closed
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [closed]
|
||||
|
||||
jobs:
|
||||
PullRequestClosed_job:
|
||||
name: Pull Request Closed
|
||||
runs-on: github-ubuntu-latest-s
|
||||
permissions:
|
||||
id-token: write
|
||||
pull-requests: read
|
||||
# For external PR, ticket should be moved manually
|
||||
if: |
|
||||
github.event.pull_request.head.repo.full_name == github.repository
|
||||
steps:
|
||||
- id: secrets
|
||||
uses: SonarSource/vault-action-wrapper@v3
|
||||
with:
|
||||
secrets: |
|
||||
development/kv/data/jira user | JIRA_USER;
|
||||
development/kv/data/jira token | JIRA_TOKEN;
|
||||
- uses: sonarsource/gh-action-lt-backlog/PullRequestClosed@v2
|
||||
with:
|
||||
github-token: ${{secrets.GITHUB_TOKEN}}
|
||||
jira-user: ${{ fromJSON(steps.secrets.outputs.vault).JIRA_USER }}
|
||||
jira-token: ${{ fromJSON(steps.secrets.outputs.vault).JIRA_TOKEN }}
|
||||
29
.github/workflows/PullRequestCreated.yml
vendored
Normal file
29
.github/workflows/PullRequestCreated.yml
vendored
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
name: Pull Request Created
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: ["opened"]
|
||||
|
||||
jobs:
|
||||
PullRequestCreated_job:
|
||||
name: Pull Request Created
|
||||
runs-on: github-ubuntu-latest-s
|
||||
permissions:
|
||||
id-token: write
|
||||
# For external PR, ticket should be created manually
|
||||
if: |
|
||||
github.event.pull_request.head.repo.full_name == github.repository
|
||||
steps:
|
||||
- id: secrets
|
||||
uses: SonarSource/vault-action-wrapper@v3
|
||||
with:
|
||||
secrets: |
|
||||
development/github/token/{REPO_OWNER_NAME_DASH}-jira token | GITHUB_TOKEN;
|
||||
development/kv/data/jira user | JIRA_USER;
|
||||
development/kv/data/jira token | JIRA_TOKEN;
|
||||
- uses: sonarsource/gh-action-lt-backlog/PullRequestCreated@v2
|
||||
with:
|
||||
github-token: ${{ fromJSON(steps.secrets.outputs.vault).GITHUB_TOKEN }}
|
||||
jira-user: ${{ fromJSON(steps.secrets.outputs.vault).JIRA_USER }}
|
||||
jira-token: ${{ fromJSON(steps.secrets.outputs.vault).JIRA_TOKEN }}
|
||||
jira-project: SQSCANGHA
|
||||
28
.github/workflows/RequestReview.yml
vendored
Normal file
28
.github/workflows/RequestReview.yml
vendored
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
name: Request review
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: ["review_requested"]
|
||||
|
||||
jobs:
|
||||
RequestReview_job:
|
||||
name: Request review
|
||||
runs-on: github-ubuntu-latest-s
|
||||
permissions:
|
||||
id-token: write
|
||||
# For external PR, ticket should be moved manually
|
||||
if: |
|
||||
github.event.pull_request.head.repo.full_name == github.repository
|
||||
steps:
|
||||
- id: secrets
|
||||
uses: SonarSource/vault-action-wrapper@v3
|
||||
with:
|
||||
secrets: |
|
||||
development/github/token/{REPO_OWNER_NAME_DASH}-jira token | GITHUB_TOKEN;
|
||||
development/kv/data/jira user | JIRA_USER;
|
||||
development/kv/data/jira token | JIRA_TOKEN;
|
||||
- uses: sonarsource/gh-action-lt-backlog/RequestReview@v2
|
||||
with:
|
||||
github-token: ${{ fromJSON(steps.secrets.outputs.vault).GITHUB_TOKEN }}
|
||||
jira-user: ${{ fromJSON(steps.secrets.outputs.vault).JIRA_USER }}
|
||||
jira-token: ${{ fromJSON(steps.secrets.outputs.vault).JIRA_TOKEN }}
|
||||
30
.github/workflows/SubmitReview.yml
vendored
Normal file
30
.github/workflows/SubmitReview.yml
vendored
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
name: Submit Review
|
||||
|
||||
on:
|
||||
pull_request_review:
|
||||
types: [submitted]
|
||||
|
||||
jobs:
|
||||
SubmitReview_job:
|
||||
name: Submit Review
|
||||
runs-on: github-ubuntu-latest-s
|
||||
permissions:
|
||||
id-token: write
|
||||
pull-requests: read
|
||||
# For external PR, ticket should be moved manually
|
||||
if: |
|
||||
github.event.pull_request.head.repo.full_name == github.repository
|
||||
&& (github.event.review.state == 'changes_requested'
|
||||
|| github.event.review.state == 'approved')
|
||||
steps:
|
||||
- id: secrets
|
||||
uses: SonarSource/vault-action-wrapper@v3
|
||||
with:
|
||||
secrets: |
|
||||
development/kv/data/jira user | JIRA_USER;
|
||||
development/kv/data/jira token | JIRA_TOKEN;
|
||||
- uses: sonarsource/gh-action-lt-backlog/SubmitReview@v2
|
||||
with:
|
||||
github-token: ${{secrets.GITHUB_TOKEN}}
|
||||
jira-user: ${{ fromJSON(steps.secrets.outputs.vault).JIRA_USER }}
|
||||
jira-token: ${{ fromJSON(steps.secrets.outputs.vault).JIRA_TOKEN }}
|
||||
90
.github/workflows/qa-deprecated-c-cpp.yml
vendored
Normal file
90
.github/workflows/qa-deprecated-c-cpp.yml
vendored
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
name: QA Deprecated C and C++ action
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
|
||||
jobs:
|
||||
output-test:
|
||||
name: Action outputs
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [github-ubuntu-latest-s, github-windows-latest-s, macos-latest, macos-14]
|
||||
cache: [true, false]
|
||||
include:
|
||||
- arch: X64
|
||||
- os: macos-latest
|
||||
arch: ARM64
|
||||
- os: macos-14
|
||||
arch: ARM64
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
# Specifying a specific architecture of the runner is not possible for Github hosted runners
|
||||
# We can only check if the runner architecture matches the expected one
|
||||
- name: check_runner_arch
|
||||
shell: bash
|
||||
run: |
|
||||
echo "Runner architecture: ${{ runner.arch }}"
|
||||
if [[ "${{ runner.arch }}" != "${{ matrix.arch }}" ]]; then
|
||||
echo "##[error]Runner architecture does not match the expected one"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
|
||||
|
||||
- name: Run SonarQube C/C++ action
|
||||
id: run-action
|
||||
uses: ./deprecated-c-cpp
|
||||
env:
|
||||
SONAR_HOST_URL: 'https://next.sonarqube.com/sonarqube/'
|
||||
with:
|
||||
cache-binaries: ${{ matrix.cache }}
|
||||
|
||||
- name: SONAR_HOST_URL is set
|
||||
shell: bash
|
||||
run: |
|
||||
[[ $SONAR_HOST_URL == "https://next.sonarqube.com/sonarqube/" ]]
|
||||
|
||||
- name: sonar-scanner is installed and in PATH
|
||||
run: |
|
||||
sonar-scanner --help | grep "usage: sonar-scanner "
|
||||
|
||||
- name: sonar-scanner-binary output is correct
|
||||
shell: bash
|
||||
env:
|
||||
BINARY: ${{ steps.run-action.outputs.sonar-scanner-binary }}
|
||||
run: |
|
||||
"$BINARY" --help | grep "usage: sonar-scanner "
|
||||
|
||||
# build-wrapper does not have --help or equivalent option.
|
||||
# Pass to few arguments and ignore error code
|
||||
- name: build-wrapper is installed and in PATH on Windows
|
||||
if: runner.os == 'Windows'
|
||||
shell: bash
|
||||
run: |
|
||||
(build-wrapper-win-x86-64.exe || true) | grep "build-wrapper, version "
|
||||
|
||||
- name: build-wrapper is installed and in PATH on Linux
|
||||
if: runner.os == 'Linux'
|
||||
shell: bash
|
||||
run: |
|
||||
(build-wrapper-linux-x86-64 || true) | grep "build-wrapper, version "
|
||||
|
||||
- name: build-wrapper is installed and in PATH on macOS
|
||||
if: runner.os == 'macOs'
|
||||
shell: bash
|
||||
run: |
|
||||
(build-wrapper-macosx-x86 || true) | grep "build-wrapper, version "
|
||||
|
||||
- name: build-wrapper-binary output is correct
|
||||
shell: bash
|
||||
env:
|
||||
BINARY: ${{ steps.run-action.outputs.build-wrapper-binary }}
|
||||
run: |
|
||||
("$BINARY" || true) | grep "build-wrapper, version "
|
||||
72
.github/workflows/qa-install-build-wrapper.yml
vendored
Normal file
72
.github/workflows/qa-install-build-wrapper.yml
vendored
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
name: QA Install Build Wrapper action
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
|
||||
jobs:
|
||||
output-test:
|
||||
name: Action outputs
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [github-ubuntu-latest-s, github-windows-latest-s, macos-latest, macos-14]
|
||||
cache: [true, false]
|
||||
include:
|
||||
- arch: X64
|
||||
- os: macos-latest
|
||||
arch: ARM64
|
||||
- os: macos-14
|
||||
arch: ARM64
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
# Specifying a specific architecture of the runner is not possible for Github hosted runners
|
||||
# We can only check if the runner architecture matches the expected one
|
||||
- name: check_runner_arch
|
||||
shell: bash
|
||||
run: |
|
||||
echo "Runner architecture: ${{ runner.arch }}"
|
||||
if [[ "${{ runner.arch }}" != "${{ matrix.arch }}" ]]; then
|
||||
echo "##[error]Runner architecture does not match the expected one"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
|
||||
|
||||
- name: Run SonarQube C/C++ action
|
||||
id: run-action
|
||||
uses: ./install-build-wrapper
|
||||
env:
|
||||
SONAR_HOST_URL: 'https://next.sonarqube.com/sonarqube/'
|
||||
|
||||
# build-wrapper does not have --help or equivalent option.
|
||||
# Pass to few arguments and ignore error code
|
||||
- name: build-wrapper is installed and in PATH on Windows
|
||||
if: runner.os == 'Windows'
|
||||
shell: bash
|
||||
run: |
|
||||
(build-wrapper-win-x86-64.exe || true) | grep "build-wrapper, version "
|
||||
|
||||
- name: build-wrapper is installed and in PATH on Linux
|
||||
if: runner.os == 'Linux'
|
||||
shell: bash
|
||||
run: |
|
||||
(build-wrapper-linux-x86-64 || true) | grep "build-wrapper, version "
|
||||
|
||||
- name: build-wrapper is installed and in PATH on macOS
|
||||
if: runner.os == 'macOs'
|
||||
shell: bash
|
||||
run: |
|
||||
(build-wrapper-macosx-x86 || true) | grep "build-wrapper, version "
|
||||
|
||||
- name: build-wrapper-binary output is correct
|
||||
shell: bash
|
||||
env:
|
||||
BINARY: ${{ steps.run-action.outputs.build-wrapper-binary }}
|
||||
run: |
|
||||
("$BINARY" || true) | grep "build-wrapper, version "
|
||||
829
.github/workflows/qa-main.yml
vendored
Normal file
829
.github/workflows/qa-main.yml
vendored
Normal file
|
|
@ -0,0 +1,829 @@
|
|||
name: QA Main action
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
|
||||
jobs:
|
||||
noInputsTest:
|
||||
name: >
|
||||
No inputs
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [github-ubuntu-latest-s, macos-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Run action without args
|
||||
uses: ./
|
||||
env:
|
||||
SONAR_HOST_URL: http://not_actually_used
|
||||
SONAR_SCANNER_JSON_PARAMS: '{"sonar.scanner.internal.dumpToFile": "./output.properties"}'
|
||||
- name: Assert
|
||||
run: |
|
||||
./test/assertFileContains ./output.properties "sonar.projectBaseDir=."
|
||||
argsInputTest:
|
||||
name: >
|
||||
'args' input
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [github-ubuntu-latest-s, github-windows-latest-s, macos-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Run action with args
|
||||
uses: ./
|
||||
with:
|
||||
args: -Dsonar.someArg=aValue -Dsonar.anotherArgWithSpaces="Another Value" -Dsonar.argWithSingleQuotes='Another Value'
|
||||
env:
|
||||
SONAR_HOST_URL: http://not_actually_used
|
||||
SONAR_SCANNER_JSON_PARAMS: '{"sonar.scanner.internal.dumpToFile": "./output.properties"}'
|
||||
- name: Assert
|
||||
run: |
|
||||
./test/assertFileContains ./output.properties "sonar.someArg=aValue"
|
||||
./test/assertFileContains ./output.properties 'sonar.anotherArgWithSpaces="Another Value"'
|
||||
./test/assertFileContains ./output.properties "sonar.argWithSingleQuotes='Another Value'"
|
||||
argsInputInjectionTest:
|
||||
name: >
|
||||
'args' input with command injection will fail
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [github-ubuntu-latest-s, github-windows-latest-s, macos-latest]
|
||||
args:
|
||||
[
|
||||
-Dsonar.someArg=aValue && echo "Injection",
|
||||
-Dsonar.someArg="value\"; whoami; echo \"",
|
||||
]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Run action with args
|
||||
id: runTest
|
||||
uses: ./
|
||||
continue-on-error: true
|
||||
with:
|
||||
args: ${{ matrix.args }}
|
||||
env:
|
||||
SONAR_HOST_URL: http://not_actually_used
|
||||
SONAR_SCANNER_JSON_PARAMS: '{"sonar.scanner.internal.dumpToFile": "./output.properties"}'
|
||||
- name: Fail if action succeeded
|
||||
if: steps.runTest.outcome == 'success'
|
||||
run: exit 1
|
||||
- name: Assert the scanner was not called
|
||||
run: |
|
||||
./test/assertFileDoesntExist ./output.properties
|
||||
backtickCommandInjectionTest:
|
||||
name: >
|
||||
'args' input with backticks injection does not execute command
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [github-ubuntu-latest-s, github-windows-latest-s, macos-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Run action with args
|
||||
uses: ./
|
||||
continue-on-error: true
|
||||
with:
|
||||
args: >
|
||||
-Dsonar.arg1="refs/heads/branch: [workflows] Bump `actions/*`" -Dsonar.arg2="test `echo Command Injection`" -Dsonar.arg3="`id`" -Dsonar.arg4="test'; `echo injection`; echo '" -Dsonar.arg5=" `whoami` " -Dsonar.arg6="test\`echo injection\`test"
|
||||
env:
|
||||
SONAR_HOST_URL: http://not_actually_used
|
||||
SONAR_SCANNER_JSON_PARAMS: '{"sonar.scanner.internal.dumpToFile": "./output.properties"}'
|
||||
- name: Assert command in arg is not executed
|
||||
run: |
|
||||
./test/assertFileContains ./output.properties 'sonar.arg1="refs/heads/branch\\: \[workflows\] Bump `actions/\*`"'
|
||||
./test/assertFileContains ./output.properties 'sonar.arg2="test `echo Command Injection`"'
|
||||
./test/assertFileContains ./output.properties 'sonar.arg3="`id`"'
|
||||
./test/assertFileContains ./output.properties "sonar.arg4=\"test'; \`echo injection\`; echo '\""
|
||||
./test/assertFileContains ./output.properties 'sonar.arg5=" `whoami` "'
|
||||
./test/assertFileContains ./output.properties 'sonar.arg6="test\\\\`echo injection\\\\`test"'
|
||||
dollarSymbolCommandInjectionTest:
|
||||
name: >
|
||||
'args' input with dollar command injection does not execute command
|
||||
strategy:
|
||||
matrix:
|
||||
os: [github-ubuntu-latest-s, github-windows-latest-s, macos-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Run action with args
|
||||
uses: ./
|
||||
continue-on-error: true
|
||||
with:
|
||||
args: -Dsonar.arg1="$(whoami)" -Dsonar.arg2="$GITHUB_TOKEN" -Dsonar.arg3="$(echo outer $(echo inner))" -Dsonar.arg4="value\$(whoami)end" -Dsonar.arg5="$(printf 'A%.0s' {1..10000})" -Dsonar.arg6='value"; $(whoami); echo "'
|
||||
env:
|
||||
SONAR_HOST_URL: http://not_actually_used
|
||||
SONAR_SCANNER_JSON_PARAMS: '{"sonar.scanner.internal.dumpToFile": "./output.properties"}'
|
||||
- name: Assert command in arg is not executed
|
||||
run: |
|
||||
./test/assertFileContains ./output.properties 'sonar.arg1="$(whoami)"'
|
||||
./test/assertFileContains ./output.properties 'sonar.arg2="$GITHUB_TOKEN"'
|
||||
./test/assertFileContains ./output.properties 'sonar.arg3="$(echo outer $(echo inner))"'
|
||||
./test/assertFileContains ./output.properties 'sonar.arg4="value\\\\$(whoami)end"'
|
||||
./test/assertFileContains ./output.properties 'sonar.arg5="$(printf '\''A%.0s'\'' {1..10000})"'
|
||||
./test/assertFileContains ./output.properties 'sonar.arg6='\''value"; $(whoami); echo "'\'''
|
||||
otherCommandInjectionVariantsTest:
|
||||
name: >
|
||||
'args' input with other command injection variants does not execute command
|
||||
strategy:
|
||||
matrix:
|
||||
os: [github-ubuntu-latest-s, github-windows-latest-s, macos-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Run action with args
|
||||
uses: ./
|
||||
continue-on-error: true
|
||||
with:
|
||||
args: -Dsonar.arg1="test | base64" -Dsonar.arg2="value; whoami" -Dsonar.arg3="value && echo test" -Dsonar.arg4="value > /tmp/output.txt" -Dsonar.arg5="< /etc/passwd" -Dsonar.arg6="" -Dsonar.arg7="../../../*" -Dsonar.arg8="*.key" -Dsonar.arg9="test\u0027\u0060whoami\u0060"
|
||||
env:
|
||||
SONAR_HOST_URL: http://not_actually_used
|
||||
SONAR_SCANNER_JSON_PARAMS: '{"sonar.scanner.internal.dumpToFile": "./output.properties"}'
|
||||
- name: Assert command in arg is not executed
|
||||
run: |
|
||||
./test/assertFileContains ./output.properties 'sonar.arg1="test | base64"'
|
||||
./test/assertFileContains ./output.properties 'sonar.arg2="value; whoami"'
|
||||
./test/assertFileContains ./output.properties 'sonar.arg3="value && echo test"'
|
||||
./test/assertFileContains ./output.properties 'sonar.arg4="value > /tmp/output.txt"'
|
||||
./test/assertFileContains ./output.properties 'sonar.arg5="< /etc/passwd"'
|
||||
./test/assertFileContains ./output.properties 'sonar.arg6=""'
|
||||
./test/assertFileContains ./output.properties 'sonar.arg7="../../../\*"'
|
||||
./test/assertFileContains ./output.properties 'sonar.arg8="\*.key"'
|
||||
./test/assertFileContains ./output.properties 'sonar.arg9="test\\\\u0027\\\\u0060whoami\\\\u0060"'
|
||||
projectBaseDirInputTest:
|
||||
name: >
|
||||
'projectBaseDir' input
|
||||
strategy:
|
||||
matrix:
|
||||
os: [github-ubuntu-latest-s, github-windows-latest-s, macos-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- run: mkdir -p ./baseDir
|
||||
- name: Run action with projectBaseDir
|
||||
uses: ./
|
||||
with:
|
||||
args: -Dsonar.scanner.internal.dumpToFile=./output.properties
|
||||
projectBaseDir: ./baseDir
|
||||
env:
|
||||
SONAR_HOST_URL: http://not_actually_used
|
||||
SONAR_SCANNER_JSON_PARAMS: '{"sonar.scanner.internal.dumpToFile": "./output.properties"}'
|
||||
- name: Assert
|
||||
run: |
|
||||
./test/assertFileContains ./output.properties "sonar.projectBaseDir=.*/baseDir"
|
||||
scannerVersionTest:
|
||||
name: >
|
||||
'scannerVersion' input
|
||||
runs-on: github-ubuntu-latest-s # assumes default RUNNER_ARCH for linux is X64
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Run action with scannerVersion
|
||||
uses: ./
|
||||
with:
|
||||
scannerVersion: 6.1.0.4477
|
||||
args: -Dsonar.scanner.internal.dumpToFile=./output.properties
|
||||
env:
|
||||
NO_CACHE: true # force install-sonar-scanner-cli.sh execution
|
||||
SONAR_HOST_URL: http://not_actually_used
|
||||
SONAR_SCANNER_JSON_PARAMS: '{"sonar.scanner.internal.dumpToFile": "./output.properties"}'
|
||||
- name: Assert
|
||||
run: |
|
||||
# Verify the tool was installed by checking it's in PATH
|
||||
if ! command -v sonar-scanner &> /dev/null; then
|
||||
echo "Error: sonar-scanner not found in PATH"
|
||||
exit 1
|
||||
fi
|
||||
scannerBinariesUrlTest:
|
||||
name: >
|
||||
'scannerBinariesUrl' input with invalid URL
|
||||
runs-on: github-ubuntu-latest-s # assumes default RUNNER_ARCH for linux is X64
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Run action with scannerBinariesUrl
|
||||
id: runTest
|
||||
uses: ./
|
||||
continue-on-error: true
|
||||
with:
|
||||
scannerVersion: 6.2.1.4610
|
||||
scannerBinariesUrl: https://invalid_uri/Distribution/sonar-scanner-cli
|
||||
env:
|
||||
NO_CACHE: true # force install-sonar-scanner-cli.sh execution
|
||||
SONAR_HOST_URL: http://not_actually_used
|
||||
SONAR_SCANNER_JSON_PARAMS: '{"sonar.scanner.internal.dumpToFile": "./output.properties"}'
|
||||
- name: Fail if action succeeded
|
||||
if: steps.runTest.outcome == 'success'
|
||||
run: exit 1
|
||||
- name: Assert Sonar Scanner CLI was not downloaded
|
||||
run: |
|
||||
./test/assertFileDoesntExist "$RUNNER_TEMP/sonarscanner/sonar-scanner-cli-6.2.1.4610-linux-x64.zip"
|
||||
- name: Assert Sonar Scanner CLI was not executed
|
||||
run: |
|
||||
./test/assertFileDoesntExist ./output.properties
|
||||
scannerBinariesUrlIsEscapedWithWget:
|
||||
name: >
|
||||
'scannerBinariesUrl' is escaped with wget so special chars are not injected in the download command
|
||||
runs-on: github-ubuntu-latest-s
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Run action with scannerBinariesUrl
|
||||
id: runTest
|
||||
uses: ./
|
||||
continue-on-error: true
|
||||
with:
|
||||
scannerBinariesUrl: "http://some_uri;touch file.txt;"
|
||||
env:
|
||||
NO_CACHE: true
|
||||
SONAR_HOST_URL: http://not_actually_used
|
||||
SONAR_SCANNER_JSON_PARAMS: '{"sonar.scanner.internal.dumpToFile": "./output1.properties"}'
|
||||
- name: Assert file.txt does not exist
|
||||
run: |
|
||||
./test/assertFileDoesntExist "$RUNNER_TEMP/sonarscanner/file.txt"
|
||||
scannerBinariesUrlIsEscapedWithCurl:
|
||||
name: >
|
||||
'scannerBinariesUrl' is escaped with curl so special chars are not injected in the download command
|
||||
runs-on: github-ubuntu-latest-s
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Remove wget
|
||||
run: sudo apt-get remove -y wget
|
||||
- name: Assert wget is not available
|
||||
run: |
|
||||
if command -v wget 2>&1 >/dev/null
|
||||
then
|
||||
exit 1
|
||||
fi
|
||||
- name: Run action with scannerBinariesUrl
|
||||
id: runTest
|
||||
uses: ./
|
||||
continue-on-error: true
|
||||
with:
|
||||
scannerBinariesUrl: "http://some_uri http://another_uri'; touch file.txt;"
|
||||
env:
|
||||
NO_CACHE: true
|
||||
SONAR_HOST_URL: http://not_actually_used
|
||||
SONAR_SCANNER_JSON_PARAMS: '{"sonar.scanner.internal.dumpToFile": "./output1.properties"}'
|
||||
- name: Assert file.txt does not exist
|
||||
run: |
|
||||
./test/assertFileDoesntExist "$RUNNER_TEMP/sonarscanner/file.txt"
|
||||
dontFailGradleTest:
|
||||
name: >
|
||||
Don't fail on Gradle project
|
||||
runs-on: github-ubuntu-latest-s
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Run action on Gradle project
|
||||
id: runTest
|
||||
uses: ./
|
||||
continue-on-error: true
|
||||
env:
|
||||
SONAR_HOST_URL: http://not_actually_used
|
||||
SONAR_SCANNER_JSON_PARAMS: '{"sonar.scanner.internal.dumpToFile": "./output.properties"}'
|
||||
with:
|
||||
projectBaseDir: ./test/gradle-project
|
||||
args: -Dsonar.scanner.internal.dumpToFile=./output.properties
|
||||
- name: Assert
|
||||
run: |
|
||||
./test/assertFileExists ./output.properties
|
||||
dontFailGradleKotlinTest:
|
||||
name: >
|
||||
Don't fail on Kotlin Gradle project
|
||||
runs-on: github-ubuntu-latest-s
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Run action on Kotlin Gradle project
|
||||
id: runTest
|
||||
uses: ./
|
||||
continue-on-error: true
|
||||
env:
|
||||
SONAR_HOST_URL: http://not_actually_used
|
||||
SONAR_SCANNER_JSON_PARAMS: '{"sonar.scanner.internal.dumpToFile": "./output.properties"}'
|
||||
with:
|
||||
projectBaseDir: ./test/gradle-project
|
||||
args: -Dsonar.scanner.internal.dumpToFile=./output.properties
|
||||
- name: Assert
|
||||
run: |
|
||||
./test/assertFileExists ./output.properties
|
||||
dontFailMavenTest:
|
||||
name: >
|
||||
Don't fail on Maven project
|
||||
runs-on: github-ubuntu-latest-s
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Run action on Maven project
|
||||
id: runTest
|
||||
uses: ./
|
||||
continue-on-error: true
|
||||
env:
|
||||
SONAR_HOST_URL: http://not_actually_used
|
||||
SONAR_SCANNER_JSON_PARAMS: '{"sonar.scanner.internal.dumpToFile": "./output.properties"}'
|
||||
with:
|
||||
projectBaseDir: ./test/maven-project
|
||||
args: -Dsonar.scanner.internal.dumpToFile=./output.properties
|
||||
- name: Assert
|
||||
run: |
|
||||
./test/assertFileExists ./output.properties
|
||||
runAnalysisTest:
|
||||
runs-on: github-ubuntu-latest-s
|
||||
services:
|
||||
sonarqube:
|
||||
image: sonarqube:lts-community
|
||||
ports:
|
||||
- 9000:9000
|
||||
volumes:
|
||||
- sonarqube_data:/opt/sonarqube/data
|
||||
- sonarqube_logs:/opt/sonarqube/logs
|
||||
- sonarqube_extensions:/opt/sonarqube/extensions
|
||||
options: >-
|
||||
--health-cmd "grep -Fq \"SonarQube is operational\" /opt/sonarqube/logs/sonar.log"
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 10
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Run action on sample project
|
||||
id: runTest
|
||||
uses: ./
|
||||
env:
|
||||
SONAR_HOST_URL: http://localhost:9000
|
||||
with:
|
||||
args: -Dsonar.login=admin -Dsonar.password=admin
|
||||
projectBaseDir: ./test/example-project
|
||||
- name: Assert
|
||||
run: |
|
||||
./test/assertFileExists ./test/example-project/.scannerwork/report-task.txt
|
||||
runnerDebugUsedTest:
|
||||
name: >
|
||||
'RUNNER_DEBUG' is used
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [github-ubuntu-latest-s, github-windows-latest-s, macos-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Run action with debug mode
|
||||
uses: ./
|
||||
with:
|
||||
args: -Dsonar.scanner.internal.dumpToFile=./output.properties
|
||||
env:
|
||||
RUNNER_DEBUG: 1
|
||||
SONAR_HOST_URL: http://not_actually_used
|
||||
SONAR_SCANNER_JSON_PARAMS: '{"sonar.scanner.internal.dumpToFile": "./output.properties"}'
|
||||
- name: Assert
|
||||
run: |
|
||||
./test/assertFileContains ./output.properties "sonar.verbose=true"
|
||||
runAnalysisWithCacheTest:
|
||||
runs-on: github-ubuntu-latest-s
|
||||
services:
|
||||
sonarqube:
|
||||
image: sonarqube:lts-community
|
||||
ports:
|
||||
- 9000:9000
|
||||
volumes:
|
||||
- sonarqube_data:/opt/sonarqube/data
|
||||
- sonarqube_logs:/opt/sonarqube/logs
|
||||
- sonarqube_extensions:/opt/sonarqube/extensions
|
||||
options: >-
|
||||
--health-cmd "grep -Fq \"SonarQube is operational\" /opt/sonarqube/logs/sonar.log"
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 10
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: SonarQube Cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{ github.workspace }}/.sonar/cache
|
||||
key: ${{ runner.os }}-${{ runner.arch }}-sonar
|
||||
- name: Run action on sample project
|
||||
id: runTest
|
||||
uses: ./
|
||||
env:
|
||||
SONAR_HOST_URL: http://localhost:9000
|
||||
SONAR_USER_HOME: ${{ github.workspace }}/.sonar
|
||||
with:
|
||||
args: -Dsonar.login=admin -Dsonar.password=admin
|
||||
projectBaseDir: ./test/example-project
|
||||
- name: Assert
|
||||
run: |
|
||||
./test/assertFileExists ./test/example-project/.scannerwork/report-task.txt
|
||||
overrideSonarcloudUrlTest:
|
||||
name: >
|
||||
'SONARCLOUD_URL' is used
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [github-ubuntu-latest-s, github-windows-latest-s, macos-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Run action with SONARCLOUD_URL
|
||||
uses: ./
|
||||
with:
|
||||
args: -Dsonar.scanner.apiBaseUrl=api.mirror.sonarcloud.io -Dsonar.scanner.internal.dumpToFile=./output.properties
|
||||
env:
|
||||
SONARCLOUD_URL: mirror.sonarcloud.io
|
||||
SONAR_TOKEN: FAKE_TOKEN
|
||||
- name: Assert
|
||||
run: |
|
||||
./test/assertFileContains ./output.properties "sonar.host.url=mirror.sonarcloud.io"
|
||||
./test/assertFileContains ./output.properties "sonar.scanner.sonarcloudUrl=mirror.sonarcloud.io"
|
||||
curlPerformsRedirect:
|
||||
name: >
|
||||
curl performs redirect when scannerBinariesUrl returns 3xx
|
||||
runs-on: github-ubuntu-latest-s
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Remove wget
|
||||
run: sudo apt-get remove -y wget
|
||||
- name: Assert wget is not available
|
||||
run: |
|
||||
if command -v wget 2>&1 >/dev/null
|
||||
then
|
||||
exit 1
|
||||
fi
|
||||
- name: Generate SSL certificates for nginx
|
||||
run: ./generate-ssl.sh
|
||||
working-directory: .github/qa-nginx-redirecting
|
||||
- name: Start nginx via Docker Compose
|
||||
run: docker compose up -d --wait
|
||||
working-directory: .github/qa-nginx-redirecting
|
||||
- name: Run action with scannerBinariesUrl
|
||||
id: runTest
|
||||
uses: ./
|
||||
with:
|
||||
scannerVersion: 6.2.1.4610
|
||||
scannerBinariesUrl: https://localhost:8080/clientRedirectToSonarBinaries
|
||||
env:
|
||||
NO_CACHE: true
|
||||
NODE_TLS_REJECT_UNAUTHORIZED: 0
|
||||
SONAR_HOST_URL: http://not_actually_used
|
||||
SONAR_SCANNER_JSON_PARAMS: '{"sonar.scanner.internal.dumpToFile": "./output1.properties"}'
|
||||
- name: Assert Sonar Scanner CLI was downloaded
|
||||
run: |
|
||||
# Verify the tool was installed by checking it's in PATH
|
||||
if ! command -v sonar-scanner &> /dev/null; then
|
||||
echo "Error: sonar-scanner not found in PATH"
|
||||
exit 1
|
||||
fi
|
||||
useSslCertificate:
|
||||
name: >
|
||||
'SONAR_ROOT_CERT' is converted to truststore
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [github-ubuntu-latest-s, github-windows-latest-s, macos-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Run action with SSL certificate
|
||||
uses: ./
|
||||
with:
|
||||
args: -Dsonar.scanner.internal.dumpToFile=./output.properties
|
||||
env:
|
||||
SONAR_ROOT_CERT: |
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIFtjCCA56gAwIBAgIULroxFuPWyNOiQtAVPS/XFFMXp6owDQYJKoZIhvcNAQEL
|
||||
BQAwXDELMAkGA1UEBhMCQ0gxDzANBgNVBAgMBkdlbmV2YTEPMA0GA1UEBwwGR2Vu
|
||||
ZXZhMRcwFQYDVQQKDA5Tb25hclNvdXJjZSBTQTESMBAGA1UEAwwJbG9jYWxob3N0
|
||||
MB4XDTI0MDQxNjA4NDUyMVoXDTM0MDQxNDA4NDUyMVowXDELMAkGA1UEBhMCQ0gx
|
||||
DzANBgNVBAgMBkdlbmV2YTEPMA0GA1UEBwwGR2VuZXZhMRcwFQYDVQQKDA5Tb25h
|
||||
clNvdXJjZSBTQTESMBAGA1UEAwwJbG9jYWxob3N0MIICIjANBgkqhkiG9w0BAQEF
|
||||
AAOCAg8AMIICCgKCAgEArRRQF25E5NCgXdoEBU2SWyAoyOWMGVT1Ioltnr3sJP6L
|
||||
MjjfozK5YgaRn504291lwlG+k6tvzTSR9HB8q3ITa8AdnwMiL7jzbveYKWIlLQ7k
|
||||
dHKXWbiaIjTaZCyfnWUlDFIuR7BHwOXVwyLrBQfhoyDVaaoyowQEsUro3okIR/kB
|
||||
sqM+KH8bcdl06DMMppZ8Qy1DYvPodhnNRyOSSpfbIoodE1fju+5U0OKzvGIc9WpG
|
||||
5pKIysaW3whOa/ieb02SXrgoiHnYPpmmGzm4u/Wn8jGwhYQJSQT10yjMacGHwmBE
|
||||
q7FUr854cVd+eend056P6pwUukdNeVHCFjYRkmWCNzIxV+sS9PPtDs77/bLFIItr
|
||||
nBMHVsId38tPoru/z1S1p2dzCX3Nq09aJFF/vH2u9Sg5aerHJ7xnRroR1jIrAZtc
|
||||
jBkJHEiTlG+WaavP4j6oym+lvHvgHHL3Qwhh8emg0JiLYExVV7ma70aRDh8yoQtS
|
||||
zAUDMVfhVPKd92MS+7DC2pv2KviUNKqbHDFadl01JN3t+17/gstUNSk1jpoUfUhK
|
||||
BeUQxVEdVUy2p0HeD/TYpRvF2FEsWneq3+ZbnRp17I/uEQOck0LP2tkzAd4tmRgH
|
||||
+95yyB8MgbAfvyKWkB4+3BhtdfoYDe1asqR6z43mejDHHqgBXn+u3UKjPypKfPEC
|
||||
AwEAAaNwMG4wHwYDVR0jBBgwFoAUINXfg3fn6/RUenW3EobpMoP8wDQwCQYDVR0T
|
||||
BAIwADALBgNVHQ8EBAMCBPAwFAYDVR0RBA0wC4IJbG9jYWxob3N0MB0GA1UdDgQW
|
||||
BBRX4bsny+8GQcFpM10jtAfFxzNxzzANBgkqhkiG9w0BAQsFAAOCAgEAa+Myw6li
|
||||
Fme95cPpINTite/9LXk+TlHHnXiV5Z+Um3NTLSllX3zPuRFiOE71OKFrWQPqH2N/
|
||||
85l6h19G9xQsaqkkVFyQENkNzykZpJL/jU4+wgRtwcEDkaRGGURZacz3vfLTc1HX
|
||||
tPDNv/JsZ5HE2d7cF5YhN4UahtxS2lvarrSujaOBpFZTT6PbEYX9EnwCdapORHOh
|
||||
wKMc3OGGOiGWvRlVaWu/Huq2HvXXcK0pmaYWWKX3u21evthSYOu9U4Rk0z1y7m3/
|
||||
CIYaIrvSbkzq2KKXMn7lr26bv2cthAQrPAjb2ILPUoyzKa3wEK3lkhanM6PN9CMH
|
||||
y5KRTpqwV45Qr6BAVY1bP67pEkay2T31chIVKds6dkx9b2/bWpW9PWuymsbWX2vO
|
||||
Q1MiaPkXKSTgCRwQUR0SNbPHw3X+VhrKKJB+beX8Bh2fcKw3jGGM8oHiA1hpdnbg
|
||||
Y5fW7EupF5gabf2jNB1XJ4gowlpB3nTooKFgbcgsvi68MRdBno2TWUhsZ3zCVyaH
|
||||
KFdDV0f78Fg7oL79K3kBL/iqr+jsb8sFHKIS4Dyyz2rDJrE0q0xAPes+Bu75R3/5
|
||||
M/s2H7KuLqLdDYsCsMeMqOVuIcAyPp2MFWInYPyi0zY4fwKwm8f/Kv8Lzb+moxqI
|
||||
Fct6d1S08JAosVnZcP2P7Yz+TbmDRtsqCgk=
|
||||
-----END CERTIFICATE-----
|
||||
SONAR_HOST_URL: http://not_actually_used
|
||||
- name: Assert
|
||||
run: |
|
||||
./test/assertFileExists ~/.sonar/ssl/truststore.p12
|
||||
analysisWithSslCertificate:
|
||||
name: >
|
||||
Analysis takes into account 'SONAR_ROOT_CERT'
|
||||
runs-on: github-ubuntu-latest-s
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Generate server certificate
|
||||
run: |
|
||||
openssl req \
|
||||
-newkey rsa:4096 \
|
||||
-x509 \
|
||||
-sha256 \
|
||||
-addext "subjectAltName = DNS:localhost" \
|
||||
-days 3650 \
|
||||
-nodes \
|
||||
-out server.crt \
|
||||
-subj "/C=CH/ST=Geneva/L=Geneva/O=Server/OU=Dept" \
|
||||
-keyout server.key
|
||||
working-directory: .github/qa-sq-behind-ngix
|
||||
- name: Start nginx and SonarQube via Docker Compose
|
||||
run: docker compose up -d --wait
|
||||
working-directory: .github/qa-sq-behind-ngix
|
||||
- name: Read correct server certificate
|
||||
run: |
|
||||
# read server.crt from .github/qa-sq-behind-ngix/ and store into the SONAR_ROOT_CERT_VALID
|
||||
# environment variable, to be able to read it in the next step
|
||||
{
|
||||
echo 'SONAR_ROOT_CERT_VALID<<=========='
|
||||
cat .github/qa-sq-behind-ngix/server.crt
|
||||
echo ==========
|
||||
} >> $GITHUB_ENV
|
||||
- name: Run action with the correct SSL certificate
|
||||
uses: ./
|
||||
env:
|
||||
SONAR_ROOT_CERT: ${{ env.SONAR_ROOT_CERT_VALID }}
|
||||
SONAR_HOST_URL: https://localhost:4443
|
||||
with:
|
||||
args: -Dsonar.login=admin -Dsonar.password=admin
|
||||
projectBaseDir: ./test/example-project
|
||||
- name: Clear imported SSL certificates
|
||||
run: |
|
||||
rm -f ~/.sonar/ssl/truststore.p12
|
||||
- name: Run action with an invalid SSL certificate
|
||||
id: invalid_ssl_certificate
|
||||
continue-on-error: true
|
||||
uses: ./
|
||||
env:
|
||||
SONAR_ROOT_CERT: |
|
||||
-----BEGIN CERTIFICATE-----
|
||||
INVALID
|
||||
-----END CERTIFICATE-----
|
||||
SONAR_HOST_URL: https://localhost:4443
|
||||
with:
|
||||
args: -Dsonar.login=admin -Dsonar.password=admin
|
||||
projectBaseDir: ./test/example-project
|
||||
- name: Assert failure of previous step
|
||||
if: steps.invalid_ssl_certificate.outcome == 'success'
|
||||
run: exit 1
|
||||
- name: Clear imported SSL certificates
|
||||
run: |
|
||||
rm -f ~/.sonar/ssl/truststore.p12
|
||||
- name: Run action with the wrong SSL certificate
|
||||
id: wrong_ssl_certificate
|
||||
continue-on-error: true
|
||||
uses: ./
|
||||
env:
|
||||
SONAR_ROOT_CERT: |
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIFlTCCA32gAwIBAgIUXK4LyGUFe4ZVL93StPXCoJzmnLMwDQYJKoZIhvcNAQEL
|
||||
BQAwTzELMAkGA1UEBhMCQ0gxDzANBgNVBAgMBkdlbmV2YTEPMA0GA1UEBwwGR2Vu
|
||||
ZXZhMQ8wDQYDVQQKDAZTZXJ2ZXIxDTALBgNVBAsMBERlcHQwHhcNMjQxMTAxMDgx
|
||||
MzM3WhcNMzQxMDMwMDgxMzM3WjBPMQswCQYDVQQGEwJDSDEPMA0GA1UECAwGR2Vu
|
||||
ZXZhMQ8wDQYDVQQHDAZHZW5ldmExDzANBgNVBAoMBlNlcnZlcjENMAsGA1UECwwE
|
||||
RGVwdDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK5m0V6IFFykib77
|
||||
nmlN7weS9q3D6YGEj+8hRNQViL9KduUoLjoKpONIihU5kfIg+5SkGygjHRkBvIp3
|
||||
b0HQqhkwtGln3/FxxaSfGEguLHgzXR8JDQSyJ8UKIGOPCH93n1rUip5Ok1iExVup
|
||||
HtkiVDRoCC9cRjZXbGOKrO6VBT4RvakpkaqCdXYikV244B5ElM7kdFdz8fso78Aq
|
||||
xekb9dM0f21uUaDBKCIhRcxWeafp0CJIoejTq0+PF7qA2qIY5UHqWElWO5NsvQ8+
|
||||
MqKkIdsOa1pYNuH/5eQ59k9KSE92ps1xTKweW000GfPqxx8IQ/e4aAd2SaMTKvN6
|
||||
aac6piWBeJ7AssgWwkg/3rnZB5seQIrWjIUePmxJ4c0g0eL9cnVpYF0K/Dldle/G
|
||||
wg0zi1g709rBI1TYj9xwrivxSwEQupz8OdKqOmgqrKHJJ/CCLl+JdFYjgwl3NWLH
|
||||
wsU639H1bMXIJoQujg9U47e9fXbwiqdkMQzt7rPGkOBBaAkSctAReiXnWy+CbVEM
|
||||
QFHDrnD5YUJRd5t/DUuWuqhR2QhfUvRClPUKoVqB/iOu2IumlgDEDA8jb1dxEW+W
|
||||
iaYokQCS94OpxOJ8aeReSt9bghT0vc9ifCLWvuE1iBjujdK32ekKSY9DCZyBHXsG
|
||||
J9N1nt1qd/k7QqWOkuPjr1JrTIMbAgMBAAGjaTBnMB0GA1UdDgQWBBQw4ESReEk+
|
||||
AIxwjHRqPkESzMv1bTAfBgNVHSMEGDAWgBQw4ESReEk+AIxwjHRqPkESzMv1bTAP
|
||||
BgNVHRMBAf8EBTADAQH/MBQGA1UdEQQNMAuCCWxvY2FsaG9zdDANBgkqhkiG9w0B
|
||||
AQsFAAOCAgEAE8WefoZN23aOSe79ZN7zRBWP8DdPgFAqg5XUhfc9bCIVfJ4XMpEe
|
||||
3lzRhgjwDm4naEs35QWOhPZH2vx8XrEKnZNI6vKO8JzaCsivgngk8bsWnvhwSXy5
|
||||
eFdc99K+FOmOHevDmeiimoQnikffnSULRhQYzE2Qwyo9iky8703/+D3IKEC/8exC
|
||||
rlyGMUV/Nqj+4M+57DiZ6OXeFuunfoFB7vmcDZygqDhKoHhVRyu8qN6PeK2fvUFK
|
||||
EjeRtvA0GkdlOtLIF2g5yBTK2ykkt/oLUoAolfYUTKcoV2/FS0gVR5ovmEpKyBcP
|
||||
H9hzr16a8dtrEqOf/oKHQSLwxn8afmS354HJ75sq9SujOtIWpHfyH5IgqtUpiBN/
|
||||
bzvKs/QZjtGlqvquOTkdh9L4oxTXqG7zEStZyo/v9g5jf1Tq195b2DNFwVUZIcbb
|
||||
u2d4CvAZ1yNr+8ax/kTwBSY8WU+mCtmvowFstdvsJXVXJKnUO6EZOdbg0GxTBVyE
|
||||
zMsnPcnkOwV5TJIKKhonrgrwmPmQ9IOV9BrThVxujjjEbAdA6jM9PMiXzuDukldm
|
||||
QBRwNbczGbdsHkMKHmQnrTqOyQyI4KCXF08kcOm4C1P+Whrvi0DXkqHnyKvBE0td
|
||||
dciInBoeHwUs2eclz7gP7pMBJUlFUkKfQxwxGLIqZSXnlAFBfW6hHLI=
|
||||
-----END CERTIFICATE-----
|
||||
SONAR_HOST_URL: https://localhost:4443
|
||||
with:
|
||||
args: -Dsonar.login=admin -Dsonar.password=admin
|
||||
projectBaseDir: ./test/example-project
|
||||
- name: Assert failure of previous step
|
||||
if: steps.wrong_ssl_certificate.outcome == 'success'
|
||||
run: exit 1
|
||||
updateTruststoreWhenPresent: # can happen in uncleaned self-hosted runners
|
||||
name: >
|
||||
truststore.p12 is updated when present
|
||||
runs-on: github-ubuntu-latest-s
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Create SONAR_SSL_FOLDER with a file in it (not-truststore.p12)
|
||||
run: |
|
||||
SONAR_SSL_FOLDER=~/.sonar/ssl
|
||||
mkdir -p "$SONAR_SSL_FOLDER"
|
||||
touch "$SONAR_SSL_FOLDER/not-truststore.p12"
|
||||
# emit SONAR_SSL_FOLDER to be able to read it in the next steps
|
||||
echo "SONAR_SSL_FOLDER=$SONAR_SSL_FOLDER" >> $GITHUB_ENV
|
||||
- name: Assert truststore.p12 does not file exists
|
||||
run: |
|
||||
[ ! -f "$SONAR_SSL_FOLDER/truststore.p12" ] || exit 1
|
||||
- name: Run action with SONAR_ROOT_CERT
|
||||
uses: ./
|
||||
env:
|
||||
# NO_CACHE not needed, as SONAR_SSL_FOLDER is setup when the Sonar Scanner is run, not installed
|
||||
SONAR_HOST_URL: http://not_actually_used
|
||||
SONAR_ROOT_CERT: |
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIFlTCCA32gAwIBAgIUXK4LyGUFe4ZVL93StPXCoJzmnLMwDQYJKoZIhvcNAQEL
|
||||
BQAwTzELMAkGA1UEBhMCQ0gxDzANBgNVBAgMBkdlbmV2YTEPMA0GA1UEBwwGR2Vu
|
||||
ZXZhMQ8wDQYDVQQKDAZTZXJ2ZXIxDTALBgNVBAsMBERlcHQwHhcNMjQxMTAxMDgx
|
||||
MzM3WhcNMzQxMDMwMDgxMzM3WjBPMQswCQYDVQQGEwJDSDEPMA0GA1UECAwGR2Vu
|
||||
ZXZhMQ8wDQYDVQQHDAZHZW5ldmExDzANBgNVBAoMBlNlcnZlcjENMAsGA1UECwwE
|
||||
RGVwdDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK5m0V6IFFykib77
|
||||
nmlN7weS9q3D6YGEj+8hRNQViL9KduUoLjoKpONIihU5kfIg+5SkGygjHRkBvIp3
|
||||
b0HQqhkwtGln3/FxxaSfGEguLHgzXR8JDQSyJ8UKIGOPCH93n1rUip5Ok1iExVup
|
||||
HtkiVDRoCC9cRjZXbGOKrO6VBT4RvakpkaqCdXYikV244B5ElM7kdFdz8fso78Aq
|
||||
xekb9dM0f21uUaDBKCIhRcxWeafp0CJIoejTq0+PF7qA2qIY5UHqWElWO5NsvQ8+
|
||||
MqKkIdsOa1pYNuH/5eQ59k9KSE92ps1xTKweW000GfPqxx8IQ/e4aAd2SaMTKvN6
|
||||
aac6piWBeJ7AssgWwkg/3rnZB5seQIrWjIUePmxJ4c0g0eL9cnVpYF0K/Dldle/G
|
||||
wg0zi1g709rBI1TYj9xwrivxSwEQupz8OdKqOmgqrKHJJ/CCLl+JdFYjgwl3NWLH
|
||||
wsU639H1bMXIJoQujg9U47e9fXbwiqdkMQzt7rPGkOBBaAkSctAReiXnWy+CbVEM
|
||||
QFHDrnD5YUJRd5t/DUuWuqhR2QhfUvRClPUKoVqB/iOu2IumlgDEDA8jb1dxEW+W
|
||||
iaYokQCS94OpxOJ8aeReSt9bghT0vc9ifCLWvuE1iBjujdK32ekKSY9DCZyBHXsG
|
||||
J9N1nt1qd/k7QqWOkuPjr1JrTIMbAgMBAAGjaTBnMB0GA1UdDgQWBBQw4ESReEk+
|
||||
AIxwjHRqPkESzMv1bTAfBgNVHSMEGDAWgBQw4ESReEk+AIxwjHRqPkESzMv1bTAP
|
||||
BgNVHRMBAf8EBTADAQH/MBQGA1UdEQQNMAuCCWxvY2FsaG9zdDANBgkqhkiG9w0B
|
||||
AQsFAAOCAgEAE8WefoZN23aOSe79ZN7zRBWP8DdPgFAqg5XUhfc9bCIVfJ4XMpEe
|
||||
3lzRhgjwDm4naEs35QWOhPZH2vx8XrEKnZNI6vKO8JzaCsivgngk8bsWnvhwSXy5
|
||||
eFdc99K+FOmOHevDmeiimoQnikffnSULRhQYzE2Qwyo9iky8703/+D3IKEC/8exC
|
||||
rlyGMUV/Nqj+4M+57DiZ6OXeFuunfoFB7vmcDZygqDhKoHhVRyu8qN6PeK2fvUFK
|
||||
EjeRtvA0GkdlOtLIF2g5yBTK2ykkt/oLUoAolfYUTKcoV2/FS0gVR5ovmEpKyBcP
|
||||
H9hzr16a8dtrEqOf/oKHQSLwxn8afmS354HJ75sq9SujOtIWpHfyH5IgqtUpiBN/
|
||||
bzvKs/QZjtGlqvquOTkdh9L4oxTXqG7zEStZyo/v9g5jf1Tq195b2DNFwVUZIcbb
|
||||
u2d4CvAZ1yNr+8ax/kTwBSY8WU+mCtmvowFstdvsJXVXJKnUO6EZOdbg0GxTBVyE
|
||||
zMsnPcnkOwV5TJIKKhonrgrwmPmQ9IOV9BrThVxujjjEbAdA6jM9PMiXzuDukldm
|
||||
QBRwNbczGbdsHkMKHmQnrTqOyQyI4KCXF08kcOm4C1P+Whrvi0DXkqHnyKvBE0td
|
||||
dciInBoeHwUs2eclz7gP7pMBJUlFUkKfQxwxGLIqZSXnlAFBfW6hHLI=
|
||||
-----END CERTIFICATE-----
|
||||
with:
|
||||
args: -Dsonar.scanner.internal.dumpToFile=./output.properties
|
||||
- name: Assert not-truststore.p12 file still exists
|
||||
run: |
|
||||
[ -f "$SONAR_SSL_FOLDER/not-truststore.p12" ] || exit 1
|
||||
- name: Assert truststore.p12 file now exists and take note of modification time
|
||||
run: |
|
||||
[ -f "$SONAR_SSL_FOLDER/truststore.p12" ] || exit 1
|
||||
# emit the modification time of the truststore.p12 file to be able to read it in the next steps
|
||||
TRUSTSTORE_P12_MOD_TIME_T1=$(stat -c %Y "$SONAR_SSL_FOLDER/truststore.p12")
|
||||
echo "TRUSTSTORE_P12_MOD_TIME_T1=$TRUSTSTORE_P12_MOD_TIME_T1" >> $GITHUB_ENV
|
||||
- name: Run action a second time with a different SONAR_ROOT_CERT
|
||||
uses: ./
|
||||
env:
|
||||
# NO_CACHE not needed, as SONAR_SSL_FOLDER is setup when the Sonar Scanner is run, not installed
|
||||
SONAR_HOST_URL: http://not_actually_used
|
||||
SONAR_ROOT_CERT: |
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICgTCCAeoCCQCbOlrWDdX7FTANBgkqhkiG9w0BAQUFADCBhDELMAkGA1UEBhMC
|
||||
Tk8xGDAWBgNVBAgTD0FuZHJlYXMgU29sYmVyZzEMMAoGA1UEBxMDRm9vMRAwDgYD
|
||||
VQQKEwdVTklORVRUMRgwFgYDVQQDEw9mZWlkZS5lcmxhbmcubm8xITAfBgkqhkiG
|
||||
9w0BCQEWEmFuZHJlYXNAdW5pbmV0dC5ubzAeFw0wNzA2MTUxMjAxMzVaFw0wNzA4
|
||||
MTQxMjAxMzVaMIGEMQswCQYDVQQGEwJOTzEYMBYGA1UECBMPQW5kcmVhcyBTb2xi
|
||||
ZXJnMQwwCgYDVQQHEwNGb28xEDAOBgNVBAoTB1VOSU5FVFQxGDAWBgNVBAMTD2Zl
|
||||
aWRlLmVybGFuZy5ubzEhMB8GCSqGSIb3DQEJARYSYW5kcmVhc0B1bmluZXR0Lm5v
|
||||
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDivbhR7P516x/S3BqKxupQe0LO
|
||||
NoliupiBOesCO3SHbDrl3+q9IbfnfmE04rNuMcPsIxB161TdDpIesLCn7c8aPHIS
|
||||
KOtPlAeTZSnb8QAu7aRjZq3+PbrP5uW3TcfCGPtKTytHOge/OlJbo078dVhXQ14d
|
||||
1EDwXJW1rRXuUt4C8QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBACDVfp86HObqY+e8
|
||||
BUoWQ9+VMQx1ASDohBjwOsg2WykUqRXF+dLfcUH9dWR63CtZIKFDbStNomPnQz7n
|
||||
bK+onygwBspVEbnHuUihZq3ZUdmumQqCw4Uvs/1Uvq3orOo/WJVhTyvLgFVK2Qar
|
||||
Q4/67OZfHd7R+POBXhophSMv1ZOo
|
||||
-----END CERTIFICATE-----
|
||||
with:
|
||||
args: -Dsonar.scanner.internal.dumpToFile=./output.properties
|
||||
- name: Assert truststore.p12 still exists, but it has been updated, and take note of modification time
|
||||
run: |
|
||||
[ -f "$SONAR_SSL_FOLDER/truststore.p12" ] || exit 1
|
||||
TRUSTSTORE_P12_MOD_TIME_T2=$(stat -c %Y "$SONAR_SSL_FOLDER/truststore.p12")
|
||||
[ "$TRUSTSTORE_P12_MOD_TIME_T1" != "$TRUSTSTORE_P12_MOD_TIME_T2" ] || exit 1
|
||||
# emit the modification time of the truststore.p12 file to be able to read it in the next steps
|
||||
echo "TRUSTSTORE_P12_MOD_TIME_T2=$TRUSTSTORE_P12_MOD_TIME_T2" >> $GITHUB_ENV
|
||||
- name: Remove sonar alias from truststore.p12
|
||||
run: keytool -delete -alias sonar -keystore "$SONAR_SSL_FOLDER/truststore.p12" -storepass changeit
|
||||
- name: Run action a third time
|
||||
uses: ./
|
||||
env:
|
||||
# NO_CACHE not needed, as SONAR_SSL_FOLDER is setup when the Sonar Scanner is run, not installed
|
||||
SONAR_HOST_URL: http://not_actually_used
|
||||
SONAR_ROOT_CERT: |
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICgTCCAeoCCQCbOlrWDdX7FTANBgkqhkiG9w0BAQUFADCBhDELMAkGA1UEBhMC
|
||||
Tk8xGDAWBgNVBAgTD0FuZHJlYXMgU29sYmVyZzEMMAoGA1UEBxMDRm9vMRAwDgYD
|
||||
VQQKEwdVTklORVRUMRgwFgYDVQQDEw9mZWlkZS5lcmxhbmcubm8xITAfBgkqhkiG
|
||||
9w0BCQEWEmFuZHJlYXNAdW5pbmV0dC5ubzAeFw0wNzA2MTUxMjAxMzVaFw0wNzA4
|
||||
MTQxMjAxMzVaMIGEMQswCQYDVQQGEwJOTzEYMBYGA1UECBMPQW5kcmVhcyBTb2xi
|
||||
ZXJnMQwwCgYDVQQHEwNGb28xEDAOBgNVBAoTB1VOSU5FVFQxGDAWBgNVBAMTD2Zl
|
||||
aWRlLmVybGFuZy5ubzEhMB8GCSqGSIb3DQEJARYSYW5kcmVhc0B1bmluZXR0Lm5v
|
||||
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDivbhR7P516x/S3BqKxupQe0LO
|
||||
NoliupiBOesCO3SHbDrl3+q9IbfnfmE04rNuMcPsIxB161TdDpIesLCn7c8aPHIS
|
||||
KOtPlAeTZSnb8QAu7aRjZq3+PbrP5uW3TcfCGPtKTytHOge/OlJbo078dVhXQ14d
|
||||
1EDwXJW1rRXuUt4C8QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBACDVfp86HObqY+e8
|
||||
BUoWQ9+VMQx1ASDohBjwOsg2WykUqRXF+dLfcUH9dWR63CtZIKFDbStNomPnQz7n
|
||||
bK+onygwBspVEbnHuUihZq3ZUdmumQqCw4Uvs/1Uvq3orOo/WJVhTyvLgFVK2Qar
|
||||
Q4/67OZfHd7R+POBXhophSMv1ZOo
|
||||
-----END CERTIFICATE-----
|
||||
with:
|
||||
args: -Dsonar.scanner.internal.dumpToFile=./output.properties
|
||||
- name: Assert truststore.p12 still exists, and it has been updated again
|
||||
run: |
|
||||
[ -f "$SONAR_SSL_FOLDER/truststore.p12" ] || exit 1
|
||||
TRUSTSTORE_P12_MOD_TIME_T3=$(stat -c %Y "$SONAR_SSL_FOLDER/truststore.p12")
|
||||
[ "$TRUSTSTORE_P12_MOD_TIME_T2" != "$TRUSTSTORE_P12_MOD_TIME_T3" ] || exit 1
|
||||
scannerVersionValidationTest:
|
||||
name: >
|
||||
'scannerVersion' input validation
|
||||
runs-on: github-ubuntu-latest-s
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Run action with invalid scannerVersion
|
||||
id: invalid_version
|
||||
uses: ./
|
||||
continue-on-error: true
|
||||
with:
|
||||
scannerVersion: "7.1.0-SNAPSHOT"
|
||||
args: -Dsonar.scanner.internal.dumpToFile=./output.properties
|
||||
env:
|
||||
NO_CACHE: true
|
||||
SONAR_HOST_URL: http://not_actually_used
|
||||
- name: Assert failure of previous step
|
||||
if: steps.invalid_version.outcome == 'success'
|
||||
run: |
|
||||
echo "Action with invalid scannerVersion should have failed but succeeded"
|
||||
exit 1
|
||||
351
.github/workflows/qa-scripts.yml
vendored
Normal file
351
.github/workflows/qa-scripts.yml
vendored
Normal file
|
|
@ -0,0 +1,351 @@
|
|||
name: QA Scripts
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
|
||||
jobs:
|
||||
create-install-dir-test:
|
||||
name: create_install_path.sh
|
||||
runs-on: github-ubuntu-latest-s
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
|
||||
|
||||
- name: Existing
|
||||
shell: bash
|
||||
env:
|
||||
INSTALL_PATH: '.sonar'
|
||||
run: |
|
||||
echo "- Create dir"
|
||||
mkdir -p "${INSTALL_PATH}"
|
||||
|
||||
echo "- Test script behavior"
|
||||
./scripts/create_install_path.sh > output
|
||||
grep -v "::error::" output
|
||||
|
||||
- name: Non-existing nested in current dir
|
||||
shell: bash
|
||||
env:
|
||||
INSTALL_PATH: '.sonar'
|
||||
run: |
|
||||
./scripts/create_install_path.sh > output
|
||||
grep -v "::error::" output
|
||||
test -d "${INSTALL_PATH}"
|
||||
|
||||
- name: Nonexisting nested in home
|
||||
shell: bash
|
||||
env:
|
||||
INSTALL_PATH: '~/third_party/.sonar'
|
||||
run: |
|
||||
./scripts/create_install_path.sh > output
|
||||
grep -v "::error::" output
|
||||
test -d "${INSTALL_PATH}"
|
||||
|
||||
- name: Empty install dir specified
|
||||
shell: bash
|
||||
env:
|
||||
INSTALL_PATH: ''
|
||||
run: |
|
||||
(./scripts/create_install_path.sh || echo "=== Script failed ===") > output
|
||||
grep "::error::Empty installation path specified" output
|
||||
grep "=== Script failed ===" output
|
||||
|
||||
- name: No permission to create directory
|
||||
shell: bash
|
||||
env:
|
||||
INSTALL_PATH: '/non_creatable'
|
||||
run: |
|
||||
(./scripts/create_install_path.sh || echo "=== Script failed ===") > output
|
||||
grep "::error::Failed to create non-existing installation path '/non_creatable'" output
|
||||
grep "=== Script failed ===" output
|
||||
|
||||
- name: Existing but not directory
|
||||
shell: bash
|
||||
env:
|
||||
INSTALL_PATH: 'not_directory'
|
||||
run: |
|
||||
echo "- Create normal file"
|
||||
echo "content" > "${INSTALL_PATH}"
|
||||
|
||||
echo "- Test script behavior"
|
||||
(./scripts/create_install_path.sh || echo "=== Script failed ===") > output
|
||||
grep "::error::Installation path 'not_directory' is not a directory" output
|
||||
grep "=== Script failed ===" output
|
||||
|
||||
|
||||
- name: Existing but not readable
|
||||
shell: bash
|
||||
env:
|
||||
INSTALL_PATH: 'not_readable'
|
||||
run: |
|
||||
echo "- Create dir and make it not readable"
|
||||
mkdir -p "${INSTALL_PATH}"
|
||||
chmod -r "${INSTALL_PATH}"
|
||||
|
||||
echo "- Test script behavior"
|
||||
(./scripts/create_install_path.sh || echo "=== Script failed ===") > output
|
||||
grep "::error::Installation path 'not_readable' is not readable" output
|
||||
grep "=== Script failed ===" output
|
||||
|
||||
- name: Existing but not writeable
|
||||
shell: bash
|
||||
env:
|
||||
INSTALL_PATH: 'not_writeable'
|
||||
run: |
|
||||
echo "- Create dir and make it not writeable"
|
||||
mkdir -p "${INSTALL_PATH}"
|
||||
chmod -w "${INSTALL_PATH}"
|
||||
|
||||
echo "- Test script behavior"
|
||||
(./scripts/create_install_path.sh || echo "=== Script failed ===") > output
|
||||
grep "::error::Installation path 'not_writeable' is not writeable" output
|
||||
grep "=== Script failed ===" output
|
||||
setup-script-test:
|
||||
name: configure_paths.sh
|
||||
runs-on: github-ubuntu-latest-s
|
||||
env:
|
||||
INSTALL_PATH: 'install-directory'
|
||||
SONAR_HOST_URL: 'http://sonar-host.com'
|
||||
SONAR_SCANNER_VERSION: 'vX.Y.Z.MMMM'
|
||||
SONAR_SCANNER_URL_WINDOWS_X64: 'https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-vX.Y.Z.MMMM-windows-x64.zip'
|
||||
SONAR_SCANNER_SHA_WINDOWS_X64: 'DOWNLOAD-SHA-WINDOWS-X64'
|
||||
SONAR_SCANNER_URL_LINUX_X64: 'https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-vX.Y.Z.MMMM-linux-x64.zip'
|
||||
SONAR_SCANNER_SHA_LINUX_X64: 'DOWNLOAD-SHA-LINUX-X64'
|
||||
SONAR_SCANNER_URL_LINUX_AARCH64: 'https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-vX.Y.Z.MMMM-linux-aarch64.zip'
|
||||
SONAR_SCANNER_SHA_LINUX_AARCH64: 'DOWNLOAD-SHA-LINUX-AARCH64'
|
||||
SONAR_SCANNER_URL_MACOSX_X64: 'https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-vX.Y.Z.MMMM-macosx-x64.zip'
|
||||
SONAR_SCANNER_SHA_MACOSX_X64: 'DOWNLOAD-SHA-MACOSX-X64'
|
||||
SONAR_SCANNER_URL_MACOSX_AARCH64: 'https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-vX.Y.Z.MMMM-macosx-aarch64.zip'
|
||||
SONAR_SCANNER_SHA_MACOSX_AARCH64: 'DOWNLOAD-SHA-MACOSX-AARCH64'
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
|
||||
|
||||
- name: Windows
|
||||
shell: bash
|
||||
env:
|
||||
OS: 'Windows'
|
||||
ARCH: 'X64'
|
||||
run: |
|
||||
./scripts/configure_paths.sh > output
|
||||
grep -v "::error::" output
|
||||
|
||||
echo "- Check sonar-scanner:"
|
||||
grep "sonar-scanner-url=https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-vX.Y.Z.MMMM-windows-x64.zip" output
|
||||
grep "sonar-scanner-sha=DOWNLOAD-SHA-WINDOWS-X64" output
|
||||
grep "sonar-scanner-dir=install-directory/sonar-scanner-vX.Y.Z.MMMM-windows-x64" output
|
||||
grep "sonar-scanner-bin=install-directory/sonar-scanner-vX.Y.Z.MMMM-windows-x64/bin/sonar-scanner.bat" output
|
||||
|
||||
echo "- Check build-wrapper:"
|
||||
grep "build-wrapper-url=http://sonar-host.com/static/cpp/build-wrapper-win-x86.zip" output
|
||||
grep "build-wrapper-dir=install-directory/build-wrapper-win-x86" output
|
||||
grep "build-wrapper-bin=install-directory/build-wrapper-win-x86/build-wrapper-win-x86-64.exe" output
|
||||
|
||||
- name: Linux X64
|
||||
shell: bash
|
||||
env:
|
||||
OS: 'Linux'
|
||||
ARCH: 'X64'
|
||||
run: |
|
||||
./scripts/configure_paths.sh > output
|
||||
grep -v "::error::" output
|
||||
|
||||
echo "- Check sonar-scanner:"
|
||||
grep "sonar-scanner-url=https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-vX.Y.Z.MMMM-linux-x64.zip" output
|
||||
grep "sonar-scanner-sha=DOWNLOAD-SHA-LINUX-X64" output
|
||||
grep "sonar-scanner-dir=install-directory/sonar-scanner-vX.Y.Z.MMMM-linux-x64" output
|
||||
grep "sonar-scanner-bin=install-directory/sonar-scanner-vX.Y.Z.MMMM-linux-x64/bin/sonar-scanner" output
|
||||
|
||||
echo "- Check build-wrapper:"
|
||||
grep "build-wrapper-url=http://sonar-host.com/static/cpp/build-wrapper-linux-x86.zip" output
|
||||
grep "build-wrapper-dir=install-directory/build-wrapper-linux-x86" output
|
||||
grep "build-wrapper-bin=install-directory/build-wrapper-linux-x86/build-wrapper-linux-x86-64" output
|
||||
|
||||
- name: Linux ARM64
|
||||
shell: bash
|
||||
env:
|
||||
OS: 'Linux'
|
||||
ARCH: 'ARM64'
|
||||
run: |
|
||||
./scripts/configure_paths.sh > output
|
||||
grep -v "::error::" output
|
||||
echo "- Check sonar-scanner:"
|
||||
grep "sonar-scanner-url=https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-vX.Y.Z.MMMM-linux-aarch64.zip" output
|
||||
grep "sonar-scanner-sha=DOWNLOAD-SHA-LINUX-AARCH64" output
|
||||
grep "sonar-scanner-dir=install-directory/sonar-scanner-vX.Y.Z.MMMM-linux-aarch64" output
|
||||
grep "sonar-scanner-bin=install-directory/sonar-scanner-vX.Y.Z.MMMM-linux-aarch64/bin/sonar-scanner" output
|
||||
echo "- Check build-wrapper:"
|
||||
grep "build-wrapper-url=http://sonar-host.com/static/cpp/build-wrapper-linux-aarch64.zip" output
|
||||
grep "build-wrapper-dir=install-directory/build-wrapper-linux-aarch64" output
|
||||
grep "build-wrapper-bin=install-directory/build-wrapper-linux-aarch64/build-wrapper-linux-aarch64" output
|
||||
|
||||
- name: macOSX_X64
|
||||
shell: bash
|
||||
env:
|
||||
OS: 'macOS'
|
||||
ARCH: 'X64'
|
||||
run: |
|
||||
./scripts/configure_paths.sh > output
|
||||
grep -v "::error::" output
|
||||
|
||||
echo "- Check sonar-scanner:"
|
||||
grep "sonar-scanner-url=https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-vX.Y.Z.MMMM-macosx-x64.zip" output
|
||||
grep "sonar-scanner-sha=DOWNLOAD-SHA-MACOSX-X64" output
|
||||
grep "sonar-scanner-dir=install-directory/sonar-scanner-vX.Y.Z.MMMM-macosx-x64" output
|
||||
grep "sonar-scanner-bin=install-directory/sonar-scanner-vX.Y.Z.MMMM-macosx-x64/bin/sonar-scanner" output
|
||||
|
||||
echo "- Check build-wrapper:"
|
||||
grep "build-wrapper-url=http://sonar-host.com/static/cpp/build-wrapper-macosx-x86.zip" output
|
||||
grep "build-wrapper-dir=install-directory/build-wrapper-macosx-x86" output
|
||||
grep "build-wrapper-bin=install-directory/build-wrapper-macosx-x86/build-wrapper-macosx-x86" output
|
||||
|
||||
- name: macOSX_ARM64
|
||||
shell: bash
|
||||
env:
|
||||
OS: 'macOS'
|
||||
ARCH: 'ARM64'
|
||||
run: |
|
||||
./scripts/configure_paths.sh > output
|
||||
grep -v "::error::" output
|
||||
|
||||
echo "- Check sonar-scanner:"
|
||||
grep "sonar-scanner-url=https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-vX.Y.Z.MMMM-macosx-aarch64.zip" output
|
||||
grep "sonar-scanner-sha=DOWNLOAD-SHA-MACOSX-AARCH64" output
|
||||
grep "sonar-scanner-dir=install-directory/sonar-scanner-vX.Y.Z.MMMM-macosx-aarch64" output
|
||||
grep "sonar-scanner-bin=install-directory/sonar-scanner-vX.Y.Z.MMMM-macosx-aarch64/bin/sonar-scanner" output
|
||||
|
||||
echo "- Check build-wrapper:"
|
||||
grep "build-wrapper-url=http://sonar-host.com/static/cpp/build-wrapper-macosx-x86.zip" output
|
||||
grep "build-wrapper-dir=install-directory/build-wrapper-macosx-x86" output
|
||||
grep "build-wrapper-bin=install-directory/build-wrapper-macosx-x86/build-wrapper-macosx-x86" output
|
||||
|
||||
- name: Unsupported OS
|
||||
shell: bash
|
||||
env:
|
||||
OS: 'unsupportedOS'
|
||||
ARCH: 'X64'
|
||||
run: |
|
||||
(./scripts/configure_paths.sh || echo "=== Script failed ===") > output
|
||||
|
||||
echo "- Check errors:"
|
||||
grep "::error::Unsupported runner OS 'unsupportedOS'" output
|
||||
grep "=== Script failed ===" output
|
||||
|
||||
- name: Unsupported architecture
|
||||
shell: bash
|
||||
env:
|
||||
OS: 'Linux'
|
||||
ARCH: 'X86'
|
||||
run: |
|
||||
(./scripts/configure_paths.sh || echo "=== Script failed ===") > output
|
||||
|
||||
echo "- Check errors:"
|
||||
grep "::error::Architecture 'X86' is unsupported by build-wrapper" output
|
||||
grep "=== Script failed ===" output
|
||||
download-script-test:
|
||||
name: download.sh
|
||||
runs-on: github-ubuntu-latest-s
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
|
||||
|
||||
- name: Download test without validation
|
||||
shell: bash
|
||||
env:
|
||||
INSTALL_PATH: 'install-directory-no-sha-validation'
|
||||
DOWNLOAD_URL: 'https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.6.2.2472-linux.zip'
|
||||
EXPECTED_SHA: 'incorrect-sha-not-validated'
|
||||
TMP_ZIP_PATH: ${{ runner.temp }}/sonar-scanner.zip
|
||||
run: |
|
||||
./scripts/download.sh > output
|
||||
test -f "$TMP_ZIP_PATH"
|
||||
grep -v "::error::" output
|
||||
- name: Download test with validation
|
||||
shell: bash
|
||||
env:
|
||||
INSTALL_PATH: 'install-directory-sha-validation'
|
||||
DOWNLOAD_URL: 'https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.6.2.2472-linux.zip'
|
||||
EXPECTED_SHA: '9411331814c1d002bd65d37758b872918b7602e7cf3ca5b83a3e19a729b2be05'
|
||||
TMP_ZIP_PATH: ${{ runner.temp }}/sonar-scanner.zip
|
||||
run: |
|
||||
./scripts/download.sh -v > output
|
||||
test -f "$TMP_ZIP_PATH"
|
||||
grep -v "::error::" output
|
||||
- name: Incorrect install dir
|
||||
shell: bash
|
||||
env:
|
||||
INSTALL_PATH: ''
|
||||
run: |
|
||||
(./scripts/download.sh || echo "=== Script failed ===") > output
|
||||
grep "::error::Failed to create" output
|
||||
grep "=== Script failed ===" output
|
||||
- name: Incorrect download url
|
||||
shell: bash
|
||||
env:
|
||||
INSTALL_PATH: 'install-directory-incorrect-url'
|
||||
DOWNLOAD_URL: 'incorrect-url'
|
||||
run: |
|
||||
(./scripts/download.sh || echo "=== Script failed ===") > output
|
||||
grep "::error::Failed to download 'incorrect-url'" output
|
||||
grep "=== Script failed ===" output
|
||||
- name: Incorrect SHA256
|
||||
shell: bash
|
||||
env:
|
||||
INSTALL_PATH: 'install-directory-incorrect-sha'
|
||||
DOWNLOAD_URL: 'https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.6.2.2472-linux.zip'
|
||||
EXPECTED_SHA: 'incorrect-sha256'
|
||||
TMP_ZIP_PATH: ${{ runner.temp }}/sonar-scanner.zip
|
||||
run: |
|
||||
(./scripts/download.sh -v || echo "=== Script failed ===") > output
|
||||
grep "::error::Checking sha256 failed" output
|
||||
grep "=== Script failed ===" output
|
||||
- name: Mismatching SHA256
|
||||
shell: bash
|
||||
env:
|
||||
INSTALL_PATH: 'install-directory-mismtaching-sha'
|
||||
DOWNLOAD_URL: 'https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.6.2.2472-linux.zip'
|
||||
EXPECTED_SHA: '3e121d85a4adb1f30b917d5f3eb897966b59e02c3d6d313a78dcd964193dc963'
|
||||
TMP_ZIP_PATH: ${{ runner.temp }}/sonar-scanner.zip
|
||||
run: |
|
||||
(./scripts/download.sh -v || echo "=== Script failed ===") > output
|
||||
grep "::error::Checking sha256 failed" output
|
||||
grep "=== Script failed ===" output
|
||||
fetch-latest-version-test:
|
||||
name: fetch_latest_version.sh
|
||||
runs-on: github-ubuntu-latest-s
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
|
||||
- name: Test script
|
||||
shell: bash
|
||||
run: |
|
||||
./scripts/fetch_latest_version.sh > output
|
||||
|
||||
echo "- Check sonar-scanner version:"
|
||||
grep "sonar-scanner-version=" output
|
||||
SONAR_SCANNER_VERSION=$(cat output | cut -d= -f 2)
|
||||
test ! -z "${SONAR_SCANNER_VERSION}"
|
||||
|
||||
echo "- Check windows sonar-scanner URLs:"
|
||||
grep "sonar-scanner-url-windows-x64=https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-${SONAR_SCANNER_VERSION}-windows-x64.zip" output
|
||||
grep -e "^sonar-scanner-sha-windows-x64=[0-9A-Fa-f]\+$" output
|
||||
|
||||
echo "- Check linux sonar-scanner URLs:"
|
||||
grep "sonar-scanner-url-linux-x64=https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-${SONAR_SCANNER_VERSION}-linux-x64.zip" output
|
||||
grep -e "^sonar-scanner-sha-linux-x64=[0-9A-Fa-f]\+$" output
|
||||
grep "sonar-scanner-url-linux-aarch64=https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-${SONAR_SCANNER_VERSION}-linux-aarch64.zip" output
|
||||
grep -e "^sonar-scanner-sha-linux-aarch64=[0-9A-Fa-f]\+$" output
|
||||
|
||||
echo "- Check macosx sonar-scanner URLs:"
|
||||
grep "sonar-scanner-url-linux-x64=https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-${SONAR_SCANNER_VERSION}-linux-x64.zip" output
|
||||
grep -e "^sonar-scanner-sha-linux-x64=[0-9A-Fa-f]\+$" output
|
||||
grep "sonar-scanner-url-linux-aarch64=https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-${SONAR_SCANNER_VERSION}-linux-aarch64.zip" output
|
||||
grep -e "^sonar-scanner-sha-linux-aarch64=[0-9A-Fa-f]\+$" output
|
||||
18
.github/workflows/qa.yml
vendored
18
.github/workflows/qa.yml
vendored
|
|
@ -1,18 +0,0 @@
|
|||
name: QA
|
||||
|
||||
on: push
|
||||
|
||||
jobs:
|
||||
run_qa:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- run: ./test/run-qa.sh
|
||||
timeout-minutes: 5
|
||||
services:
|
||||
sonarqube:
|
||||
image: sonarqube:8.9-community
|
||||
ports:
|
||||
- 9000:9000
|
||||
25
.github/workflows/unit-tests.yml
vendored
Normal file
25
.github/workflows/unit-tests.yml
vendored
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
name: Unit tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: "20"
|
||||
cache: "npm"
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Run tests
|
||||
run: npm test
|
||||
32
.github/workflows/update-tags.yml
vendored
Normal file
32
.github/workflows/update-tags.yml
vendored
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
name: Update Tags
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- v*.*.*
|
||||
|
||||
jobs:
|
||||
generate:
|
||||
runs-on: github-ubuntu-latest-s
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Parse semver
|
||||
uses: madhead/semver-utils@36d1e0ed361bd7b4b77665de8093092eaeabe6ba # v4.3.0
|
||||
id: version
|
||||
with:
|
||||
version: ${{ github.ref_name }}
|
||||
|
||||
- name: Update tags
|
||||
run: |
|
||||
TAGS='v${{ steps.version.outputs.major }} v${{ steps.version.outputs.major }}.${{ steps.version.outputs.minor }}'
|
||||
|
||||
for t in $TAGS; do
|
||||
git tag -f "$t"
|
||||
git push origin ":$t" 2>/dev/null || true
|
||||
git push origin "$t"
|
||||
done
|
||||
83
.github/workflows/version_update.yml
vendored
Normal file
83
.github/workflows/version_update.yml
vendored
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
name: sonar-scanner version check
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '15 10 * * *'
|
||||
|
||||
jobs:
|
||||
check-version:
|
||||
name: Check for sonar-scanner version update
|
||||
runs-on: github-ubuntu-latest-s
|
||||
outputs:
|
||||
should_update: ${{ steps.version-check.outputs.should_update }}
|
||||
new-version: ${{ steps.latest-version.outputs.sonar-scanner-version }}
|
||||
steps:
|
||||
- run: sudo apt install -y jq
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
ref: master
|
||||
fetch-depth: 0
|
||||
|
||||
- name: "Fetch currently used sonar-scanner version"
|
||||
id: tagged-version
|
||||
shell: bash
|
||||
run: cat sonar-scanner-version >> $GITHUB_OUTPUT
|
||||
|
||||
- name: "Fetch latest sonar-scanner version"
|
||||
id: latest-version
|
||||
shell: bash
|
||||
run: |
|
||||
./scripts/fetch_latest_version.sh > sonar-scanner-version
|
||||
cat sonar-scanner-version >> $GITHUB_OUTPUT
|
||||
|
||||
- name: "Determine if update is needed"
|
||||
id: version-check
|
||||
shell: bash
|
||||
run: |
|
||||
if [[ "${{ steps.tagged-version.outputs.sonar-scanner-version }}" != "${{ steps.latest-version.outputs.sonar-scanner-version }}" ]]; then
|
||||
echo "should_update=true" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "should_update=false" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
update-version:
|
||||
name: Prepare pull request for sonar-scanner version update
|
||||
needs: check-version
|
||||
runs-on: github-ubuntu-latest-s
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
if: needs.check-version.outputs.should_update == 'true'
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
ref: master
|
||||
persist-credentials: true
|
||||
fetch-depth: 0
|
||||
- run: sudo snap install yq
|
||||
- name: "Update default version"
|
||||
shell: bash
|
||||
env:
|
||||
NEW_VERSION: ${{ needs.check-version.outputs.new-version }}
|
||||
run: |
|
||||
yq -i '.inputs.scannerVersion.default = strenv(NEW_VERSION)' action.yml
|
||||
./scripts/fetch_latest_version.sh > sonar-scanner-version
|
||||
- name: "Create Pull Request for version update"
|
||||
shell: bash
|
||||
env:
|
||||
UPDATE_BRANCH: update-to-sonar-scanner-${{ needs.check-version.outputs.new-version }}
|
||||
TITLE: "Update SonarScanner CLI to ${{ needs.check-version.outputs.new-version }}"
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
git config --global user.name "SonarTech"
|
||||
git config --global user.email "sonartech@sonarsource.com"
|
||||
git checkout -b ${UPDATE_BRANCH}
|
||||
git add sonar-scanner-version
|
||||
git add action.yml
|
||||
git commit -m "${TITLE}"
|
||||
git push --force-with-lease origin ${UPDATE_BRANCH}
|
||||
gh pr list
|
||||
|
||||
if [[ $(gh pr list -H "${UPDATE_BRANCH}" | grep "${UPDATE_BRANCH}" | wc -l) -eq 0 ]]; then
|
||||
gh pr create -B master -H ${UPDATE_BRANCH} --title "${TITLE}" --body "Automatic update of the sonar-scanner version value. Be sure to trigger the QA workflow by closing and reopening this PR (see https://github.com/orgs/community/discussions/65321)."
|
||||
fi
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -1,2 +1,5 @@
|
|||
.idea
|
||||
.DS_Store
|
||||
|
||||
# Node
|
||||
node_modules/
|
||||
|
|
|
|||
20
Dockerfile
20
Dockerfile
|
|
@ -1,20 +0,0 @@
|
|||
FROM sonarsource/sonar-scanner-cli:4.6
|
||||
|
||||
LABEL version="1.0.0" \
|
||||
repository="https://github.com/sonarsource/sonarqube-scan-action" \
|
||||
homepage="https://github.com/sonarsource/sonarqube-scan-action" \
|
||||
maintainer="SonarSource" \
|
||||
com.github.actions.name="SonarQube Scan" \
|
||||
com.github.actions.description="Scan your code with SonarQube to detect Bugs, Vulnerabilities and Code Smells in up to 27 programming languages!" \
|
||||
com.github.actions.icon="check" \
|
||||
com.github.actions.color="green"
|
||||
|
||||
# Set up local envs in order to allow for special chars (non-asci) in filenames.
|
||||
ENV LC_ALL="C.UTF-8"
|
||||
|
||||
# https://help.github.com/en/actions/creating-actions/dockerfile-support-for-github-actions#user
|
||||
USER root
|
||||
|
||||
COPY entrypoint.sh /entrypoint.sh
|
||||
RUN chmod +x /entrypoint.sh
|
||||
ENTRYPOINT ["/entrypoint.sh"]
|
||||
445
README.md
445
README.md
|
|
@ -1,38 +1,52 @@
|
|||
# Scan your code with SonarQube [](https://github.com/SonarSource/sonarqube-scan-action/actions/workflows/qa.yml)
|
||||
# Scan your code with SonarQube [](https://github.com/SonarSource/sonarqube-scan-action/actions/workflows/qa-main.yml) [](https://github.com/SonarSource/sonarqube-scan-action/actions/workflows/qa-install-build-wrapper.yml) [](https://github.com/SonarSource/sonarqube-scan-action/actions/workflows/qa-scripts.yml) [](https://github.com/SonarSource/sonarqube-scan-action/actions/workflows/qa-deprecated-c-cpp.yml)
|
||||
|
||||
Using this GitHub Action, scan your code with [SonarQube](https://www.sonarqube.org/) to detects Bugs, Vulnerabilities and Code Smells in up to 27 programming languages!
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="./images/SQ_Logo_Server_Cloud_Dark_Backgrounds.png">
|
||||
<img alt="SonarQube Logo" src="./images/SQ_Logo_Server_Cloud_Light_Backgrounds.png">
|
||||
</picture>
|
||||
|
||||
<img src="./images/SonarQube-72px.png">
|
||||
|
||||
SonarQube is the leading product for Continuous Code Quality & Code Security. It supports most popular programming languages, including Java, JavaScript, TypeScript, C#, Python, C, C++, and many more.
|
||||
## A GitHub Action for SonarQube
|
||||
This GitHub Action integrates continuous code quality and security analysis directly into your workflow. It scans your project with either [SonarQube Server](https://www.sonarsource.com/products/sonarqube/) or [SonarQube Cloud](https://www.sonarsource.com/products/sonarcloud/), helping you catch bugs, security vulnerabilities, and code smells automatically within your CI/CD pipeline. **This action is the official method for scanning C, C++, Objective-C, and Dart projects via GitHub Actions.**
|
||||
|
||||
## Requirements
|
||||
|
||||
To run an analysis on your code, you first need to set up your project on SonarQube. Your SonarQube instance must be accessible from GitHub, and you will need an access token to run the analysis (more information below under **Environment variables**).
|
||||
### What is SonarQube?
|
||||
[SonarQube Server](https://www.sonarsource.com/products/sonarqube/) and [SonarQube Cloud](https://www.sonarsource.com/products/sonarcloud/) are widely used static analysis solutions for continuous code quality, security inspection, and fix remediation.
|
||||
The platform supports over in 30+ languages, frameworks, and IaC platforms, including Java, JavaScript, TypeScript, C#, Python, C, C++, and [many more](https://www.sonarsource.com/knowledge/languages/).
|
||||
|
||||
Read more information on how to analyze your code [here](https://docs.sonarqube.org/latest/analysis/github-integration/).
|
||||
## Quick Start
|
||||
|
||||
## Usage
|
||||
### 1. Prerequisites:
|
||||
|
||||
Project metadata, including the location to the sources to be analyzed, must be declared in the file `sonar-project.properties` in the base directory:
|
||||
You must have a project already set up on SonarQube Cloud or SonarQube Server. This action performs the analysis, but the project must exist on the platform to receive the results.
|
||||
|
||||
```properties
|
||||
sonar.projectKey=<replace with the key generated when setting up the project on SonarQube>
|
||||
For more information, see [Key Requirements](#key-requirements).
|
||||
|
||||
# relative paths to source directories. More details and properties are described
|
||||
# in https://docs.sonarqube.org/latest/project-administration/narrowing-the-focus/
|
||||
sonar.sources=.
|
||||
```
|
||||
|
||||
The workflow YAML file will usually look something like this:
|
||||
### 2. Required variables:
|
||||
|
||||
The action needs two key variables to connect to the SonarQube instance and run the analysis. These should be stored as GitHub secrets or variables for security.
|
||||
|
||||
• `SONAR_TOKEN` : The authentication token required to access the SonarQube instance. This is a mandatory secret for all use cases.
|
||||
|
||||
• `SONAR_HOST_URL` : The URL of the SonarQube Server. This is required for self-hosted SonarQube Server but not needed for SonarQube Cloud.
|
||||
|
||||
For more information, see [Configuration](#configuration).
|
||||
|
||||
### 3. Quick Start Workflow Example (for SonarQube Cloud)
|
||||
|
||||
Create or update your CI pipeline to run the scan action:
|
||||
|
||||
|
||||
```yaml
|
||||
on:
|
||||
# Trigger analysis when pushing in master or pull requests, and when creating
|
||||
# a pull request.
|
||||
# Trigger analysis when pushing to your main branches, and when creating a pull request.
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- master
|
||||
- develop
|
||||
- 'releases/**'
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
|
||||
|
|
@ -41,61 +55,412 @@ jobs:
|
|||
sonarqube:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
# Disabling shallow clone is recommended for improving relevancy of reporting
|
||||
# Disabling shallow clones is recommended for improving the relevancy of reporting
|
||||
fetch-depth: 0
|
||||
- name: SonarQube Scan
|
||||
uses: sonarsource/sonarqube-scan-action@master
|
||||
uses: SonarSource/sonarqube-scan-action@<action version or sha1> # Ex: v4.1.0 or sha1, See the latest version at https://github.com/marketplace/actions/official-sonarqube-scan
|
||||
env:
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
|
||||
```
|
||||
|
||||
Create a configuration file in the root directory of the project and name it `sonar-project.properties`:
|
||||
|
||||
|
||||
```properties
|
||||
sonar.organization=<replace with your SonarQube Cloud organization key>
|
||||
sonar.projectKey=<replace with the key generated when setting up the project on SonarQube Cloud>
|
||||
|
||||
# relative paths to source directories. More details and properties are described
|
||||
# at https://docs.sonarsource.com/sonarqube-cloud/advanced-setup/analysis-scope/
|
||||
sonar.sources=src
|
||||
```
|
||||
|
||||
For other workflows, see [Workflow Examples](#workflow-examples).
|
||||
|
||||
|
||||
|
||||
## Important: Special Cases and alternatives
|
||||
|
||||
This GitHub Action will not work for all technologies. If you are in one of the following situations, you should use the following alternatives:
|
||||
|
||||
* **Your code is built with Maven**. Read the documentation about our SonarScanner for Maven in SonarQube [Server](https://docs.sonarsource.com/sonarqube-server/latest/analyzing-source-code/scanners/sonarscanner-for-maven/) and [Cloud](https://docs.sonarsource.com/sonarqube-cloud/advanced-setup/ci-based-analysis/sonarscanner-for-maven/).
|
||||
* **Your code is built with Gradle**. Read the documentation about our SonarScanner for Gradle in SonarQube [Server](https://docs.sonarsource.com/sonarqube-server/latest/analyzing-source-code/scanners/sonarscanner-for-gradle/) and [Cloud](https://docs.sonarsource.com/sonarqube-cloud/advanced-setup/ci-based-analysis/sonarscanner-for-gradle/).
|
||||
* **You want to analyze a .NET solution**. Read the documentation about our SonarScanner for .NET in SonarQube [Server](https://docs.sonarsource.com/sonarqube-server/latest/analyzing-source-code/scanners/dotnet/introduction/) and [Cloud](https://docs.sonarsource.com/sonarqube-cloud/advanced-setup/ci-based-analysis/sonarscanner-for-dotnet/introduction/).
|
||||
|
||||
**Do not use this GitHub action if:**
|
||||
|
||||
* You want to run the action on C, C++, or Objective-C projects on a 32-bits system - build wrappers support only 64-bits OS.
|
||||
|
||||
**If you want to use Software Composition Analysis (SCA)**
|
||||
|
||||
Dependency scanning with SonarQube Advanced Security SCA may not work correctly if scanning requires on-the-fly manifest file generation. See the SCA analysis environment requirement documentation for [Cloud](https://docs.sonarsource.com/sonarqube-cloud/advanced-security/analyzing-projects-for-dependencies-sca#appropriate-environment) or [Server](https://docs.sonarsource.com/sonarqube-server/advanced-security/analyzing-projects-for-dependencies#appropriate-environment).
|
||||
|
||||
## Key requirements
|
||||
|
||||
To use this GitHub Action you need to meet the following prerequisites for your choosen SonarQube platform.
|
||||
|
||||
### For SonarQube Cloud
|
||||
|
||||
* Create your account on SonarQube Cloud. [Sign up for free](https://www.sonarsource.com/products/sonarcloud/signup/?utm_medium=referral&utm_source=github&utm_campaign=sc-signup&utm_content=signup-sonarcloud-listing-x-x&utm_term=ww-psp-x) now if it's not already the case!
|
||||
* [Set up a repository to be analyzed](https://sonarcloud.io/projects/create) in just one click.
|
||||
|
||||
### For SonarQube Server
|
||||
|
||||
* Your SonarQube Server instance must be accessible from GitHub, and you will need an access token to run the analysis (more information below under **Environment variables**).
|
||||
* To run an analysis on your code, you first need to set up your project on SonarQube Server.
|
||||
|
||||
Read more information on how to analyze your code [here](https://docs.sonarsource.com/sonarqube-server/latest/devops-platform-integration/github-integration/introduction/).
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Configuration
|
||||
|
||||
### Action parameters
|
||||
|
||||
#### `projectBaseDir`
|
||||
|
||||
You can change the analysis base directory by using the optional input `projectBaseDir` like this:
|
||||
|
||||
```yaml
|
||||
- name: SonarQube Scan
|
||||
uses: sonarsource/sonarqube-scan-action@master
|
||||
- uses: SonarSource/sonarqube-scan-action@<action version or sha1>
|
||||
with:
|
||||
projectBaseDir: app/src
|
||||
```
|
||||
|
||||
#### `scannerVersion`
|
||||
|
||||
In case you need to specify the version of the Sonar Scanner, you can use the `scannerVersion` option:
|
||||
|
||||
```yaml
|
||||
- uses: SonarSource/sonarqube-scan-action@<action version or sha1>
|
||||
with:
|
||||
scannerVersion: 6.2.0.4584
|
||||
```
|
||||
|
||||
#### `args`
|
||||
|
||||
In case you need to add additional analysis parameters, and you do not wish to set them in the `sonar-project.properties` file, you can use the `args` option:
|
||||
|
||||
```yaml
|
||||
- name: SonarQube Scan
|
||||
uses: sonarsource/sonarqube-scan-action@master
|
||||
- uses: SonarSource/sonarqube-scan-action@<action version>
|
||||
with:
|
||||
projectBaseDir: app/src
|
||||
args: >
|
||||
-Dsonar.organization=my-organization # For SonarQube Cloud only
|
||||
"-Dsonar.projectName=My Project"
|
||||
-Dsonar.projectKey=my-projectkey
|
||||
-Dsonar.python.coverage.reportPaths=coverage.xml
|
||||
-Dsonar.sources=lib/
|
||||
-Dsonar.tests=tests/
|
||||
-Dsonar.test.exclusions=tests/**
|
||||
-Dsonar.verbose=true
|
||||
```
|
||||
|
||||
More information about possible analysis parameters can be found in [the documentation](https://redirect.sonarsource.com/doc/analysis-parameters.html).
|
||||
> [!NOTE]
|
||||
> In version 6, the way the `args` option is handled has been changed to prevent command injection.
|
||||
> As a result, we no longer support the full bash syntax.
|
||||
> This means there is now a much more restricted use of quoting and escaping compared to older versions of the action.
|
||||
> Example:
|
||||
> ```yaml
|
||||
> with:
|
||||
> args: >
|
||||
> -testing test
|
||||
> -valid=true
|
||||
> --quotes "test quotes" "nested \'quotes\'"
|
||||
> -Dsonar.property="some value"
|
||||
> "-Dsonar.property=some value"
|
||||
> ```
|
||||
> will be parsed as the following array of strings:
|
||||
> ```
|
||||
> [
|
||||
> '-testing',
|
||||
> 'test',
|
||||
> '-valid=true',
|
||||
> '--quotes',
|
||||
> 'test quotes', # Surrounding quotes are removed
|
||||
> 'nested \'quotes\'',
|
||||
> '-Dsonar.property="some value"', # Internal quotes are NOT removed, contrary to the bash syntax
|
||||
> '-Dsonar.property=some value', # This is the proper way to pass scanner arguments with spaces
|
||||
> ]
|
||||
> ```
|
||||
|
||||
#### `scannerBinariesUrl`
|
||||
|
||||
You can also specify the URL where to retrieve the SonarScanner CLI from.
|
||||
The specified URL overrides the default address: `https://binaries.sonarsource.com/Distribution/sonar-scanner-cli`.
|
||||
This can be useful when the runner executing the action is self-hosted and has regulated or no access to the Internet:
|
||||
|
||||
```yaml
|
||||
- uses: SonarSource/sonarqube-scan-action@<action version>
|
||||
with:
|
||||
scannerBinariesUrl: https://my.custom.binaries.url.com/Distribution/sonar-scanner-cli/
|
||||
```
|
||||
|
||||
More information about possible analysis parameters can be found:
|
||||
* in the [Analysis parameters page](https://docs.sonarsource.com/sonarqube-server/latest/analyzing-source-code/analysis-parameters/) of the SonarQube Server documentation
|
||||
* in the [Analysis parameters page](https://docs.sonarsource.com/sonarqube-cloud/advanced-setup/analysis-parameters/) of the SonarQube Cloud documentation
|
||||
|
||||
|
||||
### Environment variables
|
||||
|
||||
- `SONAR_TOKEN` – **Required** this is the token used to authenticate access to SonarQube. You can read more about security tokens [here](https://docs.sonarqube.org/latest/user-guide/user-token/). You can set the `SONAR_TOKEN` environment variable in the "Secrets" settings page of your repository, or you can add them at the level of your GitHub organization (recommended).
|
||||
- `SONAR_HOST_URL` – **Required** this tells the scanner where SonarQube is hosted. You can set the `SONAR_HOST_URL` environment variable in the "Secrets" settings page of your repository, or you can add them at the level of your GitHub organization (recommended).
|
||||
- `SONAR_TOKEN` – **Required** this is the token used to authenticate access to SonarQube. You can read more about security tokens in the documentation of SonarQube [Server](https://docs.sonarsource.com/sonarqube-server/latest/user-guide/managing-tokens/) and [Cloud](https://docs.sonarsource.com/sonarqube-cloud/managing-your-account/managing-tokens/). You can set the `SONAR_TOKEN` environment variable in the "Secrets" settings page of your repository, or you can add them at the level of your GitHub organization (recommended).
|
||||
- `SONAR_HOST_URL` – this tells the scanner where SonarQube Server is hosted. You can set the `SONAR_HOST_URL` environment variable in the "Variables" settings page of your repository, or you can add them at the level of your GitHub organization (recommended). Not needed for SonarQube Cloud.
|
||||
- `SONAR_ROOT_CERT` – Holds an additional certificate (in PEM format) that is used to validate the certificate of SonarQube Server or of a secured proxy to SonarQube (Server or Cloud). You can set the `SONAR_ROOT_CERT` environment variable in the "Secrets" settings page of your repository, or you can add them at the level of your GitHub organization (recommended).
|
||||
|
||||
## Alternatives for Java, .NET, and C/C++ projects
|
||||
Here is an example of how you can pass a certificate (in PEM format) to the Scanner truststore:
|
||||
|
||||
This GitHub Action will not work for all technologies. If you are in one of the following situations, you should use the following alternatives:
|
||||
```yaml
|
||||
- uses: SonarSource/sonarqube-scan-action@<action version>
|
||||
env:
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
SONAR_HOST_URL: ${{ vars.SONAR_HOST_URL }}
|
||||
SONAR_ROOT_CERT: ${{ secrets.SONAR_ROOT_CERT }}
|
||||
```
|
||||
|
||||
* Your code is built with Maven. Read the documentation about our [Scanner for Maven](https://redirect.sonarsource.com/doc/install-configure-scanner-maven.html).
|
||||
* Your code is built with Gradle. Read the documentation about our [Scanner for Gradle](https://redirect.sonarsource.com/doc/gradle.html).
|
||||
* You want to analyze a .NET solution. Read the documentation about our [Scanner for .NET](https://redirect.sonarsource.com/doc/install-configure-scanner-msbuild.html).
|
||||
* You want to analyze C/C++ code. Read the documentation on [analyzing C/C++ code](https://docs.sonarqube.org/latest/analysis/languages/cfamily/).
|
||||
If your source code file names contain special characters that are not covered by the locale range of `en_US.UTF-8`, you can configure your desired locale like this:
|
||||
|
||||
## Have question or feedback?
|
||||
```yaml
|
||||
- uses: SonarSource/sonarqube-scan-action@<action version>
|
||||
env:
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
SONAR_HOST_URL: ${{ vars.SONAR_HOST_URL }} # or https://sonarcloud.io
|
||||
LC_ALL: "ru_RU.UTF-8"
|
||||
```
|
||||
|
||||
To provide feedback (requesting a feature or reporting a bug) please post on the [SonarSource Community Forum](https://community.sonarsource.com/tags/c/help/sq/github-actions).
|
||||
## Workflow Examples
|
||||
|
||||
## License
|
||||
|
||||
The Dockerfile and associated scripts and documentation in this project are released under the LGPLv3 License.
|
||||
### For SonarQube Cloud
|
||||
|
||||
Container images built with this project include third party materials.
|
||||
Project metadata, including the location of the sources to be analyzed, must be declared in the file sonar-project.properties in the base directory:
|
||||
|
||||
```properties
|
||||
sonar.organization=<replace with your SonarQube Cloud organization key>
|
||||
sonar.projectKey=<replace with the key generated when setting up the project on SonarQube Cloud>
|
||||
|
||||
# relative paths to source directories. More details and properties are described
|
||||
# at https://docs.sonarsource.com/sonarqube-cloud/advanced-setup/analysis-scope/
|
||||
sonar.sources=src
|
||||
```
|
||||
|
||||
|
||||
#### Standard Projects
|
||||
|
||||
For projects that:
|
||||
- do not contain C, C++, or Objective-C, and
|
||||
- for C, C++, Objective-C projects that don't use [Build Wrapper](https://docs.sonarsource.com/sonarqube-cloud/advanced-setup/languages/c-family/prerequisites/#using-build-wrapper)
|
||||
|
||||
the workflow, usually declared under `.github/workflows/build.yml`, looks like the following:
|
||||
|
||||
```yaml
|
||||
on:
|
||||
# Trigger analysis when pushing to your main branches, and when creating a pull request.
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- master
|
||||
- develop
|
||||
- 'releases/**'
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
|
||||
name: Main Workflow
|
||||
jobs:
|
||||
sonarqube:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
# Disabling shallow clones is recommended for improving the relevancy of reporting
|
||||
fetch-depth: 0
|
||||
- name: SonarQube Scan
|
||||
uses: SonarSource/sonarqube-scan-action@<action version or sha1> # Ex: v4.1.0 or sha1, See the latest version at https://github.com/marketplace/actions/official-sonarqube-scan
|
||||
env:
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
```
|
||||
|
||||
#### C/C++/Objective-C with Build Wrapper
|
||||
|
||||
For C, C++, and Objective-C projects relying on [Build Wrapper](https://docs.sonarsource.com/sonarqube-cloud/advanced-setup/languages/c-family/prerequisites/#using-build-wrapper) to generate the compilation database, the workflow requires additional steps to download the Build Wrapper and invoke it:
|
||||
|
||||
```yaml
|
||||
# Trigger analysis when pushing to your main branches, and when creating a pull request.
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- master
|
||||
- develop
|
||||
- 'releases/**'
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
|
||||
name: Main Workflow
|
||||
jobs:
|
||||
sonarqube:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
# Disabling shallow clone is recommended for improving relevancy of reporting
|
||||
fetch-depth: 0
|
||||
- name: Install Build Wrapper
|
||||
uses: SonarSource/sonarqube-scan-action/install-build-wrapper@<action version>
|
||||
- name: Run Build Wrapper
|
||||
run: |
|
||||
# Here goes your compilation wrapped with Build Wrapper
|
||||
# For more information, see https://docs.sonarsource.com/sonarqube-cloud/advanced-setup/languages/c-family/prerequisites/#using-build-wrapper
|
||||
# build-preparation steps
|
||||
# build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} build-command
|
||||
- name: SonarQube Scan
|
||||
uses: SonarSource/sonarqube-scan-action@<action version or sha1>
|
||||
env:
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
SONAR_ROOT_CERT: ${{ secrets.SONAR_ROOT_CERT }}
|
||||
with:
|
||||
# Consult https://docs.sonarsource.com/sonarqube-server/latest/analyzing-source-code/scanners/sonarscanner/ for more information and options
|
||||
args: >
|
||||
--define "sonar.cfamily.compile-commands=${{ env.BUILD_WRAPPER_OUT_DIR }}/compile_commands.json"
|
||||
```
|
||||
|
||||
See also [example configurations of C++ projects for SonarQube Cloud](https://github.com/search?q=org%3Asonarsource-cfamily-examples+gh-actions-sc&type=repositories).
|
||||
|
||||
### For SonarQube Server
|
||||
|
||||
Project metadata, including the location of the sources to be analyzed, can be declared in the file `sonar-project.properties` in the base directory:
|
||||
|
||||
```properties
|
||||
sonar.projectKey=<replace with the key generated when setting up the project on SonarQube Server>
|
||||
|
||||
# relative paths to source directories. More details and properties are described
|
||||
# at https://docs.sonarsource.com/sonarqube-server/latest/project-administration/analysis-scope/
|
||||
sonar.sources=src
|
||||
```
|
||||
|
||||
#### Standard Projects
|
||||
|
||||
For projects that:
|
||||
- do not contain C, C++, or Objective-C, and
|
||||
- for C, C++, Objective-C projects that don't use [Build Wrapper](https://docs.sonarsource.com/sonarqube-server/latest/analyzing-source-code/languages/c-family/prerequisites/#using-buildwrapper)
|
||||
the workflow, usually declared under `.github/workflows/build.yml`, looks like the following:
|
||||
|
||||
```yaml
|
||||
on:
|
||||
# Trigger analysis when pushing to your main branches, and when creating a pull request.
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- master
|
||||
- develop
|
||||
- 'releases/**'
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
|
||||
name: Main Workflow
|
||||
jobs:
|
||||
sonarqube:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
# Disabling shallow clones is recommended for improving the relevancy of reporting
|
||||
fetch-depth: 0
|
||||
- name: SonarQube Scan
|
||||
uses: SonarSource/sonarqube-scan-action@<action version or sha1> # Ex: v4.1.0, or sha1, See the latest version at https://github.com/marketplace/actions/official-sonarqube-scan
|
||||
env:
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
SONAR_HOST_URL: ${{ vars.SONAR_HOST_URL }}
|
||||
```
|
||||
|
||||
#### C/C++/Objective-C with Build Wrapper
|
||||
|
||||
|
||||
|
||||
This subsection would contain the more complex YAML configuration for projects that require the
|
||||
build wrapper to generate a compilation database. The example would detail the three-step
|
||||
process: checking out the code, installing the build wrapper, and then running the SonarQube
|
||||
scan with the appropriate parameters.
|
||||
|
||||
For C, C++, and Objective-C projects relying on [Build Wrapper](https://docs.sonarsource.com/sonarqube-server/latest/analyzing-source-code/languages/c-family/prerequisites/#using-buildwrapper) to generate the compilation database, the workflow requires additional steps to download the Build Wrapper and invoke it:
|
||||
|
||||
```yaml
|
||||
# Trigger analysis when pushing to your main branches, and when creating a pull request.
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- master
|
||||
- develop
|
||||
- 'releases/**'
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
|
||||
name: Main Workflow
|
||||
jobs:
|
||||
sonarqube:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
# Disabling shallow clone is recommended for improving relevancy of reporting
|
||||
fetch-depth: 0
|
||||
- name: Install Build Wrapper
|
||||
uses: SonarSource/sonarqube-scan-action/install-build-wrapper@<action version>
|
||||
env:
|
||||
SONAR_HOST_URL: ${{ vars.SONAR_HOST_URL }}
|
||||
- name: Run Build Wrapper
|
||||
run: |
|
||||
# Here goes your compilation wrapped with Build Wrapper
|
||||
# For more information, see https://docs.sonarsource.com/sonarqube-server/latest/analyzing-source-code/languages/c-family/prerequisites/#using-buildwrapper
|
||||
# build-preparation steps
|
||||
# build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} build-command
|
||||
- name: SonarQube Scan
|
||||
uses: SonarSource/sonarqube-scan-action@<action version or sha1>
|
||||
env:
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
SONAR_HOST_URL: ${{ vars.SONAR_HOST_URL }}
|
||||
SONAR_ROOT_CERT: ${{ secrets.SONAR_ROOT_CERT }}
|
||||
with:
|
||||
# Consult https://docs.sonarsource.com/sonarqube-server/latest/analyzing-source-code/scanners/sonarscanner/ for more information and options
|
||||
args: >
|
||||
--define sonar.cfamily.compile-commands="${{ env.BUILD_WRAPPER_OUT_DIR }}/compile_commands.json"
|
||||
```
|
||||
|
||||
If you are using SonarQube Server 10.5 or earlier, use `sonar.cfamily.build-wrapper-output` instead of `sonar.cfamily.compile-commands` in the `args` property of the last step, as Build Wrapper does not generate a `compile_commands.json` file before SonarQube Server 10.6.
|
||||
|
||||
It should look like this:
|
||||
|
||||
```yaml
|
||||
with:
|
||||
args: >
|
||||
--define "sonar.cfamily.build-wrapper-output=${{ env.BUILD_WRAPPER_OUT_DIR }}"
|
||||
```
|
||||
|
||||
See also [example configurations of C++ projects for SonarQube Server](https://github.com/search?q=org%3Asonarsource-cfamily-examples+gh-actions-sq&type=repositories).
|
||||
|
||||
## Advanced Settings
|
||||
|
||||
### Self-hosted runner or container
|
||||
|
||||
When running the action in a self-hosted runner or container, please ensure that the following programs are installed:
|
||||
|
||||
* **curl** or **wget**
|
||||
* **unzip**
|
||||
|
||||
### Additional information
|
||||
|
||||
The `sonarqube-scan-action/install-build-wrapper` action installs `coreutils` if run on macOS.
|
||||
|
||||
## Support & Community
|
||||
|
||||
To provide feedback (requesting a feature or reporting a bug) please post on the SonarSource Community Forum page for [SonarQube Server](https://community.sonarsource.com/tags/c/help/sq/github-actions) or [SonarQube Cloud](https://community.sonarsource.com/tags/c/help/sc/9/github-actions).
|
||||
|
||||
### License
|
||||
|
||||
Container images built with this project include third-party materials.
|
||||
|
|
|
|||
13
SECURITY.md
Normal file
13
SECURITY.md
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# Reporting Security Issues
|
||||
|
||||
A mature software vulnerability treatment process is a cornerstone of a robust information security management system. Contributions from the community play an important role in the evolution and security of our products, and in safeguarding the security and privacy of our users.
|
||||
|
||||
If you believe you have discovered a security vulnerability in Sonar's products, we encourage you to report it immediately.
|
||||
|
||||
To responsibly report a security issue, please email us at [security@sonarsource.com](mailto:security@sonarsource.com). Sonar’s security team will acknowledge your report, guide you through the next steps, or request additional information if necessary. Customers with a support contract can also report the vulnerability directly through the support channel.
|
||||
|
||||
For security vulnerabilities found in third-party libraries, please also contact the library's owner or maintainer directly.
|
||||
|
||||
## Responsible Disclosure Policy
|
||||
|
||||
For more information about disclosing a security vulnerability to Sonar, please refer to our community post: [Responsible Vulnerability Disclosure](https://community.sonarsource.com/t/responsible-vulnerability-disclosure/9317).
|
||||
24
action.yml
24
action.yml
|
|
@ -1,17 +1,29 @@
|
|||
name: Official SonarQube Scan
|
||||
# Warning: changing name would change URL in the marketplace
|
||||
description: >
|
||||
Scan your code with SonarQube to detect Bugs, Vulnerabilities and Code Smells in up to 27 programming languages!
|
||||
Scan your code with SonarQube Server and Cloud to detect issues in 30+ languages. (Formerly SonarQube and SonarCloud)
|
||||
|
||||
branding:
|
||||
icon: check
|
||||
color: green
|
||||
runs:
|
||||
using: docker
|
||||
image: Dockerfile
|
||||
inputs:
|
||||
args:
|
||||
description: Additional arguments to the sonar-scanner
|
||||
description: Additional arguments to the Sonar Scanner CLI
|
||||
required: false
|
||||
default: ""
|
||||
projectBaseDir:
|
||||
description: Set the sonar.projectBaseDir analysis property
|
||||
required: false
|
||||
default: .
|
||||
default: "."
|
||||
scannerVersion:
|
||||
description: Version of the Sonar Scanner CLI to use
|
||||
required: false
|
||||
# to be kept in sync with sonar-scanner-version
|
||||
default: 8.0.1.6346
|
||||
scannerBinariesUrl:
|
||||
description: URL to download the Sonar Scanner CLI binaries from
|
||||
required: false
|
||||
default: https://binaries.sonarsource.com/Distribution/sonar-scanner-cli
|
||||
runs:
|
||||
using: node20
|
||||
main: dist/index.js
|
||||
|
|
|
|||
58
contributing.md
Normal file
58
contributing.md
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
# SonarQube Scan Action
|
||||
|
||||
## Contributing
|
||||
|
||||
If you would like to see a new feature, please create a new thread in the forum ["Suggest new features"](https://community.sonarsource.com/c/suggestions/features).
|
||||
|
||||
Please be aware that we are not actively looking for feature contributions. The truth is that it's extremely difficult for someone outside SonarSource to comply with our roadmap and expectations. Therefore, we typically only accept minor cosmetic changes and typo fixes.
|
||||
|
||||
### Submitting a pull request
|
||||
|
||||
With that in mind, if you would like to submit a code contribution, please create a pull request for this repository. Please explain your motives to contribute this change: what problem you are trying to fix, what improvement you are trying to make.
|
||||
|
||||
Make sure that you follow our [code style](https://github.com/SonarSource/sonar-developer-toolset#code-style) and all tests are passing (Travis build is executed for each pull request).
|
||||
|
||||
### Next steps
|
||||
|
||||
One of the members of our team will carefully review your pull request. You might be asked at this point for clarifications or your pull request might be rejected if we decide that it doesn't fit our roadmap and vision for the product.
|
||||
If your contribution looks promising then either we will decide:
|
||||
|
||||
- it is good to go and merge your pull request to the master branch
|
||||
|
||||
or
|
||||
|
||||
- that we need to think over your change and modify it to adhere to our roadmap and internal standards. We will close your pull request at this point, but we might come back to your changes later in the future when we decide it is the right time to work on it.
|
||||
|
||||
Thank You!
|
||||
The SonarSource Team
|
||||
|
||||
## Development
|
||||
|
||||
Both the main action and the secondary _install-build-wrapper_ action are [Javascript actions](https://docs.github.com/en/actions/tutorials/create-actions/create-a-javascript-action). They need to be packaged to work properly. We follow the official guidelines and rely on rollup for that.
|
||||
|
||||
### Requirements
|
||||
|
||||
Make sure you have node 20 & npm installed. We recommend using [nvm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm#using-a-node-version-manager-to-install-nodejs-and-npm) for that.
|
||||
|
||||
### Building & testing
|
||||
|
||||
You'll first need to install dependencies:
|
||||
|
||||
```sh
|
||||
npm install
|
||||
```
|
||||
|
||||
To use rollup to bundle the scripts, run the `build` command:
|
||||
|
||||
```sh
|
||||
npm run build
|
||||
```
|
||||
|
||||
> ⚠️ Since the action uses the code in the repository, it is necessary to commit the bundled code! ⚠️
|
||||
|
||||
|
||||
To run the js unit tests, run the `test` command:
|
||||
|
||||
```sh
|
||||
npm run test
|
||||
```
|
||||
134
deprecated-c-cpp/action.yml
Normal file
134
deprecated-c-cpp/action.yml
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
name: 'SonarQube Scan for C and C++'
|
||||
description: 'Scan your C and C++ code with SonarQube to detect bugs, vulnerabilities and code smells.'
|
||||
branding:
|
||||
icon: check
|
||||
color: green
|
||||
inputs:
|
||||
installation-path:
|
||||
description: 'Directory where the sonar-scanner and build wrapper will be installed. Created if does not exists.'
|
||||
required: false
|
||||
default: '.sonar'
|
||||
cache-binaries:
|
||||
description: 'Controls if installed binaries are cached using GitHub cache.'
|
||||
required: false
|
||||
default: 'true'
|
||||
|
||||
outputs:
|
||||
sonar-scanner-binary:
|
||||
description: "Absolute path to sonar-scanner binary."
|
||||
value: ${{ steps.setup-outputs.outputs.sonar-scanner-binary }}
|
||||
build-wrapper-binary:
|
||||
description: "Absolute path to build-wrapper binary."
|
||||
value: ${{ steps.setup-outputs.outputs.build-wrapper-binary }}
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
# install packaged required for greadlink and sha256sum command on macOS
|
||||
- name: Install required packages for macOS
|
||||
if: runner.os == 'macOS'
|
||||
shell: bash
|
||||
run: brew install coreutils
|
||||
|
||||
- name: Set SONAR_HOST_URL to 'https://sonarcloud.io'
|
||||
if: env.SONAR_HOST_URL == ''
|
||||
shell: bash
|
||||
run: |
|
||||
echo "Setting SONAR_HOST_URL to 'https://sonarcloud.io'"
|
||||
echo "SONAR_HOST_URL=https://sonarcloud.io" >> $GITHUB_ENV
|
||||
|
||||
- name: Verify and create installation path
|
||||
shell: bash
|
||||
env:
|
||||
INSTALL_PATH: ${{ inputs.installation-path }}
|
||||
run: ${GITHUB_ACTION_PATH}/../scripts/create_install_path.sh
|
||||
|
||||
- name: Set version of sonar-scanner
|
||||
id: sonar-scanner-version
|
||||
shell: bash
|
||||
run: cat ${GITHUB_ACTION_PATH}/../sonar-scanner-version >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Configure paths
|
||||
id: configure_paths
|
||||
shell: bash
|
||||
env:
|
||||
OS: ${{ runner.os }}
|
||||
ARCH: ${{ runner.arch }}
|
||||
INSTALL_PATH: ${{ inputs.installation-path }}
|
||||
SONAR_SCANNER_VERSION: ${{ steps.sonar-scanner-version.outputs.sonar-scanner-version }}
|
||||
SONAR_SCANNER_URL_WINDOWS_X64: ${{ steps.sonar-scanner-version.outputs.sonar-scanner-url-windows-x64 }}
|
||||
SONAR_SCANNER_SHA_WINDOWS_X64: ${{ steps.sonar-scanner-version.outputs.sonar-scanner-sha-windows-x64 }}
|
||||
SONAR_SCANNER_URL_LINUX_X64: ${{ steps.sonar-scanner-version.outputs.sonar-scanner-url-linux-x64 }}
|
||||
SONAR_SCANNER_SHA_LINUX_X64: ${{ steps.sonar-scanner-version.outputs.sonar-scanner-sha-linux-x64 }}
|
||||
SONAR_SCANNER_URL_LINUX_AARCH64: ${{ steps.sonar-scanner-version.outputs.sonar-scanner-url-linux-aarch64 }}
|
||||
SONAR_SCANNER_SHA_LINUX_AARCH64: ${{ steps.sonar-scanner-version.outputs.sonar-scanner-sha-linux-aarch64 }}
|
||||
SONAR_SCANNER_URL_MACOSX_X64: ${{ steps.sonar-scanner-version.outputs.sonar-scanner-url-macosx-x64 }}
|
||||
SONAR_SCANNER_SHA_MACOSX_X64: ${{ steps.sonar-scanner-version.outputs.sonar-scanner-sha-macosx-x64 }}
|
||||
SONAR_SCANNER_URL_MACOSX_AARCH64: ${{ steps.sonar-scanner-version.outputs.sonar-scanner-url-macosx-aarch64 }}
|
||||
SONAR_SCANNER_SHA_MACOSX_AARCH64: ${{ steps.sonar-scanner-version.outputs.sonar-scanner-sha-macosx-aarch64 }}
|
||||
run: ${GITHUB_ACTION_PATH}/../scripts/configure_paths.sh >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Cache sonar-scanner installation
|
||||
id: cache-sonar-tools
|
||||
if: inputs.cache-binaries == 'true'
|
||||
uses: actions/cache@v4
|
||||
env:
|
||||
# The default value is 60mins. Reaching timeout is treated the same as a cache miss.
|
||||
SEGMENT_DOWNLOAD_TIMEOUT_MINS: 1
|
||||
with:
|
||||
key: sonar-scanner-${{ runner.os }}-${{ runner.arch }}-${{ steps.sonar-scanner-version.outputs.sonar-scanner-version }}
|
||||
path: ${{ steps.configure_paths.outputs.sonar-scanner-dir }}
|
||||
|
||||
- name: Download and install sonar-scanner
|
||||
if: steps.cache-sonar-tools.outputs.cache-hit != 'true'
|
||||
shell: bash
|
||||
env:
|
||||
DOWNLOAD_URL: ${{ steps.configure_paths.outputs.sonar-scanner-url }}
|
||||
EXPECTED_SHA: ${{ steps.configure_paths.outputs.sonar-scanner-sha }}
|
||||
INSTALL_PATH: ${{ inputs.installation-path }}
|
||||
TMP_ZIP_PATH: ${{ runner.temp }}/sonar-scanner.zip
|
||||
run: ${GITHUB_ACTION_PATH}/../scripts/download.sh -v
|
||||
|
||||
- name: Add the custom root certificate to java certificate store
|
||||
shell: bash
|
||||
run: ${GITHUB_ACTION_PATH}/../scripts/cert.sh
|
||||
|
||||
- name: Download and install build-wrapper
|
||||
shell: bash
|
||||
env:
|
||||
DOWNLOAD_URL: ${{ steps.configure_paths.outputs.build-wrapper-url }}
|
||||
INSTALL_PATH: ${{ inputs.installation-path }}
|
||||
TMP_ZIP_PATH: ${{ runner.temp }}/build-wrapper.zip
|
||||
run: ${GITHUB_ACTION_PATH}/../scripts/download.sh
|
||||
|
||||
- name: Setup action outputs
|
||||
id: setup-outputs
|
||||
shell: bash
|
||||
env:
|
||||
SONAR_SCANNER_DIR: ${{ steps.configure_paths.outputs.sonar-scanner-dir }}
|
||||
SONAR_SCANNER_BIN: ${{ steps.configure_paths.outputs.sonar-scanner-bin }}
|
||||
BUILD_WRAPPER_DIR: ${{ steps.configure_paths.outputs.build-wrapper-dir }}
|
||||
BUILD_WRAPPER_BIN: ${{ steps.configure_paths.outputs.build-wrapper-bin }}
|
||||
run: |
|
||||
source ${GITHUB_ACTION_PATH}/../scripts/utils.sh
|
||||
|
||||
echo "::group::Action outputs"
|
||||
echo "SONAR_HOST_URL=${SONAR_HOST_URL}" >> $GITHUB_ENV
|
||||
echo "'SONAR_HOST_URL' environment variable set to '${SONAR_HOST_URL}'"
|
||||
|
||||
SONAR_SCANNER_BIN_DIR=$(realpath "${SONAR_SCANNER_DIR}/bin")
|
||||
echo "${SONAR_SCANNER_BIN_DIR}" >> $GITHUB_PATH
|
||||
echo "'${SONAR_SCANNER_BIN_DIR}' added to the path"
|
||||
|
||||
SONAR_SCANNER_BIN=$(realpath "${SONAR_SCANNER_BIN}")
|
||||
echo "sonar-scanner-binary=${SONAR_SCANNER_BIN}" >> $GITHUB_OUTPUT
|
||||
echo "'sonar-scanner-binary' output set to '${SONAR_SCANNER_BIN}'"
|
||||
|
||||
BUILD_WRAPPER_BIN_DIR=$(realpath "${BUILD_WRAPPER_DIR}")
|
||||
echo "${BUILD_WRAPPER_BIN_DIR}" >> $GITHUB_PATH
|
||||
echo "'${BUILD_WRAPPER_BIN_DIR}' added to the path"
|
||||
|
||||
BUILD_WRAPPER_BIN=$(realpath "${BUILD_WRAPPER_BIN}")
|
||||
echo "build-wrapper-binary=${BUILD_WRAPPER_BIN}" >> $GITHUB_OUTPUT
|
||||
echo "'build-wrapper-binary' output set to '${BUILD_WRAPPER_BIN}'"
|
||||
echo "::endgroup::"
|
||||
27277
dist/exec-BTlTa8sL.js
vendored
Normal file
27277
dist/exec-BTlTa8sL.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/exec-BTlTa8sL.js.map
vendored
Normal file
1
dist/exec-BTlTa8sL.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
2979
dist/index.js
vendored
Normal file
2979
dist/index.js
vendored
Normal file
File diff suppressed because it is too large
Load diff
1
dist/index.js.map
vendored
Normal file
1
dist/index.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
207
dist/install-build-wrapper.js
vendored
Normal file
207
dist/install-build-wrapper.js
vendored
Normal file
|
|
@ -0,0 +1,207 @@
|
|||
import { f as execExports, e as coreExports } from './exec-BTlTa8sL.js';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import 'os';
|
||||
import 'crypto';
|
||||
import 'http';
|
||||
import 'https';
|
||||
import 'net';
|
||||
import 'tls';
|
||||
import 'events';
|
||||
import 'assert';
|
||||
import 'util';
|
||||
import 'stream';
|
||||
import 'buffer';
|
||||
import 'querystring';
|
||||
import 'stream/web';
|
||||
import 'node:stream';
|
||||
import 'node:util';
|
||||
import 'node:events';
|
||||
import 'worker_threads';
|
||||
import 'perf_hooks';
|
||||
import 'util/types';
|
||||
import 'async_hooks';
|
||||
import 'console';
|
||||
import 'url';
|
||||
import 'zlib';
|
||||
import 'string_decoder';
|
||||
import 'diagnostics_channel';
|
||||
import 'child_process';
|
||||
import 'timers';
|
||||
|
||||
/**
|
||||
* Compute all names and paths related to the build wrapper
|
||||
* based on the runner environment
|
||||
*/
|
||||
function getBuildWrapperInfo({
|
||||
runnerOS,
|
||||
runnerArch,
|
||||
runnerTemp,
|
||||
sonarHostUrl,
|
||||
}) {
|
||||
const { buildWrapperSuffix, buildWrapperName } = getSuffixAndName(
|
||||
runnerOS,
|
||||
runnerArch
|
||||
);
|
||||
|
||||
const buildWrapperDir = `${runnerTemp}/build-wrapper-${buildWrapperSuffix}`;
|
||||
const buildWrapperUrl = `${sonarHostUrl}/static/cpp/build-wrapper-${buildWrapperSuffix}.zip`;
|
||||
const buildWrapperBin = `${buildWrapperDir}/${buildWrapperName}`;
|
||||
|
||||
return {
|
||||
buildWrapperUrl,
|
||||
buildWrapperDir,
|
||||
buildWrapperBin,
|
||||
};
|
||||
}
|
||||
|
||||
function getSuffixAndName(runnerOS, runnerArch) {
|
||||
if (
|
||||
runnerArch !== "X64" &&
|
||||
!(runnerArch === "ARM64" && (runnerOS === "macOS" || runnerOS === "Linux"))
|
||||
) {
|
||||
throw new Error(
|
||||
`Architecture '${runnerArch}' is unsupported by build-wrapper`
|
||||
);
|
||||
}
|
||||
|
||||
switch (runnerOS) {
|
||||
case "Windows":
|
||||
return {
|
||||
buildWrapperSuffix: "win-x86",
|
||||
buildWrapperName: "build-wrapper-win-x86-64.exe",
|
||||
};
|
||||
|
||||
case "Linux":
|
||||
switch (runnerArch) {
|
||||
case "X64":
|
||||
return {
|
||||
buildWrapperSuffix: "linux-x86",
|
||||
buildWrapperName: "build-wrapper-linux-x86-64",
|
||||
};
|
||||
|
||||
case "ARM64":
|
||||
return {
|
||||
buildWrapperSuffix: "linux-aarch64",
|
||||
buildWrapperName: "build-wrapper-linux-aarch64",
|
||||
};
|
||||
}
|
||||
break; // handled before the switch
|
||||
|
||||
case "macOS":
|
||||
return {
|
||||
buildWrapperSuffix: "macosx-x86",
|
||||
buildWrapperName: "build-wrapper-macosx-x86",
|
||||
};
|
||||
|
||||
default:
|
||||
throw new Error(`Unsupported runner OS '${runnerOS}'`);
|
||||
}
|
||||
}
|
||||
|
||||
async function getRealPath(filePath, runnerOS) {
|
||||
switch (runnerOS) {
|
||||
case "Windows": {
|
||||
const windowsResult = await execExports.getExecOutput("cygpath", [
|
||||
"--absolute",
|
||||
"--windows",
|
||||
filePath,
|
||||
]);
|
||||
return windowsResult.stdout.trim();
|
||||
}
|
||||
case "Linux": {
|
||||
const linuxResult = await execExports.getExecOutput("readlink", [
|
||||
"-f",
|
||||
filePath,
|
||||
]);
|
||||
return linuxResult.stdout.trim();
|
||||
}
|
||||
case "macOS": {
|
||||
const macResult = await execExports.getExecOutput("greadlink", ["-f", filePath]);
|
||||
return macResult.stdout.trim();
|
||||
}
|
||||
default:
|
||||
return path.resolve(filePath);
|
||||
}
|
||||
}
|
||||
|
||||
async function installMacOSPackages() {
|
||||
if (process.platform === "darwin") {
|
||||
coreExports.info("Installing required packages for macOS");
|
||||
await execExports.exec("brew", ["install", "coreutils"]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* These RUNNER_XX env variables come from GitHub by default.
|
||||
* See https://docs.github.com/en/actions/reference/workflows-and-actions/variables#default-environment-variables
|
||||
*
|
||||
* If SONAR_HOST_URL is omitted, we assume sonarcloud.io
|
||||
*/
|
||||
function getEnvVariables() {
|
||||
const sonarHostUrl = process.env.SONAR_HOST_URL
|
||||
? process.env.SONAR_HOST_URL.replace(/\/$/, "")
|
||||
: "https://sonarcloud.io";
|
||||
|
||||
return {
|
||||
runnerOS: process.env.RUNNER_OS,
|
||||
runnerArch: process.env.RUNNER_ARCH,
|
||||
runnerTemp: process.env.RUNNER_TEMP,
|
||||
sonarHostUrl,
|
||||
};
|
||||
}
|
||||
|
||||
async function downloadAndInstallBuildWrapper(downloadUrl, runnerEnv) {
|
||||
const { runnerArch, runnerOS, runnerTemp } = runnerEnv;
|
||||
const tmpZipPath = path.join(
|
||||
runnerTemp,
|
||||
`build-wrapper-${runnerOS}-${runnerArch}.zip`
|
||||
);
|
||||
|
||||
coreExports.startGroup(`Download ${downloadUrl}`);
|
||||
|
||||
coreExports.info(`Downloading '${downloadUrl}'`);
|
||||
|
||||
if (!fs.existsSync(runnerTemp)) {
|
||||
fs.mkdirSync(runnerTemp, { recursive: true });
|
||||
}
|
||||
|
||||
await execExports.exec("curl", ["-sSLo", tmpZipPath, downloadUrl]);
|
||||
|
||||
coreExports.info("Decompressing");
|
||||
await execExports.exec("unzip", ["-o", "-d", runnerTemp, tmpZipPath]);
|
||||
|
||||
coreExports.endGroup();
|
||||
}
|
||||
|
||||
async function run() {
|
||||
try {
|
||||
await installMacOSPackages();
|
||||
|
||||
const envVariables = getEnvVariables();
|
||||
|
||||
const { buildWrapperBin, buildWrapperDir, buildWrapperUrl } =
|
||||
getBuildWrapperInfo(envVariables);
|
||||
|
||||
await downloadAndInstallBuildWrapper(buildWrapperUrl, envVariables);
|
||||
|
||||
const buildWrapperBinDir = await getRealPath(
|
||||
buildWrapperDir,
|
||||
envVariables.runnerOS
|
||||
);
|
||||
coreExports.addPath(buildWrapperBinDir);
|
||||
coreExports.info(`'${buildWrapperBinDir}' added to the path`);
|
||||
|
||||
const buildWrapperBinPath = await getRealPath(
|
||||
buildWrapperBin,
|
||||
envVariables.runnerOS
|
||||
);
|
||||
coreExports.setOutput("build-wrapper-binary", buildWrapperBinPath);
|
||||
coreExports.info(`'build-wrapper-binary' output set to '${buildWrapperBinPath}'`);
|
||||
} catch (error) {
|
||||
coreExports.setFailed(error.message);
|
||||
}
|
||||
}
|
||||
|
||||
run();
|
||||
//# sourceMappingURL=install-build-wrapper.js.map
|
||||
1
dist/install-build-wrapper.js.map
vendored
Normal file
1
dist/install-build-wrapper.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -1,27 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
if [[ -z "${SONAR_TOKEN}" ]]; then
|
||||
echo "This GitHub Action requires the SONAR_TOKEN env variable."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -z "${SONAR_HOST_URL}" ]]; then
|
||||
echo "This GitHub Action requires the SONAR_HOST_URL env variable."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -f "${INPUT_PROJECTBASEDIR%/}pom.xml" ]]; then
|
||||
echo "Maven project detected. You should run the goal 'org.sonarsource.scanner.maven:sonar' during build rather than using this GitHub Action."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -f "${INPUT_PROJECTBASEDIR%/}build.gradle" ]]; then
|
||||
echo "Gradle project detected. You should use the SonarQube plugin for Gradle during build rather than using this GitHub Action."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
unset JAVA_HOME
|
||||
|
||||
sonar-scanner -Dsonar.projectBaseDir=${INPUT_PROJECTBASEDIR} ${INPUT_ARGS}
|
||||
BIN
images/SQ_Logo_Server_Cloud_Dark_Backgrounds.png
Normal file
BIN
images/SQ_Logo_Server_Cloud_Dark_Backgrounds.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 24 KiB |
BIN
images/SQ_Logo_Server_Cloud_Light_Backgrounds.png
Normal file
BIN
images/SQ_Logo_Server_Cloud_Light_Backgrounds.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 25 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 9.7 KiB |
13
install-build-wrapper/action.yml
Normal file
13
install-build-wrapper/action.yml
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
name: "Install Build Wrapper for C and C++"
|
||||
description: >
|
||||
Download and install the Build Wrapper for C, C++, and Objective-C
|
||||
projects analyzed with manual config.
|
||||
branding:
|
||||
icon: check
|
||||
color: green
|
||||
outputs:
|
||||
build-wrapper-binary:
|
||||
description: "Absolute path to Build Wrapper binary."
|
||||
runs:
|
||||
using: node20
|
||||
main: ../dist/install-build-wrapper.js
|
||||
945
package-lock.json
generated
Normal file
945
package-lock.json
generated
Normal file
|
|
@ -0,0 +1,945 @@
|
|||
{
|
||||
"name": "sonarqube-scan-action",
|
||||
"version": "6.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "sonarqube-scan-action",
|
||||
"version": "6.0.0",
|
||||
"license": "LGPL-3.0-only",
|
||||
"dependencies": {
|
||||
"@actions/core": "1.11.1",
|
||||
"@actions/github": "6.0.1",
|
||||
"@actions/tool-cache": "2.0.2",
|
||||
"string-argv": "0.3.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-commonjs": "28.0.6",
|
||||
"@rollup/plugin-node-resolve": "16.0.1",
|
||||
"mock-fs": "5.5.0",
|
||||
"rollup": "4.50.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@actions/core": {
|
||||
"version": "1.11.1",
|
||||
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.11.1.tgz",
|
||||
"integrity": "sha512-hXJCSrkwfA46Vd9Z3q4cpEpHB1rL5NG04+/rbqW9d3+CSvtB1tYe8UTpAlixa1vj0m/ULglfEK2UKxMGxCxv5A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@actions/exec": "^1.1.1",
|
||||
"@actions/http-client": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@actions/exec": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@actions/exec/-/exec-1.1.1.tgz",
|
||||
"integrity": "sha512-+sCcHHbVdk93a0XT19ECtO/gIXoxvdsgQLzb2fE2/5sIZmWQuluYyjPQtrtTHdU1YzTZ7bAPN4sITq2xi1679w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@actions/io": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@actions/github": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@actions/github/-/github-6.0.1.tgz",
|
||||
"integrity": "sha512-xbZVcaqD4XnQAe35qSQqskb3SqIAfRyLBrHMd/8TuL7hJSz2QtbDwnNM8zWx4zO5l2fnGtseNE3MbEvD7BxVMw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@actions/http-client": "^2.2.0",
|
||||
"@octokit/core": "^5.0.1",
|
||||
"@octokit/plugin-paginate-rest": "^9.2.2",
|
||||
"@octokit/plugin-rest-endpoint-methods": "^10.4.0",
|
||||
"@octokit/request": "^8.4.1",
|
||||
"@octokit/request-error": "^5.1.1",
|
||||
"undici": "^5.28.5"
|
||||
}
|
||||
},
|
||||
"node_modules/@actions/http-client": {
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.2.3.tgz",
|
||||
"integrity": "sha512-mx8hyJi/hjFvbPokCg4uRd4ZX78t+YyRPtnKWwIl+RzNaVuFpQHfmlGVfsKEJN8LwTCvL+DfVgAM04XaHkm6bA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"tunnel": "^0.0.6",
|
||||
"undici": "^5.25.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@actions/io": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@actions/io/-/io-1.1.3.tgz",
|
||||
"integrity": "sha512-wi9JjgKLYS7U/z8PPbco+PvTb/nRWjeoFlJ1Qer83k/3C5PHQi28hiVdeE2kHXmIL99mQFawx8qt/JPjZilJ8Q==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@actions/tool-cache": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@actions/tool-cache/-/tool-cache-2.0.2.tgz",
|
||||
"integrity": "sha512-fBhNNOWxuoLxztQebpOaWu6WeVmuwa77Z+DxIZ1B+OYvGkGQon6kTVg6Z32Cb13WCuw0szqonK+hh03mJV7Z6w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@actions/core": "^1.11.1",
|
||||
"@actions/exec": "^1.0.0",
|
||||
"@actions/http-client": "^2.0.1",
|
||||
"@actions/io": "^1.1.1",
|
||||
"semver": "^6.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@fastify/busboy": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz",
|
||||
"integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/sourcemap-codec": {
|
||||
"version": "1.5.5",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
|
||||
"integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@octokit/auth-token": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz",
|
||||
"integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/core": {
|
||||
"version": "5.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.2.2.tgz",
|
||||
"integrity": "sha512-/g2d4sW9nUDJOMz3mabVQvOGhVa4e/BN/Um7yca9Bb2XTzPPnfTWHWQg+IsEYO7M3Vx+EXvaM/I2pJWIMun1bg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/auth-token": "^4.0.0",
|
||||
"@octokit/graphql": "^7.1.0",
|
||||
"@octokit/request": "^8.4.1",
|
||||
"@octokit/request-error": "^5.1.1",
|
||||
"@octokit/types": "^13.0.0",
|
||||
"before-after-hook": "^2.2.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/endpoint": {
|
||||
"version": "9.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.6.tgz",
|
||||
"integrity": "sha512-H1fNTMA57HbkFESSt3Y9+FBICv+0jFceJFPWDePYlR/iMGrwM5ph+Dd4XRQs+8X+PUFURLQgX9ChPfhJ/1uNQw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^13.1.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/graphql": {
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.1.1.tgz",
|
||||
"integrity": "sha512-3mkDltSfcDUoa176nlGoA32RGjeWjl3K7F/BwHwRMJUW/IteSa4bnSV8p2ThNkcIcZU2umkZWxwETSSCJf2Q7g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/request": "^8.4.1",
|
||||
"@octokit/types": "^13.0.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/openapi-types": {
|
||||
"version": "24.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-24.2.0.tgz",
|
||||
"integrity": "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@octokit/plugin-paginate-rest": {
|
||||
"version": "9.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-9.2.2.tgz",
|
||||
"integrity": "sha512-u3KYkGF7GcZnSD/3UP0S7K5XUFT2FkOQdcfXZGZQPGv3lm4F2Xbf71lvjldr8c1H3nNbF+33cLEkWYbokGWqiQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^12.6.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@octokit/core": "5"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/openapi-types": {
|
||||
"version": "20.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-20.0.0.tgz",
|
||||
"integrity": "sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/types": {
|
||||
"version": "12.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.6.0.tgz",
|
||||
"integrity": "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^20.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/plugin-rest-endpoint-methods": {
|
||||
"version": "10.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-10.4.1.tgz",
|
||||
"integrity": "sha512-xV1b+ceKV9KytQe3zCVqjg+8GTGfDYwaT1ATU5isiUyVtlVAO3HNdzpS4sr4GBx4hxQ46s7ITtZrAsxG22+rVg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^12.6.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@octokit/core": "5"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/openapi-types": {
|
||||
"version": "20.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-20.0.0.tgz",
|
||||
"integrity": "sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/types": {
|
||||
"version": "12.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.6.0.tgz",
|
||||
"integrity": "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^20.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/request": {
|
||||
"version": "8.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.4.1.tgz",
|
||||
"integrity": "sha512-qnB2+SY3hkCmBxZsR/MPCybNmbJe4KAlfWErXq+rBKkQJlbjdJeS85VI9r8UqeLYLvnAenU8Q1okM/0MBsAGXw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/endpoint": "^9.0.6",
|
||||
"@octokit/request-error": "^5.1.1",
|
||||
"@octokit/types": "^13.1.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/request-error": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.1.1.tgz",
|
||||
"integrity": "sha512-v9iyEQJH6ZntoENr9/yXxjuezh4My67CBSu9r6Ve/05Iu5gNgnisNWOsoJHTP6k0Rr0+HQIpnH+kyammu90q/g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^13.1.0",
|
||||
"deprecation": "^2.0.0",
|
||||
"once": "^1.4.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/types": {
|
||||
"version": "13.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.10.0.tgz",
|
||||
"integrity": "sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^24.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@rollup/plugin-commonjs": {
|
||||
"version": "28.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-28.0.6.tgz",
|
||||
"integrity": "sha512-XSQB1K7FUU5QP+3lOQmVCE3I0FcbbNvmNT4VJSj93iUjayaARrTQeoRdiYQoftAJBLrR9t2agwAd3ekaTgHNlw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@rollup/pluginutils": "^5.0.1",
|
||||
"commondir": "^1.0.1",
|
||||
"estree-walker": "^2.0.2",
|
||||
"fdir": "^6.2.0",
|
||||
"is-reference": "1.2.1",
|
||||
"magic-string": "^0.30.3",
|
||||
"picomatch": "^4.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.0.0 || 14 >= 14.17"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"rollup": "^2.68.0||^3.0.0||^4.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"rollup": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@rollup/plugin-node-resolve": {
|
||||
"version": "16.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-16.0.1.tgz",
|
||||
"integrity": "sha512-tk5YCxJWIG81umIvNkSod2qK5KyQW19qcBF/B78n1bjtOON6gzKoVeSzAE8yHCZEDmqkHKkxplExA8KzdJLJpA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@rollup/pluginutils": "^5.0.1",
|
||||
"@types/resolve": "1.20.2",
|
||||
"deepmerge": "^4.2.2",
|
||||
"is-module": "^1.0.0",
|
||||
"resolve": "^1.22.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"rollup": "^2.78.0||^3.0.0||^4.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"rollup": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@rollup/pluginutils": {
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.3.0.tgz",
|
||||
"integrity": "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/estree": "^1.0.0",
|
||||
"estree-walker": "^2.0.2",
|
||||
"picomatch": "^4.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"rollup": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@rollup/rollup-android-arm-eabi": {
|
||||
"version": "4.50.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.50.1.tgz",
|
||||
"integrity": "sha512-HJXwzoZN4eYTdD8bVV22DN8gsPCAj3V20NHKOs8ezfXanGpmVPR7kalUHd+Y31IJp9stdB87VKPFbsGY3H/2ag==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-android-arm64": {
|
||||
"version": "4.50.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.50.1.tgz",
|
||||
"integrity": "sha512-PZlsJVcjHfcH53mOImyt3bc97Ep3FJDXRpk9sMdGX0qgLmY0EIWxCag6EigerGhLVuL8lDVYNnSo8qnTElO4xw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-darwin-arm64": {
|
||||
"version": "4.50.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.50.1.tgz",
|
||||
"integrity": "sha512-xc6i2AuWh++oGi4ylOFPmzJOEeAa2lJeGUGb4MudOtgfyyjr4UPNK+eEWTPLvmPJIY/pgw6ssFIox23SyrkkJw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-darwin-x64": {
|
||||
"version": "4.50.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.50.1.tgz",
|
||||
"integrity": "sha512-2ofU89lEpDYhdLAbRdeyz/kX3Y2lpYc6ShRnDjY35bZhd2ipuDMDi6ZTQ9NIag94K28nFMofdnKeHR7BT0CATw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-freebsd-arm64": {
|
||||
"version": "4.50.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.50.1.tgz",
|
||||
"integrity": "sha512-wOsE6H2u6PxsHY/BeFHA4VGQN3KUJFZp7QJBmDYI983fgxq5Th8FDkVuERb2l9vDMs1D5XhOrhBrnqcEY6l8ZA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-freebsd-x64": {
|
||||
"version": "4.50.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.50.1.tgz",
|
||||
"integrity": "sha512-A/xeqaHTlKbQggxCqispFAcNjycpUEHP52mwMQZUNqDUJFFYtPHCXS1VAG29uMlDzIVr+i00tSFWFLivMcoIBQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
|
||||
"version": "4.50.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.50.1.tgz",
|
||||
"integrity": "sha512-54v4okehwl5TaSIkpp97rAHGp7t3ghinRd/vyC1iXqXMfjYUTm7TfYmCzXDoHUPTTf36L8pr0E7YsD3CfB3ZDg==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
|
||||
"version": "4.50.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.50.1.tgz",
|
||||
"integrity": "sha512-p/LaFyajPN/0PUHjv8TNyxLiA7RwmDoVY3flXHPSzqrGcIp/c2FjwPPP5++u87DGHtw+5kSH5bCJz0mvXngYxw==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm64-gnu": {
|
||||
"version": "4.50.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.50.1.tgz",
|
||||
"integrity": "sha512-2AbMhFFkTo6Ptna1zO7kAXXDLi7H9fGTbVaIq2AAYO7yzcAsuTNWPHhb2aTA6GPiP+JXh85Y8CiS54iZoj4opw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm64-musl": {
|
||||
"version": "4.50.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.50.1.tgz",
|
||||
"integrity": "sha512-Cgef+5aZwuvesQNw9eX7g19FfKX5/pQRIyhoXLCiBOrWopjo7ycfB292TX9MDcDijiuIJlx1IzJz3IoCPfqs9w==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-loongarch64-gnu": {
|
||||
"version": "4.50.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.50.1.tgz",
|
||||
"integrity": "sha512-RPhTwWMzpYYrHrJAS7CmpdtHNKtt2Ueo+BlLBjfZEhYBhK00OsEqM08/7f+eohiF6poe0YRDDd8nAvwtE/Y62Q==",
|
||||
"cpu": [
|
||||
"loong64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-ppc64-gnu": {
|
||||
"version": "4.50.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.50.1.tgz",
|
||||
"integrity": "sha512-eSGMVQw9iekut62O7eBdbiccRguuDgiPMsw++BVUg+1K7WjZXHOg/YOT9SWMzPZA+w98G+Fa1VqJgHZOHHnY0Q==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
|
||||
"version": "4.50.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.50.1.tgz",
|
||||
"integrity": "sha512-S208ojx8a4ciIPrLgazF6AgdcNJzQE4+S9rsmOmDJkusvctii+ZvEuIC4v/xFqzbuP8yDjn73oBlNDgF6YGSXQ==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-riscv64-musl": {
|
||||
"version": "4.50.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.50.1.tgz",
|
||||
"integrity": "sha512-3Ag8Ls1ggqkGUvSZWYcdgFwriy2lWo+0QlYgEFra/5JGtAd6C5Hw59oojx1DeqcA2Wds2ayRgvJ4qxVTzCHgzg==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-s390x-gnu": {
|
||||
"version": "4.50.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.50.1.tgz",
|
||||
"integrity": "sha512-t9YrKfaxCYe7l7ldFERE1BRg/4TATxIg+YieHQ966jwvo7ddHJxPj9cNFWLAzhkVsbBvNA4qTbPVNsZKBO4NSg==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-x64-gnu": {
|
||||
"version": "4.50.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.50.1.tgz",
|
||||
"integrity": "sha512-MCgtFB2+SVNuQmmjHf+wfI4CMxy3Tk8XjA5Z//A0AKD7QXUYFMQcns91K6dEHBvZPCnhJSyDWLApk40Iq/H3tA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-x64-musl": {
|
||||
"version": "4.50.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.50.1.tgz",
|
||||
"integrity": "sha512-nEvqG+0jeRmqaUMuwzlfMKwcIVffy/9KGbAGyoa26iu6eSngAYQ512bMXuqqPrlTyfqdlB9FVINs93j534UJrg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-openharmony-arm64": {
|
||||
"version": "4.50.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.50.1.tgz",
|
||||
"integrity": "sha512-RDsLm+phmT3MJd9SNxA9MNuEAO/J2fhW8GXk62G/B4G7sLVumNFbRwDL6v5NrESb48k+QMqdGbHgEtfU0LCpbA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"openharmony"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-arm64-msvc": {
|
||||
"version": "4.50.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.50.1.tgz",
|
||||
"integrity": "sha512-hpZB/TImk2FlAFAIsoElM3tLzq57uxnGYwplg6WDyAxbYczSi8O2eQ+H2Lx74504rwKtZ3N2g4bCUkiamzS6TQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-ia32-msvc": {
|
||||
"version": "4.50.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.50.1.tgz",
|
||||
"integrity": "sha512-SXjv8JlbzKM0fTJidX4eVsH+Wmnp0/WcD8gJxIZyR6Gay5Qcsmdbi9zVtnbkGPG8v2vMR1AD06lGWy5FLMcG7A==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-x64-msvc": {
|
||||
"version": "4.50.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.50.1.tgz",
|
||||
"integrity": "sha512-StxAO/8ts62KZVRAm4JZYq9+NqNsV7RvimNK+YM7ry//zebEH6meuugqW/P5OFUCjyQgui+9fUxT6d5NShvMvA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
]
|
||||
},
|
||||
"node_modules/@types/estree": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
|
||||
"integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/resolve": {
|
||||
"version": "1.20.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz",
|
||||
"integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/before-after-hook": {
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz",
|
||||
"integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/commondir": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
|
||||
"integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/deepmerge": {
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
|
||||
"integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/deprecation": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
|
||||
"integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/estree-walker": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
|
||||
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/fdir": {
|
||||
"version": "6.5.0",
|
||||
"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
|
||||
"integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"picomatch": "^3 || ^4"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"picomatch": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/fsevents": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
||||
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/function-bind": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
||||
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/hasown": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
|
||||
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"function-bind": "^1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/is-core-module": {
|
||||
"version": "2.16.1",
|
||||
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
|
||||
"integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"hasown": "^2.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/is-module": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz",
|
||||
"integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/is-reference": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz",
|
||||
"integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/estree": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/magic-string": {
|
||||
"version": "0.30.18",
|
||||
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.18.tgz",
|
||||
"integrity": "sha512-yi8swmWbO17qHhwIBNeeZxTceJMeBvWJaId6dyvTSOwTipqeHhMhOrz6513r1sOKnpvQ7zkhlG8tPrpilwTxHQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@jridgewell/sourcemap-codec": "^1.5.5"
|
||||
}
|
||||
},
|
||||
"node_modules/mock-fs": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-5.5.0.tgz",
|
||||
"integrity": "sha512-d/P1M/RacgM3dB0sJ8rjeRNXxtapkPCUnMGmIN0ixJ16F/E4GUZCvWcSGfWGz8eaXYvn1s9baUwNjI4LOPEjiA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"node_modules/path-parse": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
|
||||
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/picomatch": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
|
||||
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/jonschlinkert"
|
||||
}
|
||||
},
|
||||
"node_modules/resolve": {
|
||||
"version": "1.22.10",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
|
||||
"integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"is-core-module": "^2.16.0",
|
||||
"path-parse": "^1.0.7",
|
||||
"supports-preserve-symlinks-flag": "^1.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"resolve": "bin/resolve"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/rollup": {
|
||||
"version": "4.50.1",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.50.1.tgz",
|
||||
"integrity": "sha512-78E9voJHwnXQMiQdiqswVLZwJIzdBKJ1GdI5Zx6XwoFKUIk09/sSrr+05QFzvYb8q6Y9pPV45zzDuYa3907TZA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/estree": "1.0.8"
|
||||
},
|
||||
"bin": {
|
||||
"rollup": "dist/bin/rollup"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0",
|
||||
"npm": ">=8.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@rollup/rollup-android-arm-eabi": "4.50.1",
|
||||
"@rollup/rollup-android-arm64": "4.50.1",
|
||||
"@rollup/rollup-darwin-arm64": "4.50.1",
|
||||
"@rollup/rollup-darwin-x64": "4.50.1",
|
||||
"@rollup/rollup-freebsd-arm64": "4.50.1",
|
||||
"@rollup/rollup-freebsd-x64": "4.50.1",
|
||||
"@rollup/rollup-linux-arm-gnueabihf": "4.50.1",
|
||||
"@rollup/rollup-linux-arm-musleabihf": "4.50.1",
|
||||
"@rollup/rollup-linux-arm64-gnu": "4.50.1",
|
||||
"@rollup/rollup-linux-arm64-musl": "4.50.1",
|
||||
"@rollup/rollup-linux-loongarch64-gnu": "4.50.1",
|
||||
"@rollup/rollup-linux-ppc64-gnu": "4.50.1",
|
||||
"@rollup/rollup-linux-riscv64-gnu": "4.50.1",
|
||||
"@rollup/rollup-linux-riscv64-musl": "4.50.1",
|
||||
"@rollup/rollup-linux-s390x-gnu": "4.50.1",
|
||||
"@rollup/rollup-linux-x64-gnu": "4.50.1",
|
||||
"@rollup/rollup-linux-x64-musl": "4.50.1",
|
||||
"@rollup/rollup-openharmony-arm64": "4.50.1",
|
||||
"@rollup/rollup-win32-arm64-msvc": "4.50.1",
|
||||
"@rollup/rollup-win32-ia32-msvc": "4.50.1",
|
||||
"@rollup/rollup-win32-x64-msvc": "4.50.1",
|
||||
"fsevents": "~2.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/semver": {
|
||||
"version": "6.3.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
||||
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
}
|
||||
},
|
||||
"node_modules/string-argv": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz",
|
||||
"integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.6.19"
|
||||
}
|
||||
},
|
||||
"node_modules/supports-preserve-symlinks-flag": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
|
||||
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/tunnel": {
|
||||
"version": "0.0.6",
|
||||
"resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
|
||||
"integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.6.11 <=0.7.0 || >=0.7.3"
|
||||
}
|
||||
},
|
||||
"node_modules/undici": {
|
||||
"version": "5.29.0",
|
||||
"resolved": "https://registry.npmjs.org/undici/-/undici-5.29.0.tgz",
|
||||
"integrity": "sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@fastify/busboy": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0"
|
||||
}
|
||||
},
|
||||
"node_modules/universal-user-agent": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.1.tgz",
|
||||
"integrity": "sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
|
||||
"license": "ISC"
|
||||
}
|
||||
}
|
||||
}
|
||||
24
package.json
Normal file
24
package.json
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"name": "sonarqube-scan-action",
|
||||
"version": "6.0.0",
|
||||
"description": "This SonarSource project, available as a GitHub Action, scans your projects with SonarQube [Server](https://www.sonarsource.com/products/sonarqube/) or [Cloud](https://www.sonarsource.com/products/sonarcloud/).",
|
||||
"type": "module",
|
||||
"main": "src/main/index.js",
|
||||
"scripts": {
|
||||
"build": "rollup --config rollup.config.js",
|
||||
"test": "node --test"
|
||||
},
|
||||
"license": "LGPL-3.0-only",
|
||||
"dependencies": {
|
||||
"@actions/core": "1.11.1",
|
||||
"@actions/github": "6.0.1",
|
||||
"@actions/tool-cache": "2.0.2",
|
||||
"string-argv": "0.3.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-commonjs": "28.0.6",
|
||||
"@rollup/plugin-node-resolve": "16.0.1",
|
||||
"mock-fs": "5.5.0",
|
||||
"rollup": "4.50.1"
|
||||
}
|
||||
}
|
||||
18
rollup.config.js
Normal file
18
rollup.config.js
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
import commonjs from "@rollup/plugin-commonjs";
|
||||
import { nodeResolve } from "@rollup/plugin-node-resolve";
|
||||
|
||||
const config = {
|
||||
input: [
|
||||
"src/main/index.js",
|
||||
"src/install-build-wrapper/install-build-wrapper.js",
|
||||
],
|
||||
output: {
|
||||
esModule: true,
|
||||
dir: "dist",
|
||||
format: "es",
|
||||
sourcemap: true,
|
||||
},
|
||||
plugins: [commonjs(), nodeResolve({ preferBuiltins: true })],
|
||||
};
|
||||
|
||||
export default config;
|
||||
8
scripts/cert.sh
Executable file
8
scripts/cert.sh
Executable file
|
|
@ -0,0 +1,8 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
if [[ -n "${SONAR_ROOT_CERT}" ]]; then
|
||||
echo "Adding custom root certificate to java certificate store"
|
||||
rm -f /tmp/tmpcert.pem
|
||||
echo "${SONAR_ROOT_CERT}" > /tmp/tmpcert.pem
|
||||
keytool -keystore /etc/ssl/certs/java/cacerts -storepass changeit -noprompt -trustcacerts -importcert -alias sonarqube -file /tmp/tmpcert.pem
|
||||
fi
|
||||
71
scripts/configure_paths.sh
Executable file
71
scripts/configure_paths.sh
Executable file
|
|
@ -0,0 +1,71 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
if [[ ${ARCH} != "X64" && ! (${ARCH} == "ARM64" && (${OS} == "macOS" || ${OS} == "Linux")) ]]; then
|
||||
echo "::error::Architecture '${ARCH}' is unsupported by build-wrapper"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case ${OS} in
|
||||
Windows)
|
||||
SONAR_SCANNER_SUFFIX="windows-x64"
|
||||
BUILD_WRAPPER_SUFFIX="win-x86"
|
||||
SONAR_SCANNER_NAME="sonar-scanner.bat"
|
||||
BUILD_WRAPPER_NAME="build-wrapper-win-x86-64.exe"
|
||||
SONAR_SCANNER_URL="${SONAR_SCANNER_URL_WINDOWS_X64}"
|
||||
SONAR_SCANNER_SHA="${SONAR_SCANNER_SHA_WINDOWS_X64}"
|
||||
;;
|
||||
Linux)
|
||||
case ${ARCH} in
|
||||
X64)
|
||||
SONAR_SCANNER_SUFFIX="linux-x64"
|
||||
BUILD_WRAPPER_SUFFIX="linux-x86"
|
||||
BUILD_WRAPPER_NAME="build-wrapper-linux-x86-64"
|
||||
SONAR_SCANNER_URL="${SONAR_SCANNER_URL_LINUX_X64}"
|
||||
SONAR_SCANNER_SHA="${SONAR_SCANNER_SHA_LINUX_X64}"
|
||||
;;
|
||||
ARM64)
|
||||
SONAR_SCANNER_SUFFIX="linux-aarch64"
|
||||
BUILD_WRAPPER_SUFFIX="linux-aarch64"
|
||||
BUILD_WRAPPER_NAME="build-wrapper-linux-aarch64"
|
||||
SONAR_SCANNER_URL="${SONAR_SCANNER_URL_LINUX_AARCH64}"
|
||||
SONAR_SCANNER_SHA="${SONAR_SCANNER_SHA_LINUX_AARCH64}"
|
||||
;;
|
||||
esac
|
||||
SONAR_SCANNER_NAME="sonar-scanner"
|
||||
;;
|
||||
macOS)
|
||||
case ${ARCH} in
|
||||
X64)
|
||||
SONAR_SCANNER_SUFFIX="macosx-x64"
|
||||
SONAR_SCANNER_URL="${SONAR_SCANNER_URL_MACOSX_X64}"
|
||||
SONAR_SCANNER_SHA="${SONAR_SCANNER_SHA_MACOSX_X64}"
|
||||
;;
|
||||
ARM64)
|
||||
SONAR_SCANNER_SUFFIX="macosx-aarch64"
|
||||
SONAR_SCANNER_URL="${SONAR_SCANNER_URL_MACOSX_AARCH64}"
|
||||
SONAR_SCANNER_SHA="${SONAR_SCANNER_SHA_MACOSX_AARCH64}"
|
||||
;;
|
||||
esac
|
||||
BUILD_WRAPPER_SUFFIX="macosx-x86"
|
||||
SONAR_SCANNER_NAME="sonar-scanner"
|
||||
BUILD_WRAPPER_NAME="build-wrapper-macosx-x86"
|
||||
;;
|
||||
*)
|
||||
echo "::error::Unsupported runner OS '${OS}'"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
echo "sonar-scanner-url=${SONAR_SCANNER_URL}"
|
||||
echo "sonar-scanner-sha=${SONAR_SCANNER_SHA}"
|
||||
|
||||
SONAR_SCANNER_DIR="${INSTALL_PATH}/sonar-scanner-${SONAR_SCANNER_VERSION}-${SONAR_SCANNER_SUFFIX}"
|
||||
echo "sonar-scanner-dir=${SONAR_SCANNER_DIR}"
|
||||
echo "sonar-scanner-bin=${SONAR_SCANNER_DIR}/bin/${SONAR_SCANNER_NAME}"
|
||||
|
||||
BUILD_WRAPPER_DIR="${INSTALL_PATH}/build-wrapper-${BUILD_WRAPPER_SUFFIX}"
|
||||
echo "build-wrapper-url=${SONAR_HOST_URL%/}/static/cpp/build-wrapper-${BUILD_WRAPPER_SUFFIX}.zip"
|
||||
echo "build-wrapper-dir=${BUILD_WRAPPER_DIR}"
|
||||
echo "build-wrapper-bin=${BUILD_WRAPPER_DIR}/${BUILD_WRAPPER_NAME}"
|
||||
|
||||
26
scripts/create_install_path.sh
Executable file
26
scripts/create_install_path.sh
Executable file
|
|
@ -0,0 +1,26 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
source "$(dirname -- "$0")/utils.sh"
|
||||
|
||||
echo "Installation path is '${INSTALL_PATH}'"
|
||||
|
||||
test ! -z "${INSTALL_PATH}"
|
||||
check_status "Empty installation path specified"
|
||||
|
||||
if [[ ! -e "${INSTALL_PATH}" ]]; then
|
||||
mkdir -p "${INSTALL_PATH}"
|
||||
check_status "Failed to create non-existing installation path '${INSTALL_PATH}'"
|
||||
fi
|
||||
|
||||
ABSOLUTE_INSTALL_PATH=$(realpath "${INSTALL_PATH}")
|
||||
echo "Absolute installation path is '${ABSOLUTE_INSTALL_PATH}'"
|
||||
|
||||
test -d "${INSTALL_PATH}"
|
||||
check_status "Installation path '${INSTALL_PATH}' is not a directory (absolute path is '${ABSOLUTE_INSTALL_PATH}')"
|
||||
|
||||
test -r "${INSTALL_PATH}"
|
||||
check_status "Installation path '${INSTALL_PATH}' is not readable (absolute path is '${ABSOLUTE_INSTALL_PATH}')"
|
||||
|
||||
test -w "${INSTALL_PATH}"
|
||||
check_status "Installation path '${INSTALL_PATH}' is not writeable (absolute path is '${ABSOLUTE_INSTALL_PATH}')"
|
||||
|
||||
58
scripts/download.sh
Executable file
58
scripts/download.sh
Executable file
|
|
@ -0,0 +1,58 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
source "$(dirname -- "$0")/utils.sh"
|
||||
|
||||
VERIFY_CORRECTNESS=false
|
||||
|
||||
help() {
|
||||
cat <<EOF
|
||||
Usage: ./download [-v]
|
||||
-h Display help
|
||||
-v Verify correctness of a download with SHA256 checksum; Optional
|
||||
EOF
|
||||
}
|
||||
|
||||
parse_arguments() {
|
||||
while getopts "hv" arg; do
|
||||
case $arg in
|
||||
v)
|
||||
VERIFY_CORRECTNESS=true
|
||||
echo "Verify correctness is set to true"
|
||||
;;
|
||||
?)
|
||||
help
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
verify_download_correctness() {
|
||||
echo "${EXPECTED_SHA} ${TMP_ZIP_PATH}" | sha256sum -c -
|
||||
check_status "Checking sha256 failed"
|
||||
}
|
||||
|
||||
download() {
|
||||
echo "Downloading '${DOWNLOAD_URL}'"
|
||||
mkdir -p "${INSTALL_PATH}"
|
||||
check_status "Failed to create ${INSTALL_PATH}"
|
||||
curl -sSLo "${TMP_ZIP_PATH}" "${DOWNLOAD_URL}"
|
||||
check_status "Failed to download '${DOWNLOAD_URL}'"
|
||||
}
|
||||
|
||||
decompress() {
|
||||
echo "Decompressing"
|
||||
unzip -o -d "${INSTALL_PATH}" "${TMP_ZIP_PATH}"
|
||||
check_status "Failed to unzip the archive into '${INSTALL_PATH}'"
|
||||
}
|
||||
|
||||
####################################################################################
|
||||
|
||||
echo "::group::Download ${DOWNLOAD_URL}"
|
||||
parse_arguments $@
|
||||
download
|
||||
if [ "$VERIFY_CORRECTNESS" = true ]; then
|
||||
verify_download_correctness
|
||||
fi
|
||||
decompress
|
||||
echo "::endgroup::"
|
||||
25
scripts/fetch_latest_version.sh
Executable file
25
scripts/fetch_latest_version.sh
Executable file
|
|
@ -0,0 +1,25 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
source "$(dirname -- "$0")/utils.sh"
|
||||
|
||||
SONAR_SCANNER_VERSION=$(curl -sSL -H "Accept: application/vnd.github+json" \
|
||||
https://api.github.com/repos/SonarSource/sonar-scanner-cli/releases/latest | jq -r '.tag_name')
|
||||
check_status "Failed to fetch latest sonar-scanner version from GitHub API"
|
||||
|
||||
echo "sonar-scanner-version=${SONAR_SCANNER_VERSION}"
|
||||
|
||||
for OS in windows linux macosx; do
|
||||
if [[ "$OS" == "windows" ]]; then
|
||||
ARCHS=("x64")
|
||||
else
|
||||
ARCHS=("x64" "aarch64")
|
||||
fi
|
||||
for ARCH in "${ARCHS[@]}"; do
|
||||
SONAR_SCANNER_URL="https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-${SONAR_SCANNER_VERSION}-${OS}-${ARCH}.zip"
|
||||
SONAR_SCANNER_SHA=$(curl -sSL "${SONAR_SCANNER_URL}.sha256")
|
||||
check_status "Failed to download ${OS} ${ARCH} sonar-scanner checksum from '${SONAR_SCANNER_URL}'"
|
||||
|
||||
echo "sonar-scanner-url-${OS}-${ARCH}=${SONAR_SCANNER_URL}"
|
||||
echo "sonar-scanner-sha-${OS}-${ARCH}=${SONAR_SCANNER_SHA}"
|
||||
done
|
||||
done
|
||||
25
scripts/utils.sh
Executable file
25
scripts/utils.sh
Executable file
|
|
@ -0,0 +1,25 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
check_status() {
|
||||
exit_status=$?
|
||||
if [ $exit_status -ne 0 ]; then
|
||||
echo "::error::$1"
|
||||
exit $exit_status
|
||||
fi
|
||||
}
|
||||
|
||||
realpath() {
|
||||
case ${RUNNER_OS} in
|
||||
Windows)
|
||||
cygpath --absolute --windows "$1"
|
||||
;;
|
||||
Linux)
|
||||
readlink -f "$1"
|
||||
;;
|
||||
macOS)
|
||||
# installed by coreutils package
|
||||
greadlink -f "$1"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
11
sonar-scanner-version
Normal file
11
sonar-scanner-version
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
sonar-scanner-version=8.0.1.6346
|
||||
sonar-scanner-url-windows-x64=https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-8.0.1.6346-windows-x64.zip
|
||||
sonar-scanner-sha-windows-x64=52b35b24be4ce5ec2e2933b32683db45db139581c46945546d9739b0c8866231
|
||||
sonar-scanner-url-linux-x64=https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-8.0.1.6346-linux-x64.zip
|
||||
sonar-scanner-sha-linux-x64=4bd40bf8411ed104853e94a3746ec92bc92845fde2b27dbf5c33fb5cfa8ecbe9
|
||||
sonar-scanner-url-linux-aarch64=https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-8.0.1.6346-linux-aarch64.zip
|
||||
sonar-scanner-sha-linux-aarch64=ae2b062ed6d640ab9014ab576042385d54c910857de952f5cb2592d2a2d7c8d8
|
||||
sonar-scanner-url-macosx-x64=https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-8.0.1.6346-macosx-x64.zip
|
||||
sonar-scanner-sha-macosx-x64=aa9065347ba834ff6f3d461183eb40a67a321e6996206875fd257e8e7d5745b2
|
||||
sonar-scanner-url-macosx-aarch64=https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-8.0.1.6346-macosx-aarch64.zip
|
||||
sonar-scanner-sha-macosx-aarch64=2d65d49c327ec8ca5ec7c6dc2af17749f5b43c596fd906501bba5a0b09edc5e2
|
||||
80
src/install-build-wrapper/__tests__/utils.test.js
Normal file
80
src/install-build-wrapper/__tests__/utils.test.js
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
import assert from "node:assert/strict";
|
||||
import { describe, it } from "node:test";
|
||||
import { getBuildWrapperInfo } from "../utils.js";
|
||||
|
||||
describe("getBuildWrapperInfo", () => {
|
||||
const supportedPlatforms = [
|
||||
{
|
||||
platform: "Linux",
|
||||
arch: "X64",
|
||||
expectedSuffix: "linux-x86",
|
||||
expectedName: "build-wrapper-linux-x86-64",
|
||||
},
|
||||
{
|
||||
platform: "Linux",
|
||||
arch: "ARM64",
|
||||
expectedSuffix: "linux-aarch64",
|
||||
expectedName: "build-wrapper-linux-aarch64",
|
||||
},
|
||||
{
|
||||
platform: "Windows",
|
||||
arch: "X64",
|
||||
expectedSuffix: "win-x86",
|
||||
expectedName: "build-wrapper-win-x86-64.exe",
|
||||
},
|
||||
{
|
||||
platform: "macOS",
|
||||
arch: "X64",
|
||||
expectedSuffix: "macosx-x86",
|
||||
expectedName: "build-wrapper-macosx-x86",
|
||||
},
|
||||
{
|
||||
platform: "macOS",
|
||||
arch: "ARM64",
|
||||
expectedSuffix: "macosx-x86",
|
||||
expectedName: "build-wrapper-macosx-x86",
|
||||
},
|
||||
];
|
||||
|
||||
const unsupportedPlatforms = [
|
||||
{ platform: "linux", arch: "arm" },
|
||||
{ platform: "openbsd", arch: "X64" },
|
||||
{ platform: undefined, arch: "X64" },
|
||||
{ platform: "Linux", arch: undefined },
|
||||
{ platform: null, arch: "X64" },
|
||||
{ platform: "Linux", arch: null },
|
||||
];
|
||||
|
||||
supportedPlatforms.forEach(
|
||||
({ platform, arch, expectedSuffix, expectedName }) => {
|
||||
it(`returns ${expectedName} for ${platform} ${arch}`, () => {
|
||||
const result = getBuildWrapperInfo({
|
||||
runnerOS: platform,
|
||||
runnerArch: arch,
|
||||
runnerTemp: "/tmp",
|
||||
sonarHostUrl: "https://sonarcloud.io"
|
||||
});
|
||||
assert.equal(result.buildWrapperUrl, `https://sonarcloud.io/static/cpp/build-wrapper-${expectedSuffix}.zip`);
|
||||
assert.equal(result.buildWrapperDir, `/tmp/build-wrapper-${expectedSuffix}`);
|
||||
assert.equal(result.buildWrapperBin, `/tmp/build-wrapper-${expectedSuffix}/${expectedName}`);
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
unsupportedPlatforms.forEach(({ platform, arch }) => {
|
||||
it(`throws for unsupported platform ${platform} ${arch}`, () => {
|
||||
assert.throws(
|
||||
() => getBuildWrapperInfo({
|
||||
runnerOS: platform,
|
||||
runnerArch: arch,
|
||||
runnerTemp: "/tmp",
|
||||
sonarHostUrl: "https://sonarcloud.io"
|
||||
}),
|
||||
(error) => {
|
||||
return error.message.includes('unsupported') || error.message.includes('Unsupported');
|
||||
},
|
||||
`should have thrown for ${platform} ${arch}`
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
85
src/install-build-wrapper/install-build-wrapper.js
Normal file
85
src/install-build-wrapper/install-build-wrapper.js
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
import * as core from "@actions/core";
|
||||
import * as exec from "@actions/exec";
|
||||
import * as fs from "fs";
|
||||
import * as path from "path";
|
||||
import { getBuildWrapperInfo, getRealPath } from "./utils";
|
||||
|
||||
async function installMacOSPackages() {
|
||||
if (process.platform === "darwin") {
|
||||
core.info("Installing required packages for macOS");
|
||||
await exec.exec("brew", ["install", "coreutils"]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* These RUNNER_XX env variables come from GitHub by default.
|
||||
* See https://docs.github.com/en/actions/reference/workflows-and-actions/variables#default-environment-variables
|
||||
*
|
||||
* If SONAR_HOST_URL is omitted, we assume sonarcloud.io
|
||||
*/
|
||||
function getEnvVariables() {
|
||||
const sonarHostUrl = process.env.SONAR_HOST_URL
|
||||
? process.env.SONAR_HOST_URL.replace(/\/$/, "")
|
||||
: "https://sonarcloud.io";
|
||||
|
||||
return {
|
||||
runnerOS: process.env.RUNNER_OS,
|
||||
runnerArch: process.env.RUNNER_ARCH,
|
||||
runnerTemp: process.env.RUNNER_TEMP,
|
||||
sonarHostUrl,
|
||||
};
|
||||
}
|
||||
|
||||
async function downloadAndInstallBuildWrapper(downloadUrl, runnerEnv) {
|
||||
const { runnerArch, runnerOS, runnerTemp } = runnerEnv;
|
||||
const tmpZipPath = path.join(
|
||||
runnerTemp,
|
||||
`build-wrapper-${runnerOS}-${runnerArch}.zip`
|
||||
);
|
||||
|
||||
core.startGroup(`Download ${downloadUrl}`);
|
||||
|
||||
core.info(`Downloading '${downloadUrl}'`);
|
||||
|
||||
if (!fs.existsSync(runnerTemp)) {
|
||||
fs.mkdirSync(runnerTemp, { recursive: true });
|
||||
}
|
||||
|
||||
await exec.exec("curl", ["-sSLo", tmpZipPath, downloadUrl]);
|
||||
|
||||
core.info("Decompressing");
|
||||
await exec.exec("unzip", ["-o", "-d", runnerTemp, tmpZipPath]);
|
||||
|
||||
core.endGroup();
|
||||
}
|
||||
|
||||
async function run() {
|
||||
try {
|
||||
await installMacOSPackages();
|
||||
|
||||
const envVariables = getEnvVariables();
|
||||
|
||||
const { buildWrapperBin, buildWrapperDir, buildWrapperUrl } =
|
||||
getBuildWrapperInfo(envVariables);
|
||||
|
||||
await downloadAndInstallBuildWrapper(buildWrapperUrl, envVariables);
|
||||
|
||||
const buildWrapperBinDir = await getRealPath(
|
||||
buildWrapperDir,
|
||||
envVariables.runnerOS
|
||||
);
|
||||
core.addPath(buildWrapperBinDir);
|
||||
core.info(`'${buildWrapperBinDir}' added to the path`);
|
||||
|
||||
const buildWrapperBinPath = await getRealPath(
|
||||
buildWrapperBin,
|
||||
envVariables.runnerOS
|
||||
);
|
||||
core.setOutput("build-wrapper-binary", buildWrapperBinPath);
|
||||
core.info(`'build-wrapper-binary' output set to '${buildWrapperBinPath}'`);
|
||||
} catch (error) {
|
||||
core.setFailed(error.message);
|
||||
}
|
||||
}
|
||||
|
||||
run();
|
||||
98
src/install-build-wrapper/utils.js
Normal file
98
src/install-build-wrapper/utils.js
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
import * as exec from "@actions/exec";
|
||||
import * as path from "path";
|
||||
|
||||
/**
|
||||
* Compute all names and paths related to the build wrapper
|
||||
* based on the runner environment
|
||||
*/
|
||||
export function getBuildWrapperInfo({
|
||||
runnerOS,
|
||||
runnerArch,
|
||||
runnerTemp,
|
||||
sonarHostUrl,
|
||||
}) {
|
||||
const { buildWrapperSuffix, buildWrapperName } = getSuffixAndName(
|
||||
runnerOS,
|
||||
runnerArch
|
||||
);
|
||||
|
||||
const buildWrapperDir = `${runnerTemp}/build-wrapper-${buildWrapperSuffix}`;
|
||||
const buildWrapperUrl = `${sonarHostUrl}/static/cpp/build-wrapper-${buildWrapperSuffix}.zip`;
|
||||
const buildWrapperBin = `${buildWrapperDir}/${buildWrapperName}`;
|
||||
|
||||
return {
|
||||
buildWrapperUrl,
|
||||
buildWrapperDir,
|
||||
buildWrapperBin,
|
||||
};
|
||||
}
|
||||
|
||||
function getSuffixAndName(runnerOS, runnerArch) {
|
||||
if (
|
||||
runnerArch !== "X64" &&
|
||||
!(runnerArch === "ARM64" && (runnerOS === "macOS" || runnerOS === "Linux"))
|
||||
) {
|
||||
throw new Error(
|
||||
`Architecture '${runnerArch}' is unsupported by build-wrapper`
|
||||
);
|
||||
}
|
||||
|
||||
switch (runnerOS) {
|
||||
case "Windows":
|
||||
return {
|
||||
buildWrapperSuffix: "win-x86",
|
||||
buildWrapperName: "build-wrapper-win-x86-64.exe",
|
||||
};
|
||||
|
||||
case "Linux":
|
||||
switch (runnerArch) {
|
||||
case "X64":
|
||||
return {
|
||||
buildWrapperSuffix: "linux-x86",
|
||||
buildWrapperName: "build-wrapper-linux-x86-64",
|
||||
};
|
||||
|
||||
case "ARM64":
|
||||
return {
|
||||
buildWrapperSuffix: "linux-aarch64",
|
||||
buildWrapperName: "build-wrapper-linux-aarch64",
|
||||
};
|
||||
}
|
||||
break; // handled before the switch
|
||||
|
||||
case "macOS":
|
||||
return {
|
||||
buildWrapperSuffix: "macosx-x86",
|
||||
buildWrapperName: "build-wrapper-macosx-x86",
|
||||
};
|
||||
|
||||
default:
|
||||
throw new Error(`Unsupported runner OS '${runnerOS}'`);
|
||||
}
|
||||
}
|
||||
|
||||
export async function getRealPath(filePath, runnerOS) {
|
||||
switch (runnerOS) {
|
||||
case "Windows": {
|
||||
const windowsResult = await exec.getExecOutput("cygpath", [
|
||||
"--absolute",
|
||||
"--windows",
|
||||
filePath,
|
||||
]);
|
||||
return windowsResult.stdout.trim();
|
||||
}
|
||||
case "Linux": {
|
||||
const linuxResult = await exec.getExecOutput("readlink", [
|
||||
"-f",
|
||||
filePath,
|
||||
]);
|
||||
return linuxResult.stdout.trim();
|
||||
}
|
||||
case "macOS": {
|
||||
const macResult = await exec.getExecOutput("greadlink", ["-f", filePath]);
|
||||
return macResult.stdout.trim();
|
||||
}
|
||||
default:
|
||||
return path.resolve(filePath);
|
||||
}
|
||||
}
|
||||
7
src/main/__tests__/mocks.js
Normal file
7
src/main/__tests__/mocks.js
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
export function mockCore(overrides = {}) {
|
||||
return {
|
||||
setFailed: (msg) => console.error(msg),
|
||||
warning: (msg) => console.log(msg),
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
177
src/main/__tests__/sanity-checks.test.js
Normal file
177
src/main/__tests__/sanity-checks.test.js
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
import mockfs from "mock-fs";
|
||||
import assert from "node:assert/strict";
|
||||
import { describe, it, mock } from "node:test";
|
||||
import {
|
||||
checkGradleProject,
|
||||
checkMavenProject,
|
||||
checkSonarToken,
|
||||
validateScannerVersion,
|
||||
} from "../sanity-checks.js";
|
||||
import { mockCore } from "./mocks.js";
|
||||
|
||||
describe("validateScannerVersion", () => {
|
||||
const expected =
|
||||
"Invalid scannerVersion format. Expected format: x.y.z.w (e.g., 7.1.0.4889)";
|
||||
|
||||
const validVersions = [undefined, "", "7.1.0.4889", "1.2.3.4"];
|
||||
|
||||
const invalidVersions = [
|
||||
"wrong",
|
||||
"4.2.",
|
||||
"7.1.0",
|
||||
"7.1.0.abc",
|
||||
"7.1.0.4889.5",
|
||||
"7.1",
|
||||
"7",
|
||||
"7.1.0.",
|
||||
".7.1.0.4889",
|
||||
"7..1.0.4889",
|
||||
"7.1..0.4889",
|
||||
"7.1.0..4889",
|
||||
"a.b.c.d",
|
||||
"7.1.0.4889-SNAPSHOT",
|
||||
"v7.1.0.4889",
|
||||
"7.1.0.4889.0.0",
|
||||
"-7.1.0.4889",
|
||||
"7.-1.0.4889",
|
||||
"7.1.-0.4889",
|
||||
"7.1.0.-4889",
|
||||
"7.1.0.4889 ",
|
||||
" 7.1.0.4889",
|
||||
"7.1.0.4889\n",
|
||||
"7,1,0,4889",
|
||||
];
|
||||
|
||||
validVersions.forEach((version) => {
|
||||
it(`accepts ${version}`, () => {
|
||||
assert.equal(validateScannerVersion(version), undefined);
|
||||
});
|
||||
});
|
||||
|
||||
invalidVersions.forEach((version) =>
|
||||
it(`throws for ${version}`, () => {
|
||||
assert.throws(
|
||||
() => validateScannerVersion(version),
|
||||
{
|
||||
message: expected,
|
||||
},
|
||||
`should have thrown for ${version}`
|
||||
);
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
describe("checkSonarToken", () => {
|
||||
it("calls core.warning when SONAR_TOKEN is not set", () => {
|
||||
const warning = mock.fn();
|
||||
|
||||
checkSonarToken(mockCore({ warning }));
|
||||
|
||||
assert.equal(warning.mock.calls.length, 1);
|
||||
assert.equal(
|
||||
warning.mock.calls[0].arguments[0],
|
||||
"Running this GitHub Action without SONAR_TOKEN is not recommended"
|
||||
);
|
||||
});
|
||||
|
||||
it("does not call core.warning when SONAR_TOKEN is set", () => {
|
||||
const warning = mock.fn();
|
||||
|
||||
checkSonarToken(mockCore({ warning }), "test-token");
|
||||
|
||||
assert.equal(warning.mock.calls.length, 0);
|
||||
});
|
||||
});
|
||||
|
||||
describe("checkMavenProject", () => {
|
||||
it("calls core.warning when pom.xml exists", async () => {
|
||||
mockfs({ "/test/project/": { "pom.xml": "" } });
|
||||
const warning = mock.fn();
|
||||
|
||||
checkMavenProject({ warning }, "/test/project");
|
||||
|
||||
assert.equal(warning.mock.calls.length, 1);
|
||||
assert.equal(
|
||||
warning.mock.calls[0].arguments[0],
|
||||
"Maven project detected. Sonar recommends running the 'org.sonarsource.scanner.maven:sonar-maven-plugin:sonar' goal during the build process instead of using this GitHub Action to get more accurate results."
|
||||
);
|
||||
|
||||
mockfs.restore();
|
||||
});
|
||||
|
||||
it("does not call core.warning when pom.xml does not exist", async () => {
|
||||
mockfs({ "/test/project/": {} });
|
||||
const warning = mock.fn();
|
||||
|
||||
checkMavenProject(mockCore({ warning }), "/test/project");
|
||||
|
||||
assert.equal(warning.mock.calls.length, 0);
|
||||
|
||||
mockfs.restore();
|
||||
});
|
||||
|
||||
it("handles project base dir with trailing slash", async () => {
|
||||
mockfs({ "/test/project/": { "pom.xml": "" } });
|
||||
const warning = mock.fn();
|
||||
|
||||
checkMavenProject(mockCore({ warning }), "/test/project/");
|
||||
assert.equal(warning.mock.calls.length, 1);
|
||||
|
||||
mockfs.restore();
|
||||
});
|
||||
});
|
||||
|
||||
describe("checkGradleProject", () => {
|
||||
it("calls core.warning when build.gradle exists", async () => {
|
||||
mockfs({ "/test/project/": { "build.gradle": "" } });
|
||||
|
||||
const warning = mock.fn();
|
||||
|
||||
checkGradleProject(mockCore({ warning }), "/test/project");
|
||||
|
||||
assert.equal(warning.mock.calls.length, 1);
|
||||
assert.equal(
|
||||
warning.mock.calls[0].arguments[0],
|
||||
"Gradle project detected. Sonar recommends using the SonarQube plugin for Gradle during the build process instead of using this GitHub Action to get more accurate results."
|
||||
);
|
||||
|
||||
mockfs.restore();
|
||||
});
|
||||
|
||||
it("calls core.warning when build.gradle.kts exists", async () => {
|
||||
mockfs({ "/test/project/": { "build.gradle.kts": "" } });
|
||||
|
||||
const warning = mock.fn();
|
||||
|
||||
checkGradleProject(mockCore({ warning }), "/test/project");
|
||||
|
||||
assert.equal(warning.mock.calls.length, 1);
|
||||
assert.equal(
|
||||
warning.mock.calls[0].arguments[0],
|
||||
"Gradle project detected. Sonar recommends using the SonarQube plugin for Gradle during the build process instead of using this GitHub Action to get more accurate results."
|
||||
);
|
||||
|
||||
mockfs.restore();
|
||||
});
|
||||
|
||||
it("does not call core.warning when neither gradle file exists", async () => {
|
||||
mockfs({ "/test/project/": {} });
|
||||
|
||||
const warning = mock.fn();
|
||||
|
||||
checkGradleProject(mockCore({ warning }), "/test/project");
|
||||
|
||||
assert.equal(warning.mock.calls.length, 0);
|
||||
|
||||
mockfs.restore();
|
||||
});
|
||||
|
||||
it("handles project base dir with trailing slash", async () => {
|
||||
mockfs({ "/test/project/": { "build.gradle": "" } });
|
||||
const warning = mock.fn();
|
||||
|
||||
checkGradleProject(mockCore({ warning }), "/test/project/");
|
||||
|
||||
assert.equal(warning.mock.calls.length, 1);
|
||||
});
|
||||
});
|
||||
81
src/main/__tests__/utils.test.js
Normal file
81
src/main/__tests__/utils.test.js
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
import assert from "node:assert/strict";
|
||||
import { describe, it } from "node:test";
|
||||
import {
|
||||
getPlatformFlavor,
|
||||
getScannerDownloadURL,
|
||||
scannerDirName,
|
||||
} from "../utils.js";
|
||||
|
||||
describe("getPlatformFlavor", () => {
|
||||
const supportedPlatforms = [
|
||||
{ platform: "linux", arch: "x64", expected: "linux-x64" },
|
||||
{ platform: "linux", arch: "arm64", expected: "linux-aarch64" },
|
||||
{ platform: "win32", arch: "x64", expected: "windows-x64" },
|
||||
{ platform: "darwin", arch: "x64", expected: "macosx-x64" },
|
||||
{ platform: "darwin", arch: "arm64", expected: "macosx-aarch64" },
|
||||
];
|
||||
|
||||
const unsupportedPlatforms = [
|
||||
{ platform: "linux", arch: "arm" },
|
||||
{ platform: "openbsd", arch: "x64" },
|
||||
{ platform: undefined, arch: "x64" },
|
||||
{ platform: "linux", arch: undefined },
|
||||
{ platform: null, arch: "x64" },
|
||||
{ platform: "linux", arch: null },
|
||||
];
|
||||
|
||||
supportedPlatforms.forEach(({ platform, arch, expected }) => {
|
||||
it(`returns ${expected} for ${platform} ${arch}`, () => {
|
||||
assert.equal(getPlatformFlavor(platform, arch), expected);
|
||||
});
|
||||
});
|
||||
|
||||
unsupportedPlatforms.forEach(({ platform, arch }) => {
|
||||
it(`throws for unsupported platform ${platform} ${arch}`, () => {
|
||||
assert.throws(
|
||||
() => getPlatformFlavor(platform, arch),
|
||||
{
|
||||
message: `Platform ${platform} ${arch} not supported`,
|
||||
},
|
||||
`should have thrown for ${platform} ${arch}`
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("getScannerDownloadURL", () => {
|
||||
it("generates correct URL without trailing slash", () => {
|
||||
const result = getScannerDownloadURL({
|
||||
scannerBinariesUrl:
|
||||
"https://binaries.sonarsource.com/Distribution/sonar-scanner-cli",
|
||||
scannerVersion: "7.2.0.5079",
|
||||
flavor: "linux-x64",
|
||||
});
|
||||
assert.equal(
|
||||
result,
|
||||
"https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-7.2.0.5079-linux-x64.zip"
|
||||
);
|
||||
});
|
||||
|
||||
it("generates correct URL with trailing slash", () => {
|
||||
const result = getScannerDownloadURL({
|
||||
scannerBinariesUrl:
|
||||
"https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/",
|
||||
scannerVersion: "7.2.0.5079",
|
||||
flavor: "linux-x64",
|
||||
});
|
||||
assert.equal(
|
||||
result,
|
||||
"https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-7.2.0.5079-linux-x64.zip"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("scannerDirName", () => {
|
||||
it("handles special characters", () => {
|
||||
assert.equal(
|
||||
scannerDirName("7.2.0-SNAPSHOT", "linux_x64"),
|
||||
"sonar-scanner-7.2.0-SNAPSHOT-linux_x64"
|
||||
);
|
||||
});
|
||||
});
|
||||
75
src/main/index.js
Normal file
75
src/main/index.js
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
import * as core from "@actions/core";
|
||||
import { installSonarScanner } from "./install-sonar-scanner";
|
||||
import { runSonarScanner } from "./run-sonar-scanner";
|
||||
import {
|
||||
checkGradleProject,
|
||||
checkMavenProject,
|
||||
checkSonarToken,
|
||||
validateScannerVersion,
|
||||
} from "./sanity-checks";
|
||||
|
||||
/**
|
||||
* Inputs are defined in action.yml
|
||||
*/
|
||||
function getInputs() {
|
||||
const args = core.getInput("args");
|
||||
const projectBaseDir = core.getInput("projectBaseDir");
|
||||
const scannerBinariesUrl = core.getInput("scannerBinariesUrl");
|
||||
const scannerVersion = core.getInput("scannerVersion");
|
||||
|
||||
return { args, projectBaseDir, scannerBinariesUrl, scannerVersion };
|
||||
}
|
||||
|
||||
/**
|
||||
* These RUNNER env variables come from GitHub by default.
|
||||
* See https://docs.github.com/en/actions/reference/workflows-and-actions/variables#default-environment-variables
|
||||
*
|
||||
* The others are optional env variables provided by the user of the action
|
||||
*/
|
||||
function getEnvVariables() {
|
||||
return {
|
||||
runnerDebug: process.env.RUNNER_DEBUG,
|
||||
runnerOs: process.env.RUNNER_OS,
|
||||
runnerTemp: process.env.RUNNER_TEMP,
|
||||
sonarRootCert: process.env.SONAR_ROOT_CERT,
|
||||
sonarcloudUrl: process.env.SONARCLOUD_URL,
|
||||
sonarToken: process.env.SONAR_TOKEN,
|
||||
};
|
||||
}
|
||||
|
||||
function runSanityChecks(inputs) {
|
||||
try {
|
||||
const { projectBaseDir, scannerVersion, sonarToken } = inputs;
|
||||
|
||||
validateScannerVersion(scannerVersion);
|
||||
checkSonarToken(core, sonarToken);
|
||||
checkMavenProject(core, projectBaseDir);
|
||||
checkGradleProject(core, projectBaseDir);
|
||||
} catch (error) {
|
||||
core.setFailed(`Sanity checks failed: ${error.message}`);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
async function run() {
|
||||
try {
|
||||
const { args, projectBaseDir, scannerVersion, scannerBinariesUrl } =
|
||||
getInputs();
|
||||
const runnerEnv = getEnvVariables();
|
||||
const { sonarToken } = runnerEnv;
|
||||
|
||||
runSanityChecks({ projectBaseDir, scannerVersion, sonarToken });
|
||||
|
||||
const scannerDir = await installSonarScanner({
|
||||
scannerVersion,
|
||||
scannerBinariesUrl,
|
||||
});
|
||||
|
||||
await runSonarScanner(args, projectBaseDir, scannerDir, runnerEnv);
|
||||
} catch (error) {
|
||||
core.setFailed(`Action failed: ${error.message}`);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
run();
|
||||
59
src/main/install-sonar-scanner.js
Normal file
59
src/main/install-sonar-scanner.js
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
import * as core from "@actions/core";
|
||||
import * as tc from "@actions/tool-cache";
|
||||
import * as os from "os";
|
||||
import * as path from "path";
|
||||
import {
|
||||
getPlatformFlavor,
|
||||
getScannerDownloadURL,
|
||||
scannerDirName,
|
||||
} from "./utils";
|
||||
|
||||
const TOOLNAME = "sonar-scanner-cli";
|
||||
|
||||
/**
|
||||
* Download the Sonar Scanner CLI for the current environment and cache it.
|
||||
*/
|
||||
export async function installSonarScanner({
|
||||
scannerVersion,
|
||||
scannerBinariesUrl,
|
||||
}) {
|
||||
const flavor = getPlatformFlavor(os.platform(), os.arch());
|
||||
|
||||
// Check if tool is already cached
|
||||
let toolDir = tc.find(TOOLNAME, scannerVersion, flavor);
|
||||
|
||||
if (!toolDir) {
|
||||
core.info(
|
||||
`Installing Sonar Scanner CLI ${scannerVersion} for ${flavor}...`
|
||||
);
|
||||
|
||||
const downloadUrl = getScannerDownloadURL({
|
||||
scannerBinariesUrl,
|
||||
scannerVersion,
|
||||
flavor,
|
||||
});
|
||||
|
||||
core.info(`Downloading from: ${downloadUrl}`);
|
||||
|
||||
const downloadPath = await tc.downloadTool(downloadUrl);
|
||||
const extractedPath = await tc.extractZip(downloadPath);
|
||||
|
||||
// Find the actual scanner directory inside the extracted folder
|
||||
const scannerPath = path.join(
|
||||
extractedPath,
|
||||
scannerDirName(scannerVersion, flavor)
|
||||
);
|
||||
|
||||
toolDir = await tc.cacheDir(scannerPath, TOOLNAME, scannerVersion, flavor);
|
||||
|
||||
core.info(`Sonar Scanner CLI cached to: ${toolDir}`);
|
||||
} else {
|
||||
core.info(`Using cached Sonar Scanner CLI from: ${toolDir}`);
|
||||
}
|
||||
|
||||
// Add the bin directory to PATH
|
||||
const binDir = path.join(toolDir, "bin");
|
||||
core.addPath(binDir);
|
||||
|
||||
return toolDir;
|
||||
}
|
||||
152
src/main/run-sonar-scanner.js
Normal file
152
src/main/run-sonar-scanner.js
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
import * as core from "@actions/core";
|
||||
import * as exec from "@actions/exec";
|
||||
import * as fs from "fs";
|
||||
import * as os from "os";
|
||||
import * as path from "path";
|
||||
import { parseArgsStringToArgv } from "string-argv";
|
||||
|
||||
const KEYTOOL_MAIN_CLASS = "sun.security.tools.keytool.Main";
|
||||
const TRUSTSTORE_PASSWORD = "changeit"; // default password of the Java truststore!
|
||||
|
||||
export async function runSonarScanner(
|
||||
inputArgs,
|
||||
projectBaseDir,
|
||||
scannerDir,
|
||||
runnerEnv = {}
|
||||
) {
|
||||
const { runnerDebug, runnerOs, runnerTemp, sonarRootCert, sonarcloudUrl } =
|
||||
runnerEnv;
|
||||
|
||||
const scannerBin =
|
||||
runnerOs === "Windows" ? "sonar-scanner.bat" : "sonar-scanner";
|
||||
|
||||
const scannerArgs = [];
|
||||
|
||||
/**
|
||||
* Not sanitization is needed when populating scannerArgs.
|
||||
* @actions/exec will take care of sanitizing the args it receives.
|
||||
*/
|
||||
|
||||
if (sonarcloudUrl) {
|
||||
scannerArgs.push(`-Dsonar.scanner.sonarcloudUrl=${sonarcloudUrl}`);
|
||||
}
|
||||
|
||||
if (runnerDebug === "1") {
|
||||
scannerArgs.push("--debug");
|
||||
}
|
||||
|
||||
if (projectBaseDir) {
|
||||
scannerArgs.push(`-Dsonar.projectBaseDir=${projectBaseDir}`);
|
||||
}
|
||||
|
||||
// The SSL folder may exist on an uncleaned self-hosted runner
|
||||
const sslFolder = path.join(os.homedir(), ".sonar", "ssl");
|
||||
const truststoreFile = path.join(sslFolder, "truststore.p12");
|
||||
|
||||
const keytoolParams = {
|
||||
scannerDir,
|
||||
truststoreFile,
|
||||
};
|
||||
|
||||
if (fs.existsSync(truststoreFile)) {
|
||||
let aliasSonarIsPresent = true;
|
||||
|
||||
try {
|
||||
await checkSonarAliasInTruststore(keytoolParams);
|
||||
} catch (_) {
|
||||
aliasSonarIsPresent = false;
|
||||
core.info(
|
||||
`Existing Scanner truststore ${truststoreFile} does not contain 'sonar' alias`
|
||||
);
|
||||
}
|
||||
|
||||
if (aliasSonarIsPresent) {
|
||||
core.info(
|
||||
`Removing 'sonar' alias from already existing Scanner truststore: ${truststoreFile}`
|
||||
);
|
||||
await deleteSonarAliasFromTruststore(keytoolParams);
|
||||
}
|
||||
}
|
||||
|
||||
if (sonarRootCert) {
|
||||
core.info("Adding SSL certificate to the Scanner truststore");
|
||||
const tempCertPath = path.join(runnerTemp, "tmpcert.pem");
|
||||
|
||||
try {
|
||||
fs.unlinkSync(tempCertPath);
|
||||
} catch (_) {
|
||||
// File doesn't exist, ignore
|
||||
}
|
||||
|
||||
fs.writeFileSync(tempCertPath, sonarRootCert);
|
||||
fs.mkdirSync(sslFolder, { recursive: true });
|
||||
|
||||
await importCertificateToTruststore(keytoolParams, tempCertPath);
|
||||
|
||||
scannerArgs.push(
|
||||
`-Dsonar.scanner.truststorePassword=${TRUSTSTORE_PASSWORD}`
|
||||
);
|
||||
}
|
||||
|
||||
if (inputArgs) {
|
||||
/**
|
||||
* No sanitization, but it is parsing a string into an array of arguments in a safe way (= no command execution),
|
||||
* and with good enough support of quotes to support arguments containing spaces.
|
||||
*/
|
||||
const args = parseArgsStringToArgv(inputArgs);
|
||||
scannerArgs.push(...args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Arguments are sanitized by `exec`
|
||||
*/
|
||||
await exec.exec(scannerBin, scannerArgs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use keytool for now, as SonarQube 10.6 and below doesn't support openssl generated keystores
|
||||
* keytool requires a password > 6 characters, so we won't use the default password 'sonar'
|
||||
*/
|
||||
function executeKeytoolCommand({
|
||||
scannerDir,
|
||||
truststoreFile,
|
||||
extraArgs,
|
||||
options = {},
|
||||
}) {
|
||||
const baseArgs = [
|
||||
KEYTOOL_MAIN_CLASS,
|
||||
"-storetype",
|
||||
"PKCS12",
|
||||
"-keystore",
|
||||
truststoreFile,
|
||||
"-storepass",
|
||||
TRUSTSTORE_PASSWORD,
|
||||
"-noprompt",
|
||||
"-trustcacerts",
|
||||
...extraArgs,
|
||||
];
|
||||
|
||||
return exec.exec(`${scannerDir}/jre/bin/java`, baseArgs, options);
|
||||
}
|
||||
|
||||
function importCertificateToTruststore(keytoolParams, certPath) {
|
||||
return executeKeytoolCommand({
|
||||
...keytoolParams,
|
||||
extraArgs: ["-importcert", "-alias", "sonar", "-file", certPath],
|
||||
});
|
||||
}
|
||||
|
||||
function checkSonarAliasInTruststore(keytoolParams) {
|
||||
return executeKeytoolCommand({
|
||||
...keytoolParams,
|
||||
extraArgs: ["-list", "-v", "-alias", "sonar"],
|
||||
options: { silent: true },
|
||||
});
|
||||
}
|
||||
|
||||
function deleteSonarAliasFromTruststore(keytoolParams) {
|
||||
return executeKeytoolCommand({
|
||||
...keytoolParams,
|
||||
extraArgs: ["-delete", "-alias", "sonar"],
|
||||
});
|
||||
}
|
||||
44
src/main/sanity-checks.js
Normal file
44
src/main/sanity-checks.js
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
import fs from "fs";
|
||||
import { join } from "path";
|
||||
|
||||
export function validateScannerVersion(version) {
|
||||
if (!version) {
|
||||
return;
|
||||
}
|
||||
|
||||
const versionRegex = /^\d+\.\d+\.\d+\.\d+$/;
|
||||
if (!versionRegex.test(version)) {
|
||||
throw new Error(
|
||||
"Invalid scannerVersion format. Expected format: x.y.z.w (e.g., 7.1.0.4889)"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export function checkSonarToken(core, sonarToken) {
|
||||
if (!sonarToken) {
|
||||
core.warning(
|
||||
"Running this GitHub Action without SONAR_TOKEN is not recommended"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export function checkMavenProject(core, projectBaseDir) {
|
||||
const pomPath = join(projectBaseDir.replace(/\/$/, ""), "pom.xml");
|
||||
if (fs.existsSync(pomPath)) {
|
||||
core.warning(
|
||||
"Maven project detected. Sonar recommends running the 'org.sonarsource.scanner.maven:sonar-maven-plugin:sonar' goal during the build process instead of using this GitHub Action to get more accurate results."
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export function checkGradleProject(core, projectBaseDir) {
|
||||
const baseDir = projectBaseDir.replace(/\/$/, "");
|
||||
const gradlePath = join(baseDir, "build.gradle");
|
||||
const gradleKtsPath = join(baseDir, "build.gradle.kts");
|
||||
|
||||
if (fs.existsSync(gradlePath) || fs.existsSync(gradleKtsPath)) {
|
||||
core.warning(
|
||||
"Gradle project detected. Sonar recommends using the SonarQube plugin for Gradle during the build process instead of using this GitHub Action to get more accurate results."
|
||||
);
|
||||
}
|
||||
}
|
||||
35
src/main/utils.js
Normal file
35
src/main/utils.js
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
const platformFlavor = {
|
||||
linux: {
|
||||
x64: "linux-x64",
|
||||
arm64: "linux-aarch64",
|
||||
},
|
||||
win32: {
|
||||
x64: "windows-x64",
|
||||
},
|
||||
darwin: {
|
||||
x64: "macosx-x64",
|
||||
arm64: "macosx-aarch64",
|
||||
},
|
||||
};
|
||||
|
||||
export function getPlatformFlavor(platform, arch) {
|
||||
const flavor = platformFlavor[platform]?.[arch];
|
||||
|
||||
if (!flavor) {
|
||||
throw new Error(`Platform ${platform} ${arch} not supported`);
|
||||
}
|
||||
|
||||
return flavor;
|
||||
}
|
||||
|
||||
export function getScannerDownloadURL({
|
||||
scannerBinariesUrl,
|
||||
scannerVersion,
|
||||
flavor,
|
||||
}) {
|
||||
const trimURL = scannerBinariesUrl.replace(/\/$/, "");
|
||||
return `${trimURL}/sonar-scanner-cli-${scannerVersion}-${flavor}.zip`;
|
||||
}
|
||||
|
||||
export const scannerDirName = (version, flavor) =>
|
||||
`sonar-scanner-${version}-${flavor}`;
|
||||
14
test/assertFileContains
Executable file
14
test/assertFileContains
Executable file
|
|
@ -0,0 +1,14 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -eou pipefail
|
||||
|
||||
error() { echo -e "\\e[31mâś— $*\\e[0m"; }
|
||||
|
||||
scriptDir=$(dirname -- "$(readlink -f -- "${BASH_SOURCE[0]}")")
|
||||
|
||||
$scriptDir/assertFileExists "$1"
|
||||
|
||||
if ! grep -q "$2" "$1"; then
|
||||
error "'$2' not found in '$1'"
|
||||
exit 1
|
||||
fi
|
||||
10
test/assertFileDoesntExist
Executable file
10
test/assertFileDoesntExist
Executable file
|
|
@ -0,0 +1,10 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -eou pipefail
|
||||
|
||||
error() { echo -e "\\e[31mâś— $*\\e[0m"; }
|
||||
|
||||
if [ -f "$1" ]; then
|
||||
error "File '$1' found"
|
||||
exit 1
|
||||
fi
|
||||
10
test/assertFileExists
Executable file
10
test/assertFileExists
Executable file
|
|
@ -0,0 +1,10 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -eou pipefail
|
||||
|
||||
error() { echo -e "\\e[31mâś— $*\\e[0m"; }
|
||||
|
||||
if [ ! -f "$1" ]; then
|
||||
error "File '$1' not found"
|
||||
exit 1
|
||||
fi
|
||||
0
test/gradle-project-kotlin/build.gradle.kts
Normal file
0
test/gradle-project-kotlin/build.gradle.kts
Normal file
104
test/run-qa.sh
104
test/run-qa.sh
|
|
@ -1,104 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Helper functions for coloring output.
|
||||
info() { echo -e "\\e[36m$*\\e[0m"; }
|
||||
error() { echo -e "\\e[31mâś— $*\\e[0m"; }
|
||||
success() { echo -e "\\e[32mâś” $*\\e[0m"; }
|
||||
|
||||
# Helper function to check if SonarQube is up and running.
|
||||
check_sq_is_up() {
|
||||
local statusCall="$(curl --silent --user admin:admin http://127.0.0.1:9000/api/system/status)"
|
||||
local status="$(jq -r '.status' <<< "$statusCall")"
|
||||
if [[ ! $? -eq 0 ]]; then
|
||||
error "Failed to check if SonarQube is up and running."
|
||||
exit 1
|
||||
fi
|
||||
echo $status;
|
||||
}
|
||||
|
||||
info "Build scanner action..."
|
||||
docker build --no-cache -t sonarsource/sonarqube-scan-action .
|
||||
if [[ ! $? -eq 0 ]]; then
|
||||
error "Failed to build the scanner action."
|
||||
exit 1
|
||||
fi
|
||||
success "Scanner action built."
|
||||
|
||||
info "Find the network SonarQube is running on..."
|
||||
network=$(docker network ls -f 'name=github_network' --format "{{.Name}}")
|
||||
if [[ $network != "github_network_"* ]]; then
|
||||
error "Failed to find the local Docker network."
|
||||
exit 1
|
||||
fi
|
||||
success "Found the network ($network)."
|
||||
|
||||
info "Wait until SonarQube is up..."
|
||||
sleep 10
|
||||
isUp=$(check_sq_is_up)
|
||||
until [[ "$isUp" == "UP" ]]; do
|
||||
sleep 1
|
||||
isUp=$(check_sq_is_up)
|
||||
done
|
||||
success "SonarQube is up and running."
|
||||
|
||||
info "Generate a new token..."
|
||||
tokenCall=$(curl --silent --user admin:admin -d "name=token" http://127.0.0.1:9000/api/user_tokens/generate)
|
||||
token="$(jq -r '.token' <<< "$tokenCall")"
|
||||
if [[ -z "$token" ]]; then
|
||||
error "Failed to generate a new token."
|
||||
exit 1
|
||||
fi
|
||||
success "New token generated."
|
||||
|
||||
info "Test fail-fast if SONAR_TOKEN is omitted..."
|
||||
docker run -v `pwd`:/github/workspace/ --workdir /github/workspace --network $network sonarsource/sonarqube-scan-action
|
||||
if [[ $? -eq 0 ]]; then
|
||||
error "Should have failed fast."
|
||||
exit 1
|
||||
fi
|
||||
success "Correctly failed fast."
|
||||
|
||||
info "Test fail-fast if SONAR_HOST_URL is omitted..."
|
||||
docker run -v `pwd`:/github/workspace/ --workdir /github/workspace --network $network --env SONAR_TOKEN=$token sonarsource/sonarqube-scan-action
|
||||
if [[ $? -eq 0 ]]; then
|
||||
error "Should have failed fast."
|
||||
exit 1
|
||||
fi
|
||||
success "Correctly failed fast."
|
||||
|
||||
info "Test fail-fast on Gradle project..."
|
||||
pushd test/gradle-project/
|
||||
docker run -v `pwd`:/github/workspace/ --workdir /github/workspace --network $network --env SONAR_TOKEN=$token --env SONAR_HOST_URL='http://sonarqube:9000' sonarsource/sonarqube-scan-action
|
||||
if [[ $? -eq 0 ]]; then
|
||||
error "Should have failed fast."
|
||||
exit 1
|
||||
fi
|
||||
popd
|
||||
success "Correctly failed fast."
|
||||
|
||||
info "Test fail-fast on Maven project..."
|
||||
pushd test/maven-project/
|
||||
docker run -v `pwd`:/github/workspace/ --workdir /github/workspace --network $network --env SONAR_TOKEN=$token --env SONAR_HOST_URL='http://sonarqube:9000' sonarsource/sonarqube-scan-action
|
||||
if [[ $? -eq 0 ]]; then
|
||||
error "Should have failed fast."
|
||||
exit 1
|
||||
fi
|
||||
popd
|
||||
success "Correctly failed fast."
|
||||
|
||||
info "Analyze project..."
|
||||
cd test/example-project/
|
||||
docker run -v `pwd`:/github/workspace/ --workdir /github/workspace --network $network --env SONAR_TOKEN=$token --env SONAR_HOST_URL='http://sonarqube:9000' sonarsource/sonarqube-scan-action
|
||||
if [[ ! $? -eq 0 ]]; then
|
||||
error "Couldn't run the analysis."
|
||||
exit 1
|
||||
elif [[ ! -f ".scannerwork/report-task.txt" ]]; then
|
||||
error "Couldn't find the report task file. Analysis failed."
|
||||
exit 1
|
||||
fi
|
||||
success "Analysis successful."
|
||||
|
||||
echo "" # new line
|
||||
echo "============================"
|
||||
echo "" # new line
|
||||
success "QA successful!"
|
||||
Loading…
Reference in a new issue