diff --git a/.gitea/workflows/push-validation.yml b/.gitea/workflows/push-validation.yml index 3dd3cc9..f55505e 100644 --- a/.gitea/workflows/push-validation.yml +++ b/.gitea/workflows/push-validation.yml @@ -35,6 +35,27 @@ jobs: cache: true cache-dependency-path: go.sum + - name: Validate formatting + run: test -z "$(gofmt -l .)" + + - name: Module hygiene + run: | + set -euo pipefail + go mod tidy + go mod verify + + - name: Run gosec security analysis + uses: securego/gosec@v2 + with: + args: ./... + + - name: Run govulncheck + uses: golang/govulncheck-action@v1 + with: + go-package: ./... + cache: true + cache-dependency-path: go.sum + - name: Run full unit test suite with coverage run: | set -euo pipefail diff --git a/internal/vociferate/vociferate.go b/internal/vociferate/vociferate.go index 5f79b18..29ffc8e 100644 --- a/internal/vociferate/vociferate.go +++ b/internal/vociferate/vociferate.go @@ -23,11 +23,15 @@ const ( defaultUnreleasedTemplate = "### Breaking\n\n### Added\n\n### Changed\n\n### Removed\n\n### Fixed\n" ) -var releasedSectionRe = regexp.MustCompile(`(?m)^## \[(\d+\.\d+\.\d+)\] - `) -var linkedReleasedSectionRe = regexp.MustCompile(`(?m)^## \[(\d+\.\d+\.\d+)\](?:\([^\n)]*\))? - `) -var unreleasedHeadingRe = regexp.MustCompile(`(?m)^## \[Unreleased\](?:\([^\n)]*\))?\n`) -var releaseHeadingRe = regexp.MustCompile(`(?m)^## \[(\d+\.\d+\.\d+)\](?:\([^\n)]*\))? - `) -var refLinkLineRe = regexp.MustCompile(`^\[[^\]]+\]: \S`) +// Pre-compiled regex patterns used for changelog parsing. +// These are read-only after initialization. +var ( + releasedSectionRe = regexp.MustCompile(`(?m)^## \[(\d+\.\d+\.\d+)\] - `) + linkedReleasedSectionRe = regexp.MustCompile(`(?m)^## \[(\d+\.\d+\.\d+)\](?:\([^\n)]*\))? - `) + unreleasedHeadingRe = regexp.MustCompile(`(?m)^## \[Unreleased\](?:\([^\n)]*\))?\n`) + releaseHeadingRe = regexp.MustCompile(`(?m)^## \[(\d+\.\d+\.\d+)\](?:\([^\n)]*\))? - `) + refLinkLineRe = regexp.MustCompile(`^\[[^\]]+\]: \S`) +) type Options struct { // VersionFile is the path to the file that stores the current version,