VAULT-34834: pipeline: add better heuristics for changed files (#30284)

* VAULT-34834: pipeline: add better heuristics for changed files

To fully support automated Enterprise to Community backports we need to
have better changed file detection for community and enterprise only
files. Armed with this metadata, future changes will be able to inspect
changed files and automatically remove enterprise only files when
creating the CE backports.

For this change we now have the following changed file groups:
  - autopilot
  - changelog
  - community
  - docs
  - enos
  - enterprise
  - app
  - gotoolchain
  - pipeline
  - proto
  - tools
  - ui

Not included in the change, but something I did while updating out
checkers was generate a list of files that included only in
vault-enterprise and run every path the enterprise detection rules
to ensure that they are categorized appropriately post changes in
VAULT-35431. While it's possible that they'll drift, our changed
file categorization is best effort anyway and changes will always
happen in vault-enterprise and require a developer to approve the
changes.

We've also included a few new files into the various groups and updated
the various workflows to use the new categories. I've also included a
small change to the pipeline composite action whereby we do not handle
Go module caching. This will greatly reduce work on doc-only branches
that need only ensure that the pipeline binary is compiled.

Signed-off-by: Ryan Cragun <me@ryan.ec>
This commit is contained in:
Ryan Cragun 2025-04-18 10:54:41 -06:00 committed by GitHub
parent 1975736057
commit 10c4371135
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 307 additions and 152 deletions

View File

@ -11,6 +11,8 @@ description: |
to maintain compatibility in both execution contexts. to maintain compatibility in both execution contexts.
inputs: inputs:
github-token:
description: An elevated Github token to use for searching labels
vault-version: vault-version:
description: | description: |
The version of vault from hashicorp/action-set-product-version. If set we'll utilize this The version of vault from hashicorp/action-set-product-version. If set we'll utilize this
@ -97,7 +99,7 @@ runs:
name: workflow-metadata name: workflow-metadata
shell: bash shell: bash
env: env:
GH_TOKEN: ${{ github.token }} GH_TOKEN: ${{ inputs.github-token || github.token }}
run: | run: |
if [ '${{ github.event_name }}' = 'pull_request' ]; then if [ '${{ github.event_name }}' = 'pull_request' ]; then
is_draft='${{ github.event.pull_request.draft }}' is_draft='${{ github.event.pull_request.draft }}'

View File

@ -11,6 +11,9 @@ inputs:
no-restore: no-restore:
description: Whether or not to restore the Go module cache on a cache hit description: Whether or not to restore the Go module cache on a cache hit
default: "false" default: "false"
no-save:
description: Whether or not to create a Go module cache on cache miss
default: "false"
go-version: go-version:
description: "Override .go-version" description: "Override .go-version"
default: "" default: ""
@ -68,7 +71,7 @@ runs:
# keeps cache upload time, download time, and storage size to a minimum. # keeps cache upload time, download time, and storage size to a minimum.
path: ${{ steps.metadata.outputs.cache-path }} path: ${{ steps.metadata.outputs.cache-path }}
key: ${{ steps.metadata.outputs.cache-key }} key: ${{ steps.metadata.outputs.cache-key }}
- if: steps.cache-modules.outputs.cache-hit != 'true' - if: steps.cache-modules.outputs.cache-hit != 'true' && inputs.no-save != 'false'
name: Download go modules name: Download go modules
shell: bash shell: bash
env: env:

View File

@ -16,6 +16,7 @@ runs:
with: with:
github-token: ${{ inputs.github-token || github.token }} github-token: ${{ inputs.github-token || github.token }}
no-restore: true # Don't download vault's modules for pipeline no-restore: true # Don't download vault's modules for pipeline
no-save: true # Don't attempt to save modules either
- name: pipeline-metadata - name: pipeline-metadata
id: pipeline-metadata id: pipeline-metadata
shell: bash shell: bash

View File

@ -229,7 +229,7 @@ jobs:
with: with:
# The inputs defined here must be supported in both the build-artifacts-ce and # The inputs defined here must be supported in both the build-artifacts-ce and
# build-artifacts-ent workflows. The implementations should seek to keep a compatible interface. # build-artifacts-ent workflows. The implementations should seek to keep a compatible interface.
build-all: ${{ contains(fromJSON(needs.setup.outputs.labels), 'build/all') || needs.setup.outputs.workflow-trigger == 'schedule' || contains(fromJSON(needs.setup.outputs.changed-files).groups, 'gomod') }} build-all: ${{contains(fromJSON(needs.setup.outputs.labels), 'build/all') || needs.setup.outputs.workflow-trigger == 'schedule' || contains(fromJSON(needs.setup.outputs.changed-files).groups, 'gotoolchain')}}
build-date: ${{ needs.setup.outputs.build-date }} build-date: ${{ needs.setup.outputs.build-date }}
checkout-ref: ${{ needs.setup.outputs.checkout-ref }} checkout-ref: ${{ needs.setup.outputs.checkout-ref }}
compute-build: ${{ needs.setup.outputs.compute-build }} compute-build: ${{ needs.setup.outputs.compute-build }}

View File

@ -142,6 +142,7 @@ jobs:
# Run Go tests if the vault app changed # Run Go tests if the vault app changed
if: | if: |
contains(fromJSON(needs.setup.outputs.changed-files).groups, 'app') || contains(fromJSON(needs.setup.outputs.changed-files).groups, 'app') ||
contains(fromJSON(needs.setup.outputs.changed-files).groups, 'gotoolchain') ||
contains(fromJSON(needs.setup.outputs.changed-files).groups, 'pipeline') contains(fromJSON(needs.setup.outputs.changed-files).groups, 'pipeline')
name: Run Go tests name: Run Go tests
needs: setup needs: setup
@ -162,7 +163,9 @@ jobs:
test-go-testonly: test-go-testonly:
# Run Go tests tagged with "testonly" if the vault app changed # Run Go tests tagged with "testonly" if the vault app changed
if: contains(fromJSON(needs.setup.outputs.changed-files).groups, 'app') if: |
contains(fromJSON(needs.setup.outputs.changed-files).groups, 'app') ||
contains(fromJSON(needs.setup.outputs.changed-files).groups, 'gotoolchain')
name: Run Go tests tagged with testonly name: Run Go tests tagged with testonly
needs: setup needs: setup
uses: ./.github/workflows/test-go.yml uses: ./.github/workflows/test-go.yml
@ -181,7 +184,12 @@ jobs:
test-go-race: test-go-race:
# Run Go test with the data race detector enabled if the vault app changed and we're out of # Run Go test with the data race detector enabled if the vault app changed and we're out of
# drafts mode. # drafts mode.
if: contains(fromJSON(needs.setup.outputs.changed-files).groups, 'app') && needs.setup.outputs.is-draft == 'false' if: |
needs.setup.outputs.is-draft == 'false' &&
(
contains(fromJSON(needs.setup.outputs.changed-files).groups, 'app') ||
contains(fromJSON(needs.setup.outputs.changed-files).groups, 'gotoolchain')
)
name: Run Go tests with data race detection name: Run Go tests with data race detection
needs: setup needs: setup
uses: ./.github/workflows/test-go.yml uses: ./.github/workflows/test-go.yml
@ -208,7 +216,9 @@ jobs:
if: | if: |
contains(fromJSON(needs.setup.outputs.changed-files).groups, 'app') && contains(fromJSON(needs.setup.outputs.changed-files).groups, 'app') &&
needs.setup.outputs.is-enterprise == 'true' && needs.setup.outputs.is-enterprise == 'true' &&
(needs.setup.outputs.workflow-trigger == 'push' || contains(needs.setup.outputs.labels, 'fips')) (
needs.setup.outputs.workflow-trigger == 'push' || contains(needs.setup.outputs.labels, 'fips')
)
needs: setup needs: setup
uses: ./.github/workflows/test-go.yml uses: ./.github/workflows/test-go.yml
with: with:

View File

@ -16,88 +16,253 @@ type FileGroupCheck func(context.Context, *File) FileGroups
// DefaultFileGroupCheckers are the default file group checkers // DefaultFileGroupCheckers are the default file group checkers
var DefaultFileGroupCheckers = []FileGroupCheck{ var DefaultFileGroupCheckers = []FileGroupCheck{
FileGroupCheckerDir, FileGroupCheckerApp,
FileGroupCheckerFileName, FileGroupCheckerAutopilot,
FileGroupCheckerFileGo, FileGroupCheckerChangelog,
FileGroupCheckerFileProto, FileGroupCheckerCommunity,
FileGroupCheckerDocs,
FileGroupCheckerEnos,
FileGroupCheckerEnterprise,
FileGroupCheckerGoToolchain,
FileGroupCheckerPipeline,
FileGroupCheckerProto,
FileGroupCheckerWebUI,
} }
// FileGroupCheckerDir is a file group checker that groups based on the files directory // Group takes a context, a file, and one-to-many file group checkers and adds group metadata to
func FileGroupCheckerDir(ctx context.Context, file *File) FileGroups { // the file.
name := file.Name() func Group(ctx context.Context, file *File, checkers ...FileGroupCheck) {
groups := FileGroups{} if file == nil || len(checkers) < 1 {
return
}
for dir, groups := range map[string]FileGroups{ for _, check := range checkers {
".github": groups.Add(FileGroupPipeline), file.Groups = file.Groups.Add(check(ctx, file)...)
"changelog": groups.Add(FileGroupChangelog), }
"enos": groups.Add(FileGroupEnos), }
"tools": groups.Add(FileGroupTools),
"ui": groups.Add(FileGroupWebUI), // GroupFiles takes a context, a slice of files, and one-to-many file group checkers and adds group
"website": groups.Add(FileGroupDocs), // metadata to the files.
} { func GroupFiles(ctx context.Context, files []*File, checkers ...FileGroupCheck) {
if strings.HasPrefix(name, dir+string(os.PathSeparator)) { for _, file := range files {
return groups Group(ctx, file, checkers...)
}
}
// FileGroupCheckerApp is a file group checker that groups based on the file being part of the Vault
// Go app
func FileGroupCheckerApp(ctx context.Context, file *File) FileGroups {
name := file.Name()
ext := filepath.Ext(name)
switch {
case hasBaseDir(name, filepath.Join("tools", "pipeline")):
return nil
case
ext == ".go",
strings.HasSuffix(name, "go.mod"),
strings.HasSuffix(name, "go.sum"):
return FileGroups{FileGroupGoApp}
default:
return nil
}
}
// FileGroupCheckerAutopilot is a file group checker that groups based on the file being part of the
// raft autopilot system
func FileGroupCheckerAutopilot(ctx context.Context, file *File) FileGroups {
name := file.Name()
ext := filepath.Ext(name)
if ext == ".go" && strings.Contains(name, "raft_autopilot") {
return FileGroups{FileGroupAutopilot}
}
return nil
}
// FileGroupCheckerChangelog is a file group checker that groups based on the file being part of the
// CHANGELOG
func FileGroupCheckerChangelog(ctx context.Context, file *File) FileGroups {
name := file.Name()
if strings.HasPrefix(name, "CHANGELOG") || hasBaseDir(name, "changelog") {
return FileGroups{FileGroupChangelog}
}
return nil
}
// FileGroupCheckerCommunity is a file group checker that groups based on the file being part of the
// Vault App but a community only file.
func FileGroupCheckerCommunity(ctx context.Context, file *File) FileGroups {
name := file.Name()
switch filepath.Ext(name) {
case ".go":
if strings.HasSuffix(name, "_oss.go") || strings.HasSuffix(name, "_ce.go") {
return FileGroups{FileGroupCommunity}
}
case
".hcl",
".md",
".sh",
".yaml",
".yml":
switch {
case
strings.Contains(name, "-ce"),
strings.Contains(name, "_ce"),
strings.Contains(name, "-oss"),
strings.Contains(name, "_oss"):
return FileGroups{FileGroupCommunity}
} }
} }
return nil return nil
} }
// FileGroupCheckerFileName is a file group checker that groups based on the files name // FileGroupCheckerDocs is a file group checker that groups based on the file being part of the
func FileGroupCheckerFileName(ctx context.Context, file *File) FileGroups { // documenation.
func FileGroupCheckerDocs(ctx context.Context, file *File) FileGroups {
name := file.Name() name := file.Name()
groups := FileGroups{}
switch { if strings.HasPrefix(name, "README.md") || hasBaseDir(name, "website") {
case strings.HasPrefix(name, "buf."): return FileGroups{FileGroupDocs}
return groups.Add(FileGroupProto)
case strings.HasPrefix(name, "CHANGELOG"):
return groups.Add(FileGroupChangelog)
case strings.HasPrefix(name, "CODEOWNERS"):
return groups.Add(FileGroupPipeline)
case strings.HasSuffix(name, "go.mod") || strings.HasSuffix(name, "go.sum"):
return groups.Add(FileGroupGoModules, FileGroupGoApp)
} }
return nil return nil
} }
// FileGroupCheckerFileGo is a file group checker that groups based on the files extension being .go // FileGroupCheckerEnos is a file group checker that groups based on the file being part of the
func FileGroupCheckerFileGo(ctx context.Context, file *File) FileGroups { // enos testing framework.
func FileGroupCheckerEnos(ctx context.Context, file *File) FileGroups {
name := file.Name()
if strings.Contains(name, "enos") || hasBaseDir(name, "enos") {
return FileGroups{FileGroupEnos}
}
return nil
}
// FileGroupCheckerEnterprise is a file group checker that groups based on the file being part of
// the Vault App but an enterprise only file. Ideally enterprise only files will use common filename
// schema or directories to reduce our logic here, but some legacy files have been added here.
// NOTE: Even if we miss a file or two the sky will not fall, only our automation for CE backports
// could theoretically miss a file and require the author to extract it out themselves before they
// merge it. Since such files are created in Vault Enterprise there is little risk.
func FileGroupCheckerEnterprise(ctx context.Context, file *File) FileGroups {
name := file.Name()
// Base directory checks
switch {
case
hasBaseDir(name, "vault_ent"),
hasBaseDir(name, filepath.Join("scripts", "dev", "hsm")),
hasBaseDir(name, filepath.Join("scripts", "testing")),
hasBaseDir(name, filepath.Join("specs")):
return FileGroups{FileGroupEnterprise}
}
// File name checks
switch filepath.Base(name) {
case
"Dockerfile-ent",
"Dockerfile-ent-hsm":
return FileGroups{FileGroupEnterprise}
}
// File extension checks
switch filepath.Ext(name) {
case ".go":
switch {
case
strings.HasSuffix(name, "_ent.go"),
strings.HasSuffix(name, "_ent_test.go"),
strings.Contains(name, "_ent") && strings.HasSuffix(name, ".pb.go"):
return FileGroups{FileGroupEnterprise}
}
case ".txt":
if hasBaseDir(name, "changelog") && strings.HasPrefix(filepath.Base(name), "_") {
return FileGroups{FileGroupEnterprise}
}
case
".proto",
".hcl",
".md",
".sh",
".yaml",
".yml":
switch {
case
strings.Contains(name, "-ent"),
strings.Contains(name, "_ent"),
strings.Contains(name, "hsm"),
strings.Contains(name, "merkle-tree"):
return FileGroups{FileGroupEnterprise}
}
}
return nil
}
// FileGroupCheckerGoToolchain is a file group checker that groups based on the file modifying the
// Go toolchain or dependencies.
func FileGroupCheckerGoToolchain(ctx context.Context, file *File) FileGroups {
name := file.Name()
switch {
case
name == ".go-version",
strings.HasSuffix(name, "go.mod"),
strings.HasSuffix(name, "go.sum"):
return FileGroups{FileGroupGoToolchain}
default:
return nil
}
}
// FileGroupCheckerPipeline is a file group checker that groups based on the file is part of the
// build or CI pipeline.
func FileGroupCheckerPipeline(ctx context.Context, file *File) FileGroups {
name := file.Name()
switch {
case
hasBaseDir(name, ".github"),
hasBaseDir(name, "scripts"),
hasBaseDir(name, filepath.Join("tools", "pipeline")),
name == "CODEOWNERS",
name == "Dockerfile",
name == "Makefile":
return FileGroups{FileGroupPipeline}
default:
return nil
}
}
// FileGroupCheckerProto is a file group checker that groups based on the files extension being .proto
func FileGroupCheckerProto(ctx context.Context, file *File) FileGroups {
name := file.Name() name := file.Name()
ext := filepath.Ext(name) ext := filepath.Ext(name)
if ext != ".go" { if ext == ".proto" || strings.HasPrefix(name, "buf.") {
return nil return FileGroups{FileGroupProto}
}
groups := FileGroups{}
groups = groups.Add(FileGroupGoApp)
if strings.Contains(name, "raft_autopilot") {
groups = groups.Add(FileGroupAutopilot)
} }
if strings.HasSuffix(name, "_ent.go") { return nil
groups = groups.Add(FileGroupEnterprise)
} else if strings.HasSuffix(name, "_oss.go") || strings.HasSuffix(name, "_ce.go") {
groups = groups.Add(FileGroupCommunity)
}
if strings.HasPrefix(name, "tools/pipeline") {
groups = groups.Add(FileGroupPipeline)
}
return groups
} }
// FileGroupCheckerFileProto is a file group checker that groups based on the files extension being .proto // FileGroupCheckerWebUI is a file group checker that groups based on the files being part of the
func FileGroupCheckerFileProto(ctx context.Context, file *File) FileGroups { // web UI
func FileGroupCheckerWebUI(ctx context.Context, file *File) FileGroups {
name := file.Name() name := file.Name()
if hasBaseDir(name, "ui") {
ext := filepath.Ext(name) return FileGroups{FileGroupWebUI}
if ext != ".proto" {
return nil
} }
return FileGroups{FileGroupProto} return nil
}
func hasBaseDir(name, dir string) bool {
return strings.HasPrefix(name, dir+string(os.PathSeparator))
} }

View File

@ -11,72 +11,64 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
func TestFileGroupCheckerDir(t *testing.T) { func TestFileGroupDefaultCheckers(t *testing.T) {
t.Parallel() t.Parallel()
for filename, groups := range map[string]FileGroups{ for filename, groups := range map[string]FileGroups{
".github/actions/changed-files/actions.yml": {FileGroupPipeline}, ".github/actions/changed-files/actions.yml": {FileGroupPipeline},
".github/workflows/build.yml": {FileGroupPipeline}, ".github/workflows/build.yml": {FileGroupPipeline},
"changelog/16455.txt": {FileGroupChangelog}, ".github/workflows/build-artifacts-ce.yml": {FileGroupCommunity, FileGroupPipeline},
"enos/Makefile": {FileGroupEnos}, ".github/workflows/build-artifacts-ent.yml": {FileGroupEnterprise, FileGroupPipeline},
"tools/pipeline/main.go": {FileGroupTools}, ".go-version": {FileGroupGoToolchain},
"ui/lib/ldap/index.js": {FileGroupWebUI},
"website/content/api-docs/index.mdx": {FileGroupDocs},
} {
t.Run(filename, func(t *testing.T) {
file := &File{File: &github.CommitFile{Filename: &filename}}
require.Equal(t, groups, FileGroupCheckerDir(context.Background(), file))
})
}
}
func TestFileGroupCheckerFileName(t *testing.T) {
t.Parallel()
for filename, groups := range map[string]FileGroups{
"buf.yml": {FileGroupProto},
"CHANGELOG.md": {FileGroupChangelog},
"CODEOWNERS": {FileGroupPipeline},
"go.mod": {FileGroupGoApp, FileGroupGoModules},
"go.sum": {FileGroupGoApp, FileGroupGoModules},
} {
t.Run(filename, func(t *testing.T) {
file := &File{File: &github.CommitFile{Filename: &filename}}
require.Equal(t, groups, FileGroupCheckerFileName(context.Background(), file))
})
}
}
func TestFileGroupCheckerFileGo(t *testing.T) {
t.Parallel()
for filename, groups := range map[string]FileGroups{
"vault/acl.go": {FileGroupGoApp},
"command/server/config.go": {FileGroupGoApp},
"tools/pipeline/main.go": {FileGroupGoApp, FileGroupPipeline},
"command/operator_raft_autopilot_state.go": {FileGroupGoApp, FileGroupAutopilot},
"physical/raft/raft_autopilot.go": {FileGroupGoApp, FileGroupAutopilot},
"http/util_stubs_oss.go": {FileGroupGoApp, FileGroupCommunity},
"audit/backend_ce.go": {FileGroupGoApp, FileGroupCommunity}, "audit/backend_ce.go": {FileGroupGoApp, FileGroupCommunity},
"vault/activity_log_util_ent.go": {FileGroupGoApp, FileGroupEnterprise}, "audit/backend_config_ent.go": {FileGroupGoApp, FileGroupEnterprise},
"builtin/logical/transit/something_ent.go": {FileGroupGoApp, FileGroupEnterprise},
"buf.yml": {FileGroupProto},
"changelog/1726.txt": {FileGroupChangelog},
"changelog/_1726.txt": {FileGroupChangelog, FileGroupEnterprise},
"command/server/config.go": {FileGroupGoApp},
"command/operator_raft_autopilot_state.go": {FileGroupGoApp, FileGroupAutopilot},
"command/agent_ent_test.go": {FileGroupGoApp, FileGroupEnterprise},
"enos/enos-samples-ce-build.hcl": {FileGroupCommunity, FileGroupEnos},
"enos/enos-samples-ent-build.hcl": {FileGroupEnos, FileGroupEnterprise},
"enos/enos-scenario-smoke.hcl": {FileGroupEnos},
"enos/enos-scenario-autopilot-ent.hcl": {FileGroupEnos, FileGroupEnterprise},
"go.mod": {FileGroupGoApp, FileGroupGoToolchain},
"go.sum": {FileGroupGoApp, FileGroupGoToolchain},
"helper/identity/mfa/types.proto": {FileGroupProto},
"http/util_stubs_oss.go": {FileGroupGoApp, FileGroupCommunity},
"physical/raft/raft_autopilot.go": {FileGroupGoApp, FileGroupAutopilot},
"physical/raft/types.proto": {FileGroupProto},
"scripts/ci-helper.sh": {FileGroupPipeline},
"scripts/cross/Dockerfile-ent": {FileGroupEnterprise, FileGroupPipeline},
"scripts/cross/Dockerfile-ent-hsm": {FileGroupEnterprise, FileGroupPipeline},
"scripts/dev/hsm/README.md": {FileGroupEnterprise, FileGroupPipeline},
"scripts/dist-ent.sh": {FileGroupEnterprise, FileGroupPipeline},
"scripts/testing/test-vault-license.sh": {FileGroupEnterprise, FileGroupPipeline},
"scripts/testing/upgrade/README.md": {FileGroupEnterprise, FileGroupPipeline},
"sdk/database/dbplugin/v5/proto/database_ent.pb.go": {FileGroupGoApp, FileGroupEnterprise},
"sdk/database/dbplugin/v5/proto/database_ent.proto": {FileGroupEnterprise, FileGroupProto},
"specs/merkle-tree/spec.md": {FileGroupEnterprise},
"tools/pipeline/main.go": {FileGroupPipeline},
"ui/lib/ldap/index.js": {FileGroupWebUI},
"vault/acl.go": {FileGroupGoApp},
"vault/activity_log_util_ent.go": {FileGroupGoApp, FileGroupEnterprise},
"vault/identity_store_ent_test.go": {FileGroupGoApp, FileGroupEnterprise},
"vault_ent/go.mod": {FileGroupGoApp, FileGroupEnterprise, FileGroupGoToolchain},
"vault_ent/go.sum": {FileGroupGoApp, FileGroupEnterprise, FileGroupGoToolchain},
"vault_ent/requires_ent.go": {FileGroupGoApp, FileGroupEnterprise},
"website/content/api-docs/index.mdx": {FileGroupDocs},
"CHANGELOG.md": {FileGroupChangelog},
"CODEOWNERS": {FileGroupPipeline},
"Dockerfile": {FileGroupPipeline},
"Makefile": {FileGroupPipeline},
"README.md": {FileGroupDocs},
} { } {
t.Run(filename, func(t *testing.T) { t.Run(filename, func(t *testing.T) {
t.Parallel()
file := &File{File: &github.CommitFile{Filename: &filename}} file := &File{File: &github.CommitFile{Filename: &filename}}
require.Equal(t, groups, FileGroupCheckerFileGo(context.Background(), file)) Group(context.Background(), file, DefaultFileGroupCheckers...)
}) require.Equal(t, groups, file.Groups)
}
}
func TestFileGroupCheckerProto(t *testing.T) {
t.Parallel()
for filename, groups := range map[string]FileGroups{
"physical/raft/types.proto": {FileGroupProto},
"helper/identity/mfa/types.proto": {FileGroupProto},
} {
t.Run(filename, func(t *testing.T) {
file := &File{File: &github.CommitFile{Filename: &filename}}
require.Equal(t, groups, FileGroupCheckerFileProto(context.Background(), file))
}) })
} }
} }

View File

@ -26,18 +26,18 @@ type (
) )
const ( const (
FileGroupAutopilot FileGroup = "autopilot" FileGroupAutopilot FileGroup = "autopilot"
FileGroupChangelog FileGroup = "changelog" FileGroupChangelog FileGroup = "changelog"
FileGroupCommunity FileGroup = "community" FileGroupCommunity FileGroup = "community"
FileGroupDocs FileGroup = "docs" FileGroupDocs FileGroup = "docs"
FileGroupEnos FileGroup = "enos" FileGroupEnos FileGroup = "enos"
FileGroupEnterprise FileGroup = "enterprise" FileGroupEnterprise FileGroup = "enterprise"
FileGroupGoApp FileGroup = "app" FileGroupGoApp FileGroup = "app"
FileGroupGoModules FileGroup = "gomod" FileGroupGoToolchain FileGroup = "gotoolchain"
FileGroupPipeline FileGroup = "pipeline" FileGroupPipeline FileGroup = "pipeline"
FileGroupProto FileGroup = "proto" FileGroupProto FileGroup = "proto"
FileGroupTools FileGroup = "tools" FileGroupTools FileGroup = "tools"
FileGroupWebUI FileGroup = "ui" FileGroupWebUI FileGroup = "ui"
) )
// Name is the file name of the changed file // Name is the file name of the changed file

View File

@ -68,7 +68,7 @@ func (r *ListChangedFilesReq) Run(ctx context.Context, client *gh.Client) (*List
} }
if r.GroupFiles { if r.GroupFiles {
r.groupChangedFiles(ctx, res.Files, changed.DefaultFileGroupCheckers...) changed.GroupFiles(ctx, res.Files, changed.DefaultFileGroupCheckers...)
res.Groups = changed.FileGroups{} res.Groups = changed.FileGroups{}
for _, file := range res.Files { for _, file := range res.Files {
for _, group := range file.Groups { for _, group := range file.Groups {
@ -147,24 +147,6 @@ func (r *ListChangedFilesReq) getPullFiles(ctx context.Context, client *gh.Clien
} }
} }
// groupChangedFiles runs the changed files through the default group checkers
// to add group metadata. It also aggregates a combined group set for all files.
func (r *ListChangedFilesReq) groupChangedFiles(
ctx context.Context,
files changed.Files,
checks ...changed.FileGroupCheck,
) {
if len(files) < 1 {
return
}
for _, file := range files {
for _, check := range checks {
file.Groups = file.Groups.Add(check(ctx, file)...)
}
}
}
// ToJSON marshals the response to JSON. // ToJSON marshals the response to JSON.
func (r *ListChangedFilesRes) ToJSON() ([]byte, error) { func (r *ListChangedFilesRes) ToJSON() ([]byte, error) {
b, err := json.Marshal(r) b, err := json.Marshal(r)