Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .jfrog-pipelines/pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ pipelines:
description: "Forward Artifactory logs from the deployed ephemeral environment to Kibana (via Coralogix). Maps to the LOGS_TO_KIBANA parameter of the environment_setup_gen2 Jenkins job. Set 'false' to disable."
allowCustom: true
DEPLOYMENT_SIZING:
default: "large"
default: "common"
description: "Artifactory deployment sizing profile."
allowCustom: true
MAX_RUN_RETRIES:
Expand Down
48 changes: 44 additions & 4 deletions utils/tests/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,28 @@ var (
timestampAdded bool
)

// nonProjectKeyCharsRegex matches any character that isn't allowed in an Artifactory
// project key (project keys allow only lowercase alphanumeric characters and hyphens).
// We use this to sanitize the --ci.runId value before splicing it into resource names
// whose format is constrained (project keys, GPG keypair names, etc.). Project-key
// charset is a strict subset of the GPG keypair charset, so a single sanitization is
// safe for both.
var nonProjectKeyCharsRegex = regexp.MustCompile(`[^a-z0-9-]+`)

// SanitizedCiRunId returns the --ci.runId flag value lowercased with any characters
// outside [a-z0-9-] collapsed to a single hyphen and surrounding hyphens trimmed.
// Returns "" if the flag wasn't set. Callers that need a per-runId suffix on
// resources whose name format is constrained (e.g. Artifactory project keys, GPG
// keypair names) should use this so concurrent runs against a shared JPD don't
// clobber each other.
func SanitizedCiRunId() string {
if ciRunId == nil || *ciRunId == "" {
return ""
}
sanitized := nonProjectKeyCharsRegex.ReplaceAllString(strings.ToLower(*ciRunId), "-")
return strings.Trim(sanitized, "-")
}

func init() {
JfrogUrl = flag.String("jfrog.url", "http://localhost:8081/", "JFrog platform url")
JfrogUser = flag.String("jfrog.user", "admin", "JFrog platform username")
Expand All @@ -114,8 +136,8 @@ func init() {
TestPip = flag.Bool("test.pip", false, "Test Pip")
TestPipenv = flag.Bool("test.pipenv", false, "Test Pipenv")
TestPoetry = flag.Bool("test.poetry", false, "Test Poetry")
TestUv = flag.Bool("test.uv", false, "Test UV")
TestNix = flag.Bool("test.nix", false, "Test Nix")
TestUv = flag.Bool("test.uv", false, "Test UV")
TestNix = flag.Bool("test.nix", false, "Test Nix")
TestConan = flag.Bool("test.conan", false, "Test Conan")
TestHelm = flag.Bool("test.helm", false, "Test Helm")
TestHuggingFace = flag.Bool("test.huggingface", false, "Test HuggingFace")
Expand Down Expand Up @@ -640,8 +662,26 @@ func AddTimestampToGlobalVars() {
Password1 += uniqueSuffix + strconv.FormatFloat(randomSequence.Float64(), 'f', 2, 32)
Password2 += uniqueSuffix + strconv.FormatFloat(randomSequence.Float64(), 'f', 2, 32)

// Projects
ProjectKey += timestamp[len(timestamp)-7:]
/// Projects
// Artifactory project keys must be 2-32 lowercase alphanumeric or hyphen
// characters and must start with a letter. We always include the sanitized
// --ci.runId (when set) so that concurrent runs against a shared JPD don't
// clobber each other's project — createTestProject calls
// deleteProjectIfExists(tests.ProjectKey) unconditionally, which means a
// colliding key from another concurrent suite will silently delete the
// project (and every release bundle inside it) out from under us.
projectSuffix := timestamp[len(timestamp)-7:]
if sanitizedRunId := SanitizedCiRunId(); sanitizedRunId != "" {
projectSuffix = sanitizedRunId + "-" + projectSuffix
}
// ProjectKey starts as "prj" (3 chars), and the total must be <= 32. Trim
// from the front so the trailing timestamp (used for visual debuggability)
// is preserved and we don't end up with a key that starts with a hyphen.
const maxProjectKeyLen = 32
if maxSuffixLen := maxProjectKeyLen - len(ProjectKey); len(projectSuffix) > maxSuffixLen {
projectSuffix = strings.TrimLeft(projectSuffix[len(projectSuffix)-maxSuffixLen:], "-")
}
ProjectKey += projectSuffix

timestampAdded = true
}
Expand Down
Loading