Skip to content

Commit 7af0b08

Browse files
committed
feat: MegaLinter static analysis and code linting (#1)
* feat: megalinter for linting/static analysis * fix: render markdown & artifact link Signed-off-by: swappy <59965507+rycerzes@users.noreply.github.com>
1 parent 8436576 commit 7af0b08

5 files changed

Lines changed: 148 additions & 8 deletions

File tree

.github/workflows/release.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ on:
33
branches:
44
- main
55
- func
6+
- lint
67

78
name: Create Release
89

action.yml

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@ inputs:
1919
delay:
2020
description: Time to start application
2121
required: true
22-
default: 10s
22+
default: "10"
2323
container-name:
2424
description: Name of the container in case of "docker compose" command
2525
build-delay:
2626
description: Time to wait for docker container build
27-
default: 50s
27+
default: "50"
2828
runner-version:
2929
description: Version of the runner to use
3030
default: "latest"
@@ -41,7 +41,36 @@ runs:
4141
echo "Working directory: ${{ inputs.working-directory }}"
4242
echo "Keploy path: ${{ inputs.keploy-path }}"
4343
shell: bash
44-
44+
45+
- name: Run MegaLinter
46+
shell: bash
47+
run: |
48+
docker run -v $(pwd):/tmp/lint \
49+
-e GITHUB_TOKEN=${{ inputs.github-token }} \
50+
-e REPORT_OUTPUT_FOLDER=/tmp/lint/megalinter-reports \
51+
-e DISABLE_ERRORS=true \
52+
-e PARALLEL=true \
53+
-e JSON_REPORTER=true \
54+
-e MARKDOWN_SUMMARY_REPORTER=true \
55+
-e EXCLUDED_DIRECTORIES="keploy,megalinter-reports" \
56+
-e SHOW_SKIPPED_LINTERS=false \
57+
-e SHOW_ELAPSED_TIME=true \
58+
oxsecurity/megalinter-cupcake:v8.5.0
59+
working-directory: ${{ inputs.working-directory }}
60+
61+
- name: Upload MegaLinter Report
62+
uses: actions/upload-artifact@v4
63+
with:
64+
name: megalinter-report
65+
path: ${{ inputs.working-directory }}/megalinter-reports/
66+
retention-days: 1
67+
id: upload-megalinter
68+
69+
- name: Set MegaLinter artifact link
70+
shell: bash
71+
run: |
72+
echo "MEGALINTER_ARTIFACT_URL=https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}/artifacts" >> $GITHUB_ENV
73+
4574
- name: Download pre-built runner
4675
run: |
4776
echo "Downloading from: https://github.com/rycerzes/testGPT/releases/download/latest/keploy-runner"
@@ -62,7 +91,8 @@ runs:
6291
CONTAINER_NAME: ${{ inputs.container-name }}
6392
BUILD_DELAY: ${{ inputs.build-delay }}
6493
GITHUB_TOKEN: ${{ inputs.github-token }}
65-
94+
MEGALINTER_ARTIFACT_URL: ${{ env.MEGALINTER_ARTIFACT_URL }}
95+
6696
- id: keploy-test-report
6797
name: Process Test Results
6898
run: |
@@ -75,7 +105,7 @@ runs:
75105
shell: bash
76106
env:
77107
WORKDIR: ${{ inputs.working-directory }}
78-
108+
79109
- name: Check if report is generated
80110
run: |
81111
if [ -f "${GITHUB_WORKSPACE}/${WORKDIR}/final.out" ]; then
@@ -87,7 +117,7 @@ runs:
87117
shell: bash
88118
env:
89119
WORKDIR: ${{ inputs.working-directory }}
90-
120+
91121
- name: Comment on PR
92122
if: success() && github.event_name == 'pull_request'
93123
uses: actions/github-script@v6

main.go

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,18 @@ func processTestReports(githubWorkspace, workDir string) {
336336
fmt.Println("Not running in a PR context, running in manual trigger mode")
337337
}
338338

339+
// Get MegaLinter report if available
340+
var megaLinterMarkdown string
341+
megaLinterSummary, err := utils.GetMegaLinterReport(githubWorkspace, workDir)
342+
if err != nil {
343+
fmt.Printf("Warning: Failed to read MegaLinter report: %v\n", err)
344+
} else {
345+
// Get the artifact link from environment variable
346+
artifactLink := os.Getenv("MEGALINTER_ARTIFACT_URL")
347+
megaLinterMarkdown = utils.FormatMegaLinterReport(megaLinterSummary, artifactLink)
348+
fmt.Println("Successfully processed MegaLinter report")
349+
}
350+
339351
outputDir := filepath.Join(githubWorkspace, workDir)
340352
if _, err := os.Stat(outputDir); os.IsNotExist(err) {
341353
os.MkdirAll(outputDir, 0755)
@@ -399,11 +411,19 @@ func processTestReports(githubWorkspace, workDir string) {
399411
// Add PR details only if available in PR context
400412
if isPRContext && prDetailsMarkdown != "" {
401413
githubOutputBuilder.WriteString("<details>\n")
402-
githubOutputBuilder.WriteString("<summary>**🔍 PR Analysis**</summary>\n\n")
414+
githubOutputBuilder.WriteString("<summary><h3>🔍 PR Analysis</h3></summary>\n\n")
403415
githubOutputBuilder.WriteString(prDetailsMarkdown)
404416
githubOutputBuilder.WriteString("</details>\n\n")
405417
}
406418

419+
// Add MegaLinter report if available
420+
if megaLinterMarkdown != "" {
421+
githubOutputBuilder.WriteString("<details>\n")
422+
githubOutputBuilder.WriteString("<summary><h3>🔍 MegaLinter Analysis</h3></summary>\n\n")
423+
githubOutputBuilder.WriteString(megaLinterMarkdown)
424+
githubOutputBuilder.WriteString("</details>\n\n")
425+
}
426+
407427
githubOutputBuilder.WriteString("EOF\n")
408428

409429
os.WriteFile(filepath.Join(outputDir, "github_output.txt"), []byte(githubOutputBuilder.String()), 0644)

utils/megalinter_report.go

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
package utils
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"path/filepath"
7+
"strings"
8+
)
9+
10+
type MegaLinterSummary struct {
11+
Status string
12+
Table string
13+
ReportID string
14+
}
15+
16+
func GetMegaLinterReport(githubWorkspace, workDir string) (*MegaLinterSummary, error) {
17+
reportPath := filepath.Join(githubWorkspace, workDir, "megalinter-reports", "megalinter-report.md")
18+
19+
data, err := os.ReadFile(reportPath)
20+
if err != nil {
21+
return nil, fmt.Errorf("failed to read MegaLinter report: %v", err)
22+
}
23+
24+
content := string(data)
25+
26+
status := "UNKNOWN"
27+
if strings.Contains(content, "⚠️ WARNING") {
28+
status = "WARNING"
29+
} else if strings.Contains(content, "❌ ERROR") {
30+
status = "ERROR"
31+
} else if strings.Contains(content, "✅ SUCCESS") {
32+
status = "SUCCESS"
33+
}
34+
35+
lines := strings.Split(content, "\n")
36+
var tableLines []string
37+
inTable := false
38+
39+
for _, line := range lines {
40+
if strings.HasPrefix(line, "|") {
41+
inTable = true
42+
tableLines = append(tableLines, line)
43+
} else if inTable && len(line) == 0 {
44+
break
45+
}
46+
}
47+
48+
table := strings.Join(tableLines, "\n")
49+
50+
reportID := fmt.Sprintf("megalinter-report-%d", os.Getpid())
51+
52+
return &MegaLinterSummary{
53+
Status: status,
54+
Table: table,
55+
ReportID: reportID,
56+
}, nil
57+
}
58+
59+
func FormatMegaLinterReport(summary *MegaLinterSummary, artifactLink string) string {
60+
var sb strings.Builder
61+
62+
statusEmoji := "⚠️"
63+
if summary.Status == "SUCCESS" {
64+
statusEmoji = "✅"
65+
} else if summary.Status == "ERROR" {
66+
statusEmoji = "❌"
67+
}
68+
69+
sb.WriteString(fmt.Sprintf("### %s **MegaLinter Results**\n\n", statusEmoji))
70+
71+
sb.WriteString(summary.Table)
72+
73+
actionsLink := fmt.Sprintf("https://github.com/%s/actions/runs/%s",
74+
os.Getenv("GITHUB_REPOSITORY"),
75+
os.Getenv("GITHUB_RUN_ID"))
76+
77+
sb.WriteString(fmt.Sprintf("\n- [MegaLinter Full Report](%s)\n", actionsLink))
78+
79+
// Use the provided artifact link instead of constructing one
80+
if artifactLink != "" {
81+
sb.WriteString(fmt.Sprintf("- [Download MegaLinter Report](%s)\n", artifactLink))
82+
}
83+
84+
return sb.String()
85+
}
86+
87+
func GetGitHubRunID() string {
88+
return os.Getenv("GITHUB_RUN_ID")
89+
}

utils/pr_analysis.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ func FormatPRDetailsForComment(pr *PRDetails) string {
112112
sb.WriteString(fmt.Sprintf("**Updated At**: %s\n\n", pr.UpdatedAt))
113113

114114
sb.WriteString("<details>\n")
115-
sb.WriteString("<summary>**🔍 PR Analysis Details**</summary>\n\n")
115+
sb.WriteString("<summary><h4>🔍 PR Analysis Details<h4></summary>\n\n")
116116
sb.WriteString("#### **Changed Files**\n\n")
117117

118118
for _, file := range pr.ChangedFiles {

0 commit comments

Comments
 (0)