mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
CI: Add CI check for what's new link (#70046)
* Add whatsnewchecker * Add whatsnewchecker_test * Small fixes * Add step in CI * Fix lint * Fix starlark * t.Cleanup instead of separate func * Skip check for test tags
This commit is contained in:
committed by
GitHub
parent
9f065a8835
commit
91272ee4f9
46
.drone.yml
46
.drone.yml
@@ -2297,6 +2297,50 @@ environment:
|
||||
image_pull_secrets:
|
||||
- dockerconfigjson
|
||||
kind: pipeline
|
||||
name: release-whatsnew-checker
|
||||
node:
|
||||
type: no-parallel
|
||||
platform:
|
||||
arch: amd64
|
||||
os: linux
|
||||
services: []
|
||||
steps:
|
||||
- commands:
|
||||
- go build -o ./bin/build -ldflags '-extldflags -static' ./pkg/build/cmd
|
||||
depends_on: []
|
||||
environment:
|
||||
CGO_ENABLED: 0
|
||||
image: golang:1.20.4
|
||||
name: compile-build-cmd
|
||||
- commands:
|
||||
- ./bin/build whatsnew-checker
|
||||
depends_on:
|
||||
- compile-build-cmd
|
||||
image: golang:1.20.4
|
||||
name: whats-new-checker
|
||||
trigger:
|
||||
event:
|
||||
exclude:
|
||||
- promote
|
||||
ref:
|
||||
exclude:
|
||||
- refs/tags/*-cloud*
|
||||
include:
|
||||
- refs/tags/v*
|
||||
type: docker
|
||||
volumes:
|
||||
- host:
|
||||
path: /var/run/docker.sock
|
||||
name: docker
|
||||
---
|
||||
clone:
|
||||
retries: 3
|
||||
depends_on: []
|
||||
environment:
|
||||
EDITION: oss
|
||||
image_pull_secrets:
|
||||
- dockerconfigjson
|
||||
kind: pipeline
|
||||
name: release-oss-build-e2e-publish
|
||||
node:
|
||||
type: no-parallel
|
||||
@@ -7308,6 +7352,6 @@ kind: secret
|
||||
name: delivery-bot-app-private-key
|
||||
---
|
||||
kind: signature
|
||||
hmac: 57a88408eae5719f7ffa85c575c46e5b90ea301627144cb738d2ac8b8396e973
|
||||
hmac: c1eaa0e7d7427fd28ec0edba24a89aaa2bcb876391bd7ecde5f5fd55ffc0d0b5
|
||||
|
||||
...
|
||||
|
||||
@@ -82,6 +82,11 @@ func main() {
|
||||
&buildIDFlag,
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "whatsnew-checker",
|
||||
Usage: "Checks whatsNewUrl in package.json for differences between the tag and the docs version",
|
||||
Action: WhatsNewChecker,
|
||||
},
|
||||
{
|
||||
Name: "build-docker",
|
||||
Usage: "Build Grafana Docker images",
|
||||
|
||||
71
pkg/build/cmd/whatsnewchecker.go
Normal file
71
pkg/build/cmd/whatsnewchecker.go
Normal file
@@ -0,0 +1,71 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/grafana/grafana/pkg/build/config"
|
||||
"github.com/urfave/cli/v2"
|
||||
"golang.org/x/mod/semver"
|
||||
)
|
||||
|
||||
const GrafanaDir = "."
|
||||
|
||||
var whatsNewRegex = regexp.MustCompile(`^.*whats-new-in-(v\d*-[\d+]*)`)
|
||||
|
||||
type PackageJSON struct {
|
||||
Grafana Grafana `json:"grafana"`
|
||||
Version string `json:"version"`
|
||||
}
|
||||
|
||||
type Grafana struct {
|
||||
WhatsNewUrl string `json:"whatsNewUrl"`
|
||||
}
|
||||
|
||||
func WhatsNewChecker(c *cli.Context) error {
|
||||
metadata, err := config.GenerateMetadata(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if metadata.ReleaseMode.IsTest {
|
||||
fmt.Println("test mode, skipping check")
|
||||
return nil
|
||||
}
|
||||
if metadata.ReleaseMode.Mode != config.TagMode {
|
||||
return fmt.Errorf("non-tag pipeline, exiting")
|
||||
}
|
||||
|
||||
tag := fmt.Sprintf("v%s", metadata.GrafanaVersion)
|
||||
|
||||
if !semver.IsValid(tag) {
|
||||
return fmt.Errorf("non-semver compatible version %s, exiting", tag)
|
||||
}
|
||||
|
||||
majorMinorDigits := strings.Replace(semver.MajorMinor(tag), ".", "-", 1)
|
||||
|
||||
pkgJSONPath := filepath.Join(GrafanaDir, "package.json")
|
||||
//nolint:gosec
|
||||
pkgJSONB, err := os.ReadFile(pkgJSONPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to read %q: %w", pkgJSONPath, err)
|
||||
}
|
||||
|
||||
var pkgObj PackageJSON
|
||||
if err := json.Unmarshal(pkgJSONB, &pkgObj); err != nil {
|
||||
return fmt.Errorf("failed decoding %q: %w", pkgJSONPath, err)
|
||||
}
|
||||
|
||||
whatsNewSplit := whatsNewRegex.FindStringSubmatch(pkgObj.Grafana.WhatsNewUrl)
|
||||
whatsNewVersion := whatsNewSplit[1]
|
||||
|
||||
if whatsNewVersion != majorMinorDigits {
|
||||
return fmt.Errorf("whatsNewUrl in package.json needs to be updated to %s/", strings.Replace(whatsNewSplit[0], whatsNewVersion, majorMinorDigits, 1))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
83
pkg/build/cmd/whatsnewchecker_test.go
Normal file
83
pkg/build/cmd/whatsnewchecker_test.go
Normal file
@@ -0,0 +1,83 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana/pkg/build/config"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
const (
|
||||
DroneBuildEvent = "DRONE_BUILD_EVENT"
|
||||
DroneTag = "DRONE_TAG"
|
||||
DroneSemverPrerelease = "DRONE_SEMVER_PRERELEASE"
|
||||
)
|
||||
|
||||
const whatsNewUrl = "https://grafana.com/docs/grafana/next/whatsnew/whats-new-in-"
|
||||
|
||||
func TestWhatsNewChecker(t *testing.T) {
|
||||
tests := []struct {
|
||||
envMap map[string]string
|
||||
packageJsonVersion string
|
||||
name string
|
||||
wantErr bool
|
||||
errMsg string
|
||||
}{
|
||||
{envMap: map[string]string{DroneBuildEvent: config.PullRequest}, packageJsonVersion: "", name: "non-tag event", wantErr: true, errMsg: "non-tag pipeline, exiting"},
|
||||
{envMap: map[string]string{DroneBuildEvent: config.Tag, DroneTag: "abcd123"}, packageJsonVersion: "", name: "non-semver compatible", wantErr: true, errMsg: "non-semver compatible version vabcd123, exiting"},
|
||||
{envMap: map[string]string{DroneBuildEvent: config.Tag, DroneTag: "v0.0.0", DroneSemverPrerelease: "test"}, packageJsonVersion: "v10-0", name: "skip check for test tags", wantErr: false},
|
||||
{envMap: map[string]string{DroneBuildEvent: config.Tag, DroneTag: "v10.0.0"}, packageJsonVersion: "v10-0", name: "package.json version matches tag", wantErr: false},
|
||||
{envMap: map[string]string{DroneBuildEvent: config.Tag, DroneTag: "v10.0.0"}, packageJsonVersion: "v9-5", name: "package.json doesn't match tag", wantErr: true, errMsg: "whatsNewUrl in package.json needs to be updated to https://grafana.com/docs/grafana/next/whatsnew/whats-new-in-v10-0/"},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
app := cli.NewApp()
|
||||
app.Version = "1.0.0"
|
||||
context := cli.NewContext(app, &flag.FlagSet{}, nil)
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
setUpEnv(t, tt.envMap)
|
||||
err := createTempPackageJson(t, tt.packageJsonVersion)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = WhatsNewChecker(context)
|
||||
if tt.wantErr {
|
||||
require.Error(t, err)
|
||||
require.Equal(t, tt.errMsg, err.Error())
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func setUpEnv(t *testing.T, envMap map[string]string) {
|
||||
t.Helper()
|
||||
|
||||
os.Clearenv()
|
||||
t.Setenv("DRONE_BUILD_NUMBER", "12345")
|
||||
t.Setenv("DRONE_COMMIT", "abcd12345")
|
||||
for k, v := range envMap {
|
||||
t.Setenv(k, v)
|
||||
}
|
||||
}
|
||||
|
||||
func createTempPackageJson(t *testing.T, version string) error {
|
||||
t.Helper()
|
||||
|
||||
grafanaData := Grafana{WhatsNewUrl: fmt.Sprintf("%s%s/", whatsNewUrl, version)}
|
||||
data := PackageJSON{Grafana: grafanaData, Version: "1.2.3"}
|
||||
file, _ := json.MarshalIndent(data, "", " ")
|
||||
|
||||
err := os.WriteFile("package.json", file, 0644)
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Cleanup(func() {
|
||||
err := os.RemoveAll("package.json")
|
||||
require.NoError(t, err)
|
||||
})
|
||||
return nil
|
||||
}
|
||||
@@ -64,6 +64,10 @@ load(
|
||||
"scripts/drone/utils/images.star",
|
||||
"images",
|
||||
)
|
||||
load(
|
||||
"scripts/drone/pipelines/whats_new_checker.star",
|
||||
"whats_new_checker_pipeline",
|
||||
)
|
||||
|
||||
ver_mode = "release"
|
||||
release_trigger = {
|
||||
@@ -210,9 +214,12 @@ def oss_pipelines(ver_mode = ver_mode, trigger = release_trigger):
|
||||
memcached_integration_tests_step(),
|
||||
]
|
||||
|
||||
pipelines = []
|
||||
|
||||
# We don't need to run integration tests at release time since they have
|
||||
# been run multiple times before:
|
||||
if ver_mode in ("release"):
|
||||
pipelines.append(whats_new_checker_pipeline(release_trigger))
|
||||
integration_test_steps = []
|
||||
volumes = []
|
||||
|
||||
@@ -220,7 +227,7 @@ def oss_pipelines(ver_mode = ver_mode, trigger = release_trigger):
|
||||
"{}-oss-build-e2e-publish".format(ver_mode),
|
||||
"{}-oss-test-frontend".format(ver_mode),
|
||||
]
|
||||
pipelines = [
|
||||
pipelines.extend([
|
||||
pipeline(
|
||||
name = "{}-oss-build-e2e-publish".format(ver_mode),
|
||||
edition = "oss",
|
||||
@@ -232,7 +239,7 @@ def oss_pipelines(ver_mode = ver_mode, trigger = release_trigger):
|
||||
),
|
||||
test_frontend(trigger, ver_mode),
|
||||
test_backend(trigger, ver_mode),
|
||||
]
|
||||
])
|
||||
|
||||
if ver_mode not in ("release"):
|
||||
pipelines.append(pipeline(
|
||||
|
||||
43
scripts/drone/pipelines/whats_new_checker.star
Normal file
43
scripts/drone/pipelines/whats_new_checker.star
Normal file
@@ -0,0 +1,43 @@
|
||||
"""
|
||||
This module contains logic for checking if the package.json whats new url matches with the in-flight tag.
|
||||
"""
|
||||
|
||||
load(
|
||||
"scripts/drone/utils/images.star",
|
||||
"images",
|
||||
)
|
||||
load(
|
||||
"scripts/drone/steps/lib.star",
|
||||
"compile_build_cmd",
|
||||
)
|
||||
load(
|
||||
"scripts/drone/utils/utils.star",
|
||||
"pipeline",
|
||||
)
|
||||
|
||||
def whats_new_checker_step():
|
||||
return {
|
||||
"name": "whats-new-checker",
|
||||
"image": images["go_image"],
|
||||
"depends_on": [
|
||||
"compile-build-cmd",
|
||||
],
|
||||
"commands": [
|
||||
"./bin/build whatsnew-checker",
|
||||
],
|
||||
}
|
||||
|
||||
def whats_new_checker_pipeline(trigger):
|
||||
environment = {"EDITION": "oss"}
|
||||
steps = [
|
||||
compile_build_cmd(),
|
||||
whats_new_checker_step(),
|
||||
]
|
||||
return pipeline(
|
||||
name = "release-whatsnew-checker",
|
||||
edition = "oss",
|
||||
trigger = trigger,
|
||||
services = [],
|
||||
steps = steps,
|
||||
environment = environment,
|
||||
)
|
||||
Reference in New Issue
Block a user