Update README validation and Go version
- Downgrade Go version in CI to 1.24 for consistency. - Fix naming and path issues in `readmevalidation` code. - Improve regex validation for module and namespace names. - Correct typos and improve comments for clarity.
This commit is contained in:
parent
5b6d878fd7
commit
3b6b1ba4b9
4
.github/workflows/ci.yaml
vendored
4
.github/workflows/ci.yaml
vendored
@ -63,8 +63,8 @@ jobs:
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: "1.25.0"
|
||||
- name: Validate Reademde
|
||||
go-version: "1.24"
|
||||
- name: Validate README
|
||||
run: go build ./cmd/readmevalidation && ./readmevalidation
|
||||
- name: Remove build file artifact
|
||||
run: rm ./readmevalidation
|
||||
|
||||
@ -14,20 +14,14 @@ var (
|
||||
terraformSourceRe = regexp.MustCompile(`^\s*source\s*=\s*"([^"]+)"`)
|
||||
)
|
||||
|
||||
func normalizeModuleName(name string) string {
|
||||
// Normalize module names by replacing hyphens with underscores for comparison
|
||||
// since Terraform allows both but directory names typically use hyphens
|
||||
return strings.ReplaceAll(name, "-", "_")
|
||||
}
|
||||
|
||||
func extractNamespaceAndModuleFromPath(filePath string) (string, string, error) {
|
||||
// Expected path format: registry/<namespace>/modules/<module-name>/README.md
|
||||
func extractNamespaceAndModuleFromPath(filePath string) (namespace string, moduleName string, err error) {
|
||||
// Expected path format: registry/<namespace>/modules/<module-name>/README.md.
|
||||
parts := strings.Split(filepath.Clean(filePath), string(filepath.Separator))
|
||||
if len(parts) < 5 || parts[0] != "registry" || parts[2] != "modules" || parts[4] != "README.md" {
|
||||
return "", "", xerrors.Errorf("invalid module path format: %s", filePath)
|
||||
}
|
||||
namespace := parts[1]
|
||||
moduleName := parts[3]
|
||||
namespace = parts[1]
|
||||
moduleName = parts[3]
|
||||
return namespace, moduleName, nil
|
||||
}
|
||||
|
||||
@ -55,21 +49,21 @@ func validateModuleSourceURL(body string, filePath string) []error {
|
||||
isInsideTerraform = true
|
||||
firstTerraformBlock = false
|
||||
} else if isInsideTerraform {
|
||||
// End of first terraform block
|
||||
// End of first terraform block.
|
||||
break
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if isInsideTerraform {
|
||||
// Check for any source line in the first terraform block
|
||||
// Check for any source line in the first terraform block.
|
||||
if matches := terraformSourceRe.FindStringSubmatch(nextLine); matches != nil {
|
||||
actualSource := matches[1]
|
||||
if actualSource == expectedSource {
|
||||
foundCorrectSource = true
|
||||
break
|
||||
} else if strings.HasPrefix(actualSource, "registry.coder.com/") && strings.Contains(actualSource, "/"+moduleName+"/coder") {
|
||||
// Found source for this module but with wrong namespace/format
|
||||
// Found source for this module but with wrong namespace/format.
|
||||
errs = append(errs, xerrors.Errorf("incorrect source URL format: found %q, expected %q", actualSource, expectedSource))
|
||||
return errs
|
||||
}
|
||||
|
||||
@ -25,7 +25,7 @@ var (
|
||||
terraformVersionRe = regexp.MustCompile(`^\s*\bversion\s+=`)
|
||||
|
||||
// Matches the format "> [!INFO]". Deliberately using a broad pattern to catch formatting issues that can mess up
|
||||
// the renderer for the Registry website
|
||||
// the renderer for the Registry website.
|
||||
gfmAlertRegex = regexp.MustCompile(`^>(\s*)\[!(\w+)\](\s*)(.*)`)
|
||||
)
|
||||
|
||||
@ -39,7 +39,7 @@ type coderResourceFrontmatter struct {
|
||||
}
|
||||
|
||||
// A slice version of the struct tags from coderResourceFrontmatter. Might be worth using reflection to generate this
|
||||
// list at runtime in the future, but this should be okay for now
|
||||
// list at runtime in the future, but this should be okay for now.
|
||||
var supportedCoderResourceStructKeys = []string{
|
||||
"description", "icon", "display_name", "verified", "tags", "supported_os",
|
||||
// TODO: This is an old, officially deprecated key from the archived coder/modules repo. We can remove this once we
|
||||
@ -315,15 +315,15 @@ func validateResourceGfmAlerts(readmeBody string) []error {
|
||||
}
|
||||
|
||||
// Nested GFM alerts is such a weird mistake that it's probably not really safe to keep trying to process the
|
||||
// rest of the content, so this will prevent any other validations from happening for the given line
|
||||
// rest of the content, so this will prevent any other validations from happening for the given line.
|
||||
if isInsideGfmQuotes {
|
||||
errs = append(errs, errors.New("registry does not support nested GFM alerts"))
|
||||
errs = append(errs, xerrors.New("registry does not support nested GFM alerts"))
|
||||
continue
|
||||
}
|
||||
|
||||
leadingWhitespace := currentMatch[1]
|
||||
if len(leadingWhitespace) != 1 {
|
||||
errs = append(errs, errors.New("GFM alerts must have one space between the '>' and the start of the GFM brackets"))
|
||||
errs = append(errs, xerrors.New("GFM alerts must have one space between the '>' and the start of the GFM brackets"))
|
||||
}
|
||||
isInsideGfmQuotes = true
|
||||
|
||||
@ -347,7 +347,7 @@ func validateResourceGfmAlerts(readmeBody string) []error {
|
||||
}
|
||||
}
|
||||
|
||||
if gfmAlertRegex.Match([]byte(sourceLine)) {
|
||||
if gfmAlertRegex.MatchString(sourceLine) {
|
||||
errs = append(errs, xerrors.Errorf("README has an incomplete GFM alert at the end of the file"))
|
||||
}
|
||||
|
||||
|
||||
@ -26,7 +26,7 @@ type contributorProfileFrontmatter struct {
|
||||
}
|
||||
|
||||
// A slice version of the struct tags from contributorProfileFrontmatter. Might be worth using reflection to generate
|
||||
// this list at runtime in the future, but this should be okay for now
|
||||
// this list at runtime in the future, but this should be okay for now.
|
||||
var supportedContributorProfileStructKeys = []string{"display_name", "bio", "status", "avatar", "linkedin", "github", "website", "support_email"}
|
||||
|
||||
type contributorProfileReadme struct {
|
||||
|
||||
@ -13,12 +13,11 @@ import (
|
||||
|
||||
var supportedUserNameSpaceDirectories = append(supportedResourceTypes, ".images")
|
||||
|
||||
// validNameRe validates that names contain only alphanumeric characters and hyphens
|
||||
// validNameRe validates that names contain only alphanumeric characters and hyphens.
|
||||
var validNameRe = regexp.MustCompile(`^[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?$`)
|
||||
|
||||
|
||||
// validateCoderResourceSubdirectory validates that the structure of a module or template within a namespace follows all
|
||||
// expected file conventions
|
||||
// expected file conventions.
|
||||
func validateCoderResourceSubdirectory(dirPath string) []error {
|
||||
resourceDir, err := os.Stat(dirPath)
|
||||
if err != nil {
|
||||
@ -47,7 +46,7 @@ func validateCoderResourceSubdirectory(dirPath string) []error {
|
||||
continue
|
||||
}
|
||||
|
||||
// Validate module/template name
|
||||
// Validate module/template name.
|
||||
if !validNameRe.MatchString(f.Name()) {
|
||||
errs = append(errs, xerrors.Errorf("%q: name contains invalid characters (only alphanumeric characters and hyphens are allowed)", path.Join(dirPath, f.Name())))
|
||||
continue
|
||||
@ -90,7 +89,7 @@ func validateRegistryDirectory() []error {
|
||||
continue
|
||||
}
|
||||
|
||||
// Validate namespace name
|
||||
// Validate namespace name.
|
||||
if !validNameRe.MatchString(nDir.Name()) {
|
||||
allErrs = append(allErrs, xerrors.Errorf("%q: namespace name contains invalid characters (only alphanumeric characters and hyphens are allowed)", namespacePath))
|
||||
continue
|
||||
@ -136,7 +135,7 @@ func validateRegistryDirectory() []error {
|
||||
|
||||
// validateRepoStructure validates that the structure of the repo is "correct enough" to do all necessary validation
|
||||
// checks. It is NOT an exhaustive validation of the entire repo structure – it only checks the parts of the repo that
|
||||
// are relevant for the main validation steps
|
||||
// are relevant for the main validation steps.
|
||||
func validateRepoStructure() error {
|
||||
var errs []error
|
||||
if vrdErrs := validateRegistryDirectory(); len(vrdErrs) != 0 {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user