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:
|
image_pull_secrets:
|
||||||
- dockerconfigjson
|
- dockerconfigjson
|
||||||
kind: pipeline
|
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
|
name: release-oss-build-e2e-publish
|
||||||
node:
|
node:
|
||||||
type: no-parallel
|
type: no-parallel
|
||||||
@@ -7308,6 +7352,6 @@ kind: secret
|
|||||||
name: delivery-bot-app-private-key
|
name: delivery-bot-app-private-key
|
||||||
---
|
---
|
||||||
kind: signature
|
kind: signature
|
||||||
hmac: 57a88408eae5719f7ffa85c575c46e5b90ea301627144cb738d2ac8b8396e973
|
hmac: c1eaa0e7d7427fd28ec0edba24a89aaa2bcb876391bd7ecde5f5fd55ffc0d0b5
|
||||||
|
|
||||||
...
|
...
|
||||||
|
|||||||
@@ -82,6 +82,11 @@ func main() {
|
|||||||
&buildIDFlag,
|
&buildIDFlag,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "whatsnew-checker",
|
||||||
|
Usage: "Checks whatsNewUrl in package.json for differences between the tag and the docs version",
|
||||||
|
Action: WhatsNewChecker,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Name: "build-docker",
|
Name: "build-docker",
|
||||||
Usage: "Build Grafana Docker images",
|
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",
|
"scripts/drone/utils/images.star",
|
||||||
"images",
|
"images",
|
||||||
)
|
)
|
||||||
|
load(
|
||||||
|
"scripts/drone/pipelines/whats_new_checker.star",
|
||||||
|
"whats_new_checker_pipeline",
|
||||||
|
)
|
||||||
|
|
||||||
ver_mode = "release"
|
ver_mode = "release"
|
||||||
release_trigger = {
|
release_trigger = {
|
||||||
@@ -210,9 +214,12 @@ def oss_pipelines(ver_mode = ver_mode, trigger = release_trigger):
|
|||||||
memcached_integration_tests_step(),
|
memcached_integration_tests_step(),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
pipelines = []
|
||||||
|
|
||||||
# We don't need to run integration tests at release time since they have
|
# We don't need to run integration tests at release time since they have
|
||||||
# been run multiple times before:
|
# been run multiple times before:
|
||||||
if ver_mode in ("release"):
|
if ver_mode in ("release"):
|
||||||
|
pipelines.append(whats_new_checker_pipeline(release_trigger))
|
||||||
integration_test_steps = []
|
integration_test_steps = []
|
||||||
volumes = []
|
volumes = []
|
||||||
|
|
||||||
@@ -220,7 +227,7 @@ def oss_pipelines(ver_mode = ver_mode, trigger = release_trigger):
|
|||||||
"{}-oss-build-e2e-publish".format(ver_mode),
|
"{}-oss-build-e2e-publish".format(ver_mode),
|
||||||
"{}-oss-test-frontend".format(ver_mode),
|
"{}-oss-test-frontend".format(ver_mode),
|
||||||
]
|
]
|
||||||
pipelines = [
|
pipelines.extend([
|
||||||
pipeline(
|
pipeline(
|
||||||
name = "{}-oss-build-e2e-publish".format(ver_mode),
|
name = "{}-oss-build-e2e-publish".format(ver_mode),
|
||||||
edition = "oss",
|
edition = "oss",
|
||||||
@@ -232,7 +239,7 @@ def oss_pipelines(ver_mode = ver_mode, trigger = release_trigger):
|
|||||||
),
|
),
|
||||||
test_frontend(trigger, ver_mode),
|
test_frontend(trigger, ver_mode),
|
||||||
test_backend(trigger, ver_mode),
|
test_backend(trigger, ver_mode),
|
||||||
]
|
])
|
||||||
|
|
||||||
if ver_mode not in ("release"):
|
if ver_mode not in ("release"):
|
||||||
pipelines.append(pipeline(
|
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