From befc887a89c2b87d9d9c465059e0c119f5d55157 Mon Sep 17 00:00:00 2001 From: WquGuru Date: Sun, 9 Nov 2025 18:40:03 +0800 Subject: [PATCH] fix(ci): add test encryption key for CI environment (#826) * fix(ci): add test encryption key for CI environment - Add DATA_ENCRYPTION_KEY environment variable to PR test workflow - Add test RSA public key for encryption tests in CI - Ensures unit tests pass in CI without production credentials Co-authored-by: tinkle-community * fix(ci): install Go cover tool to eliminate covdata warnings - Add step to install golang.org/x/tools/cmd/cover in CI workflow - Use || true to prevent installation failure from breaking CI - Eliminates "no such tool covdata" warnings during test execution - Apply go fmt to multiple files for consistency Co-authored-by: tinkle-community * fix(ci): install covdata tool for Go 1.23 coverage The CI was failing with "go: no such tool 'covdata'" error. This is because Go 1.23 requires the covdata tool to be installed for coverage reporting. Changes: - Install golang.org/x/tools/cmd/covdata in CI workflow - Update step name to reflect both coverage tools being installed Fixes the unit test failures in CI pipeline. Co-Authored-By: tinkle-community * fix(ci): remove unnecessary covdata installation and use builtin go tool cover The previous attempt to install golang.org/x/tools/cmd/covdata was failing because the package structure changed in Go 1.23 and tools v0.38.0. The covdata tool is not needed for this project since we only use simple coverage reporting with go test -coverprofile. The go tool cover command is built into the Go toolchain and requires no additional installation. Changes: - Remove failed covdata and cover installation attempts - Add verification step for go tool cover availability - Simplify CI pipeline by eliminating unnecessary dependencies Co-authored-by: tinkle-community * fix(ci): upgrade Go version to 1.25 to match go.mod declaration The CI was using Go 1.23 while go.mod declares go 1.25.0, causing "no such tool covdata" errors during coverage test compilation. Go 1.25's coverage infrastructure requires toolchain features not available in Go 1.23. This change aligns the CI Go version with the project's declared version requirement, ensuring the full Go 1.25 toolchain (including the covdata tool) is available for coverage testing. Co-authored-by: tinkle-community --------- Co-authored-by: tinkle-community --- .github/workflows/pr-go-test-coverage.yml | 8 +++++++- auth/auth.go | 5 ----- bootstrap/bootstrap.go | 2 +- config/database.go | 18 +++++++++--------- config/database_test.go | 1 - config/test_rsa_key.pem.pub | 9 +++++++++ crypto/crypto.go | 2 +- decision/engine.go | 2 +- 8 files changed, 28 insertions(+), 19 deletions(-) create mode 100644 config/test_rsa_key.pem.pub diff --git a/.github/workflows/pr-go-test-coverage.yml b/.github/workflows/pr-go-test-coverage.yml index fb5134da..87f9a9ef 100644 --- a/.github/workflows/pr-go-test-coverage.yml +++ b/.github/workflows/pr-go-test-coverage.yml @@ -29,7 +29,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: '1.23' + go-version: '1.25' - name: Set up Python uses: actions/setup-python@v5 @@ -52,7 +52,13 @@ jobs: - name: Download dependencies run: go mod download + - name: Verify Go coverage tool + run: | + go tool cover -h || echo "Warning: go tool cover not available" + - name: Run tests with coverage + env: + DATA_ENCRYPTION_KEY: "test-encryption-key-for-ci-only-not-production" run: | go test -v -race -coverprofile=coverage.out -covermode=atomic ./... diff --git a/auth/auth.go b/auth/auth.go index c3c22bde..85fa184f 100644 --- a/auth/auth.go +++ b/auth/auth.go @@ -16,7 +16,6 @@ import ( // JWTSecret JWT密钥,将从配置中动态设置 var JWTSecret []byte - // tokenBlacklist 用于登出后的token黑名单(仅内存,按过期时间清理) var tokenBlacklist = struct { sync.RWMutex @@ -34,10 +33,6 @@ func SetJWTSecret(secret string) { JWTSecret = []byte(secret) } - - - - // BlacklistToken 将token加入黑名单直到过期 func BlacklistToken(token string, exp time.Time) { tokenBlacklist.Lock() diff --git a/bootstrap/bootstrap.go b/bootstrap/bootstrap.go index 88fd2063..ee756113 100644 --- a/bootstrap/bootstrap.go +++ b/bootstrap/bootstrap.go @@ -2,11 +2,11 @@ package bootstrap import ( "fmt" + "log" "nofx/logger" "sort" "sync" "time" - "log" ) // Priority 初始化优先级常量 diff --git a/config/database.go b/config/database.go index abbf8fd7..5977ae3c 100644 --- a/config/database.go +++ b/config/database.go @@ -54,7 +54,7 @@ type DatabaseInterface interface { // Database 配置数据库 type Database struct { - db *sql.DB + db *sql.DB cryptoService *crypto.CryptoService } @@ -760,12 +760,12 @@ func (d *Database) GetExchanges(userID string) ([]*ExchangeConfig, error) { if err != nil { return nil, err } - + // 解密敏感字段 exchange.APIKey = d.decryptSensitiveData(exchange.APIKey) exchange.SecretKey = d.decryptSensitiveData(exchange.SecretKey) exchange.AsterPrivateKey = d.decryptSensitiveData(exchange.AsterPrivateKey) - + exchanges = append(exchanges, &exchange) } @@ -889,7 +889,7 @@ func (d *Database) CreateExchange(userID, id, name, typ string, enabled bool, ap encryptedAPIKey := d.encryptSensitiveData(apiKey) encryptedSecretKey := d.encryptSensitiveData(secretKey) encryptedAsterPrivateKey := d.encryptSensitiveData(asterPrivateKey) - + _, err := d.db.Exec(` INSERT OR IGNORE INTO exchanges (id, user_id, name, type, enabled, api_key, secret_key, testnet, hyperliquid_wallet_addr, aster_user, aster_signer, aster_private_key) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) @@ -1242,13 +1242,13 @@ func (d *Database) encryptSensitiveData(plaintext string) string { if d.cryptoService == nil || plaintext == "" { return plaintext } - + encrypted, err := d.cryptoService.EncryptForStorage(plaintext) if err != nil { log.Printf("⚠️ 加密失败: %v", err) return plaintext // 返回明文作为降级处理 } - + return encrypted } @@ -1257,17 +1257,17 @@ func (d *Database) decryptSensitiveData(encrypted string) string { if d.cryptoService == nil || encrypted == "" { return encrypted } - + // 如果不是加密格式,直接返回 if !d.cryptoService.IsEncryptedStorageValue(encrypted) { return encrypted } - + decrypted, err := d.cryptoService.DecryptFromStorage(encrypted) if err != nil { log.Printf("⚠️ 解密失败: %v", err) return encrypted // 返回加密文本作为降级处理 } - + return decrypted } diff --git a/config/database_test.go b/config/database_test.go index 11655bca..99ac03f3 100644 --- a/config/database_test.go +++ b/config/database_test.go @@ -206,7 +206,6 @@ func TestUpdateExchange_NonEmptyValuesShouldUpdate(t *testing.T) { } } - // TestUpdateExchange_PartialUpdateShouldWork 测试部分字段更新 func TestUpdateExchange_PartialUpdateShouldWork(t *testing.T) { db, cleanup := setupTestDB(t) diff --git a/config/test_rsa_key.pem.pub b/config/test_rsa_key.pem.pub new file mode 100644 index 00000000..a9f89eeb --- /dev/null +++ b/config/test_rsa_key.pem.pub @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4Y666RzY5LLi6PiYL+vC +7+fcr122Fd8BC7IdqUSYKQ33Nsi9J7J5fDgcMf7ZAnIBpxMV7+e1KEoiwtGmxwHj +mYo0ZV0E6JXdiK26S052+Shquri0IXkwGFraDuNKqmGrj6vZuXtq2L2gdSyZCxrI +veN9g6LxBvLBP1Rx7UEmZeyokRYvChcxAQXuS/0br44BOHGtwAElk6AGLISz55AG +oM40b3ktiza+8THKMz3GiylQQYpBltbM3yAXPlnXJ2MtUZiaHNhEQI4++PMvEErN +Izm8cIgcvUAXJ5vBfa4kD0kSgBJFuEQ2im3qcWTuEPRKztEeJDY7XAVHc1Xy6d4N +vQIDAQAB +-----END PUBLIC KEY----- diff --git a/crypto/crypto.go b/crypto/crypto.go index 8710e908..9a29480f 100644 --- a/crypto/crypto.go +++ b/crypto/crypto.go @@ -391,4 +391,4 @@ func (cs *CryptoService) DecryptSensitiveData(payload *EncryptedPayload) (string return "", err } return string(plaintext), nil -} \ No newline at end of file +} diff --git a/decision/engine.go b/decision/engine.go index 15b4a892..a4d9132c 100644 --- a/decision/engine.go +++ b/decision/engine.go @@ -37,7 +37,7 @@ type PositionInfo struct { Leverage int `json:"leverage"` UnrealizedPnL float64 `json:"unrealized_pnl"` UnrealizedPnLPct float64 `json:"unrealized_pnl_pct"` - PeakPnLPct float64 `json:"peak_pnl_pct"` // 历史最高收益率(百分比) + PeakPnLPct float64 `json:"peak_pnl_pct"` // 历史最高收益率(百分比) LiquidationPrice float64 `json:"liquidation_price"` MarginUsed float64 `json:"margin_used"` UpdateTime int64 `json:"update_time"` // 持仓更新时间戳(毫秒)