Skip to content

Commit 38a6b1f

Browse files
authored
🐛 QD-11538: qodana-clang fails to send report (#574)
* 🧱 QD-11538: Update publisher to latest * 🐛 QD-11538: Fix qodana cloud endpoint * ✨ QD-11538: Bundle publisher-cli as part of executable * 🧱 QD-11538: Add generate step to CI build * 🐛 QD-11538: Fix typo * ♻️ QD-11538: Remove unused code * ✨ QD-11538: Create a unified system for downloading public resources * 🐛 QD-11538: Fix custom endpoints not being used * ♻️ QD-11538: Fix nitpicks
1 parent e8937a4 commit 38a6b1f

File tree

13 files changed

+188
-175
lines changed

13 files changed

+188
-175
lines changed

.github/workflows/ci.yml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,6 @@ jobs:
3737
touch cdnet/clt.zip tooling/baseline-cli.jar tooling/intellij-report-converter.jar tooling/qodana-fuser.jar
3838
rm go.work && mv go.work.github go.work
3939
shell: bash
40-
- name: Download config-loader-cli.jar
41-
run: chmod +x download_deps.sh && ./download_deps.sh
42-
shell: bash
4340
- name: Set up gotestfmt
4441
uses: gotesttools/gotestfmt-action@v2
4542
with:
@@ -50,6 +47,13 @@ jobs:
5047
registry: registry.jetbrains.team
5148
username: ${{ secrets.SPACE_USERNAME }}
5249
password: ${{ secrets.SPACE_PASSWORD }}
50+
- name: Build
51+
# Build everything that will be tested. Although go test performs a build itself, gotestfmt will panic on a
52+
# failed build.
53+
run: |
54+
go generate -v $(go list -f '{{.Dir}}/...' -m)
55+
go build -v $(go list -f '{{.Dir}}/...' -m)
56+
shell: bash
5357
- name: Run tests (with coverage)
5458
if: ${{ matrix.os != 'windows-latest' }}
5559
run: |

cmd/send.go

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ import (
2727
"github.com/google/uuid"
2828
"github.com/spf13/cobra"
2929
"os"
30-
"path/filepath"
3130
)
3231

3332
// newShowCommand returns a new instance of the show command.
@@ -57,9 +56,6 @@ If you are using other Qodana Cloud instance than https://qodana.cloud/, overrid
5756
cliOptions.ConfigName,
5857
)
5958

60-
var publisherPath string
61-
publisherPath = filepath.Join(commonCtx.ConfDirPath(), platform.PublisherJarName)
62-
6359
publisher := platform.Publisher{
6460
ResultsDir: commonCtx.ResultsDir,
6561
LogDir: commonCtx.LogDir(),
@@ -73,7 +69,6 @@ If you are using other Qodana Cloud instance than https://qodana.cloud/, overrid
7369
platform.SendReport(
7470
publisher,
7571
tokenloader.ValidateCloudToken(commonCtx, false),
76-
publisherPath,
7772
java,
7873
)
7974
},

download_checksum_of_deps.sh

Lines changed: 0 additions & 26 deletions
This file was deleted.

download_deps.sh

Lines changed: 0 additions & 61 deletions
This file was deleted.

platform/publisher.go

Lines changed: 30 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -23,46 +23,47 @@
2323
package platform
2424

2525
import (
26-
"crypto/md5"
27-
"encoding/hex"
26+
"os"
27+
2828
"github.com/JetBrains/qodana-cli/v2025/cloud"
2929
"github.com/JetBrains/qodana-cli/v2025/platform/qdenv"
3030
"github.com/JetBrains/qodana-cli/v2025/platform/utils"
31+
"github.com/JetBrains/qodana-cli/v2025/tooling"
3132
log "github.com/sirupsen/logrus"
32-
"io"
33-
"net/http"
34-
"os"
35-
"path/filepath"
3633
)
3734

38-
const PublisherJarName = "publisher-cli.jar"
39-
const PublisherVersion = "2.1.31"
40-
4135
type Publisher struct {
4236
ResultsDir string
4337
LogDir string
4438
AnalysisId string
4539
}
4640

4741
// SendReport sends report to Qodana Cloud.
48-
func SendReport(publisher Publisher, token string, publisherPath string, javaPath string) {
49-
if _, err := os.Stat(publisherPath); os.IsNotExist(err) {
50-
err := os.MkdirAll(filepath.Dir(publisherPath), os.ModePerm)
51-
if err != nil {
52-
log.Fatalf("failed to create directory: %v", err)
53-
}
54-
fetchPublisher(publisherPath)
42+
func SendReport(publisher Publisher, token string, javaPath string) {
43+
file, err := os.CreateTemp("", "qodana-publisher.jar")
44+
if err != nil {
45+
log.Fatalf("Failed to create a temporary file: %s", err)
5546
}
56-
if _, err := os.Stat(publisherPath); os.IsNotExist(err) {
57-
log.Fatalf("Not able to send the report: %s is missing", publisherPath)
47+
publisherPath := file.Name()
48+
err = file.Close()
49+
if err != nil {
50+
log.Fatalf("Failed to close temporary file %q: %s", file.Name(), err)
5851
}
52+
defer func() {
53+
err = os.Remove(file.Name())
54+
if err != nil {
55+
log.Fatalf("Failed to remove temporary file %q: %s", file.Name(), err)
56+
}
57+
}()
58+
59+
extractPublisher(publisherPath)
5960

6061
publisherCommand := getPublisherArgs(
6162
javaPath,
6263
publisherPath,
6364
publisher,
6465
token,
65-
cloud.GetCloudApiEndpoints().CloudApiUrl,
66+
cloud.GetCloudRootEndpoint().Url,
6667
)
6768
if _, _, res, err := utils.LaunchAndLog(publisher.LogDir, "publisher", publisherCommand...); res > 0 || err != nil {
6869
os.Exit(res)
@@ -90,69 +91,25 @@ func getPublisherArgs(java string, publisherPath string, publisher Publisher, to
9091
}
9192
}
9293
if endpoint != "" {
93-
publisherArgs = append(publisherArgs, "--endpoint", endpoint)
94+
publisherArgs = append(publisherArgs, "--qodana-endpoint", endpoint)
9495
}
9596
return publisherArgs
9697
}
9798

98-
func getPublisherUrl(version string) string {
99-
return "https://packages.jetbrains.team/maven/p/ij/intellij-dependencies/org/jetbrains/qodana/publisher-cli/" + version + "/publisher-cli-" + version + ".jar"
100-
}
101-
102-
func fetchPublisher(path string) {
103-
jarVersion := PublisherVersion
104-
if _, err := os.Stat(path); err == nil {
105-
return
106-
}
107-
err := utils.DownloadFile(path, getPublisherUrl(jarVersion), nil)
108-
if err != nil {
109-
log.Fatal(err)
110-
}
111-
verifyMd5Hash(jarVersion, path)
112-
}
113-
114-
func verifyMd5Hash(version string, path string) {
115-
if _, err := os.Stat(path); err != nil {
116-
log.Fatal(err)
117-
}
118-
url := getPublisherUrl(version) + ".md5"
119-
resp, err := http.Get(url)
99+
func extractPublisher(path string) {
100+
file, err := os.Create(path)
120101
if err != nil {
121-
log.Fatalf("Error downloading md5 hash: %v", err)
102+
log.Fatalf("Error while creating %q: %s", path, err)
122103
}
123-
defer func(Body io.ReadCloser) {
124-
err := Body.Close()
104+
defer func() {
105+
err := file.Close()
125106
if err != nil {
126-
log.Fatal(err)
107+
log.Fatalf("Error while closing %q: %s", path, err)
127108
}
128-
}(resp.Body)
109+
}()
129110

130-
body, err := io.ReadAll(resp.Body)
111+
_, err = file.Write(tooling.PublisherCli)
131112
if err != nil {
132-
log.Fatalf("Error reading md5 hash: %v", err)
133-
}
134-
135-
downloadedMd5 := string(body)
136-
fileContent, err := os.ReadFile(path)
137-
if err != nil {
138-
log.Fatalf("Error reading file: %v", err)
139-
}
140-
141-
hasher := md5.New()
142-
_, err = hasher.Write(fileContent)
143-
if err != nil {
144-
log.Fatalf("Error computing md5 hash: %v", err)
145-
}
146-
147-
computedMd5 := hex.EncodeToString(hasher.Sum(nil))
148-
149-
if computedMd5 != downloadedMd5 {
150-
err = os.Remove(path)
151-
if err != nil {
152-
log.Fatalf("Please remove file, since md5 doesn't match: %s", path)
153-
}
154-
log.Fatal("The provided file and the file from the link have different md5 hashes")
155-
} else {
156-
log.Debug("Obtained publisher " + version + " and successfully checked md5 hash")
113+
log.Fatalf("Error while writing %q: %s", path, err)
157114
}
158115
}

platform/publisher_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ func TestFetchPublisher(t *testing.T) {
3838
}
3939
}(tempDir) // clean up
4040
path := filepath.Join(tempDir, "publisher.jar")
41-
fetchPublisher(path)
41+
extractPublisher(path)
4242

4343
if _, err := os.Stat(path); os.IsNotExist(err) {
4444
t.Fatalf("fetchPublisher() failed, expected %v to exists, got error: %v", path, err)
@@ -72,7 +72,7 @@ func TestGetPublisherArgs(t *testing.T) {
7272
"--report-path", filepath.FromSlash("/path/to/results"),
7373
"--token", "test-token",
7474
"--tool", "test-tool",
75-
"--endpoint", "test-endpoint",
75+
"--qodana-endpoint", "test-endpoint",
7676
}
7777
if !reflect.DeepEqual(publisherArgs, expectedArgs) {
7878
t.Errorf("getPublisherArgs returned incorrect arguments: got %v, expected %v", publisherArgs, expectedArgs)

platform/run.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,10 +217,10 @@ func sendReportToQodanaServer(c thirdpartyscan.Context) {
217217
LogDir: c.LogDir(),
218218
AnalysisId: c.AnalysisId(),
219219
}
220+
220221
SendReport(
221222
publisher,
222223
cloud.Token.Token,
223-
utils.QuoteForWindows(filepath.Join(c.CacheDir(), PublisherJarName)),
224224
utils.QuoteForWindows(c.MountInfo().JavaPath),
225225
)
226226
} else {

platform/utils/fileops.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@
1717
package utils
1818

1919
import (
20+
"crypto/sha256"
21+
"errors"
2022
log "github.com/sirupsen/logrus"
23+
"io"
2124
"os"
2225
"path/filepath"
2326
)
@@ -83,3 +86,28 @@ func CopyDir(src string, dst string) error {
8386
}
8487
return nil
8588
}
89+
90+
// GetSha256 computes a hash sum for a byte stream.
91+
func GetSha256(stream io.Reader) (result [32]byte, err error) {
92+
hasher := sha256.New()
93+
_, err = io.Copy(hasher, stream)
94+
if err != nil {
95+
return result, err
96+
}
97+
98+
copy(result[:], hasher.Sum(nil))
99+
return result, nil
100+
}
101+
102+
// GetFileSha256 computes a hash sum from an existing file.
103+
func GetFileSha256(path string) (result [32]byte, err error) {
104+
reader, err := os.Open(path)
105+
if err != nil {
106+
return result, err
107+
}
108+
defer func() {
109+
err = errors.Join(err, reader.Close())
110+
}()
111+
112+
return GetSha256(reader)
113+
}

tooling/config-loader-cli-0.0.20.jar.sha256

Lines changed: 0 additions & 1 deletion
This file was deleted.

tooling/config_loader_cli.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@ package tooling
1818

1919
import _ "embed"
2020

21-
// execute [./download_deps.sh] to load config-loader-cli.jar
22-
// source code: https://github.com/JetBrains/qodana-configuration
23-
21+
//go:generate go run scripts/download-resource.go config-loader-cli.jar
2422
//go:embed config-loader-cli.jar
2523
var ConfigLoaderCli []byte

0 commit comments

Comments
 (0)