test/release/please_test.go
Rama main · réplica de lectura del repositorio original.
package release_test
import (
"os"
"path/filepath"
"strings"
"testing"
)
type triggerWorkflow struct {
On map[string]any `yaml:"on"`
}
func TestReleasePleaseOnlyCutsThePullRequest(t *testing.T) {
workflow := readYAML[workflowFile](t, ".github/workflows/release-please.yaml")
job := requireJob(t, workflow, "release-please")
if _, ok := job.Permissions["actions"]; ok {
t.Fatal("release-please can still dispatch workflows, which doubled the cost of every commit")
}
release := requireStep(t, job, "release")
if !strings.Contains(release.Uses, "googleapis/release-please-action@") {
t.Fatal("release-please output does not come from the release action")
}
for _, step := range job.Steps {
if strings.Contains(step.Run, "gh workflow run") {
t.Fatalf("release-please dispatches %q on every commit; validation belongs to release-artifacts", step.Name)
}
}
}
func TestReleaseArtifactsOnlyBuildAndPublish(t *testing.T) {
workflow := readYAML[workflowFile](t, ".github/workflows/release-artifacts.yaml")
for name, job := range workflow.Jobs {
if job.Uses != "" {
t.Errorf("release artifacts calls %s through the %s job; a release waits on nothing but its own artifacts", job.Uses, name)
}
}
want := map[string]bool{
"version": true,
"dist": true,
"image": true,
"chart": true,
"desktop": true,
"desktop-linux": true,
"publish": true,
}
for name := range workflow.Jobs {
if !want[name] {
t.Errorf("release artifacts runs %s, which does not build or publish an artifact", name)
}
delete(want, name)
}
if len(want) != 0 {
t.Fatalf("release artifacts no longer has: %v", want)
}
for _, name := range []string{"dist", "image"} {
needs := requireJob(t, workflow, name).Needs
if len(needs) != 1 || needs[0] != "version" {
t.Fatalf("%s needs %v, want only the version job", name, needs)
}
}
}
func TestEveryReleaseJobIsBounded(t *testing.T) {
workflow := readYAML[workflowFile](t, ".github/workflows/release-artifacts.yaml")
for name, job := range workflow.Jobs {
minutes, ok := job.TimeoutMinutes.(int)
if !ok {
t.Errorf("%s job has no timeout, so a stuck release hangs for six hours", name)
continue
}
if minutes <= 0 || minutes > 45 {
t.Errorf("%s job timeout = %d minutes, want a bound between 1 and 45", name, minutes)
}
}
}
func TestEveryCommitTierWorkflowStillGuardsTheReleaseCommit(t *testing.T) {
tiers := readJSON[ciTiers](t, ".github/ci-tiers.json")
seen := 0
for name, entry := range tiers.Workflows {
if entry.Tier != "commit" {
continue
}
seen++
path := filepath.Join(".github", "workflows", name)
triggers := readYAML[triggerWorkflow](t, path)
push, ok := triggers.On["push"].(map[string]any)
if !ok {
t.Errorf("%s is on the commit tier but does not run when a commit lands on main", path)
continue
}
branches, ok := push["branches"].([]any)
if !ok || len(branches) == 0 {
t.Errorf("%s names no branch to run on", path)
continue
}
if branches[0] != "main" {
t.Errorf("%s runs on %v, want main, so a release commit is covered", path, branches[0])
}
}
if seen == 0 {
t.Fatal("no workflow is on the commit tier")
}
}
func TestEveryWorkflowDeclaresACadence(t *testing.T) {
tiers := readJSON[ciTiers](t, ".github/ci-tiers.json")
entries, err := os.ReadDir(filepath.Join(repositoryRoot(t), ".github", "workflows"))
if err != nil {
t.Fatal(err)
}
found := 0
for _, entry := range entries {
if entry.IsDir() || filepath.Ext(entry.Name()) != ".yaml" {
continue
}
found++
if _, ok := tiers.Workflows[entry.Name()]; !ok {
t.Errorf("%s has no tier in .github/ci-tiers.json", entry.Name())
}
}
if found != len(tiers.Workflows) {
t.Fatalf("%d workflow files against %d declared tiers", found, len(tiers.Workflows))
}
}