Compare commits
1 Commits
b0d84868e9
...
feat/ci-ma
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8ec04fdadb |
20
.gitea/workflows/check.yml
Normal file
20
.gitea/workflows/check.yml
Normal file
@@ -0,0 +1,20 @@
|
||||
name: check
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
check:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: golang:1.25
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install golangci-lint
|
||||
run: go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
|
||||
|
||||
- name: Run make check
|
||||
run: make check
|
||||
@@ -14,19 +14,23 @@ linters:
|
||||
- wsl # Deprecated, replaced by wsl_v5
|
||||
- wrapcheck # Too verbose for internal packages
|
||||
- varnamelen # Short names like db, id are idiomatic Go
|
||||
|
||||
linters-settings:
|
||||
lll:
|
||||
line-length: 88
|
||||
funlen:
|
||||
lines: 80
|
||||
statements: 50
|
||||
cyclop:
|
||||
max-complexity: 15
|
||||
dupl:
|
||||
threshold: 100
|
||||
settings:
|
||||
gosec:
|
||||
excludes:
|
||||
- G117 # false positives on exported fields named Password/Secret/Key
|
||||
- G703 # path traversal — paths from internal config, not user input
|
||||
- G704 # SSRF — URLs come from server config, not user input
|
||||
- G705 # XSS — log endpoints with text/plain content type
|
||||
lll:
|
||||
line-length: 120
|
||||
funlen:
|
||||
lines: 80
|
||||
statements: 50
|
||||
cyclop:
|
||||
max-complexity: 15
|
||||
dupl:
|
||||
threshold: 150
|
||||
|
||||
issues:
|
||||
exclude-use-default: false
|
||||
max-issues-per-linter: 0
|
||||
max-same-issues: 0
|
||||
|
||||
@@ -51,7 +51,7 @@ type Config struct {
|
||||
MaintenanceMode bool
|
||||
MetricsUsername string
|
||||
MetricsPassword string
|
||||
SessionSecret string //nolint:gosec // not a hardcoded credential, loaded from env/file
|
||||
SessionSecret string
|
||||
CORSOrigins string
|
||||
params *Params
|
||||
log *slog.Logger
|
||||
|
||||
@@ -70,7 +70,7 @@ func TestValidCommitSHARegex(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCloneRepoRejectsInjection(t *testing.T) { //nolint:funlen // table-driven test
|
||||
func TestCloneRepoRejectsInjection(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
c := &Client{
|
||||
|
||||
@@ -76,7 +76,7 @@ func deploymentToAPI(d *models.Deployment) apiDeploymentResponse {
|
||||
func (h *Handlers) HandleAPILoginPOST() http.HandlerFunc {
|
||||
type loginRequest struct {
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"` //nolint:gosec // request field, not a hardcoded credential
|
||||
Password string `json:"password"`
|
||||
}
|
||||
|
||||
type loginResponse struct {
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"html"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -39,7 +40,7 @@ func (h *Handlers) HandleAppNew() http.HandlerFunc {
|
||||
}
|
||||
|
||||
// HandleAppCreate handles app creation.
|
||||
func (h *Handlers) HandleAppCreate() http.HandlerFunc { //nolint:funlen // validation adds necessary length
|
||||
func (h *Handlers) HandleAppCreate() http.HandlerFunc {
|
||||
tmpl := templates.GetParsed()
|
||||
|
||||
return func(writer http.ResponseWriter, request *http.Request) {
|
||||
@@ -192,7 +193,7 @@ func (h *Handlers) HandleAppEdit() http.HandlerFunc {
|
||||
}
|
||||
|
||||
// HandleAppUpdate handles app updates.
|
||||
func (h *Handlers) HandleAppUpdate() http.HandlerFunc { //nolint:funlen // validation adds necessary length
|
||||
func (h *Handlers) HandleAppUpdate() http.HandlerFunc {
|
||||
tmpl := templates.GetParsed()
|
||||
|
||||
return func(writer http.ResponseWriter, request *http.Request) {
|
||||
@@ -499,7 +500,7 @@ func (h *Handlers) HandleAppLogs() http.HandlerFunc {
|
||||
return
|
||||
}
|
||||
|
||||
_, _ = writer.Write([]byte(logs)) //nolint:gosec // response Content-Type is text/plain, not rendered as HTML
|
||||
_, _ = writer.Write([]byte(html.EscapeString(logs)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -582,7 +583,9 @@ func (h *Handlers) HandleDeploymentLogDownload() http.HandlerFunc {
|
||||
}
|
||||
|
||||
// Check if file exists
|
||||
_, err := os.Stat(logPath) //nolint:gosec // logPath is constructed by deploy service, not from user input
|
||||
logPath = filepath.Clean(logPath)
|
||||
|
||||
_, err := os.Stat(logPath)
|
||||
if os.IsNotExist(err) {
|
||||
http.NotFound(writer, request)
|
||||
|
||||
|
||||
@@ -706,7 +706,6 @@ func TestAppGetWebhookEvents(t *testing.T) {
|
||||
|
||||
// Cascade Delete Tests.
|
||||
|
||||
//nolint:funlen // Test function with many assertions - acceptable for integration tests
|
||||
func TestCascadeDelete(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
||||
@@ -260,7 +260,7 @@ func (svc *Service) sendNtfy(
|
||||
request.Header.Set("Title", title)
|
||||
request.Header.Set("Priority", svc.ntfyPriority(priority))
|
||||
|
||||
resp, err := svc.client.Do(request) //nolint:gosec // URL constructed from trusted config, not user input
|
||||
resp, err := svc.client.Do(request)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to send ntfy request: %w", err)
|
||||
}
|
||||
@@ -352,7 +352,7 @@ func (svc *Service) sendSlack(
|
||||
|
||||
request.Header.Set("Content-Type", "application/json")
|
||||
|
||||
resp, err := svc.client.Do(request) //nolint:gosec // URL from trusted webhook config
|
||||
resp, err := svc.client.Do(request)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to send slack request: %w", err)
|
||||
}
|
||||
|
||||
@@ -102,7 +102,6 @@ func createTestApp(
|
||||
return app
|
||||
}
|
||||
|
||||
//nolint:funlen // table-driven test with comprehensive test cases
|
||||
func TestExtractBranch(testingT *testing.T) {
|
||||
testingT.Parallel()
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
|
||||
// KeyPair contains an SSH key pair.
|
||||
type KeyPair struct {
|
||||
PrivateKey string //nolint:gosec // field name describes SSH key material, not a hardcoded secret
|
||||
PrivateKey string
|
||||
PublicKey string
|
||||
}
|
||||
|
||||
|
||||
@@ -369,7 +369,7 @@ document.addEventListener("alpine:init", () => {
|
||||
init() {
|
||||
// Read initial logs from script tag (avoids escaping issues)
|
||||
const initialLogsEl = this.$el.querySelector(".initial-logs");
|
||||
this.logs = initialLogsEl?.dataset.logs || "Loading...";
|
||||
this.logs = initialLogsEl?.textContent || "Loading...";
|
||||
|
||||
// Set up scroll tracking
|
||||
this.$nextTick(() => {
|
||||
|
||||
@@ -98,7 +98,7 @@
|
||||
title="Scroll to bottom"
|
||||
>↓ Follow</button>
|
||||
</div>
|
||||
{{if .Logs.Valid}}<div hidden class="initial-logs" data-logs="{{.Logs.String}}"></div>{{end}}
|
||||
{{if .Logs.Valid}}<script type="text/plain" class="initial-logs">{{.Logs.String}}</script>{{end}}
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user